diff options
Diffstat (limited to 'indra/newview/llviewerjointmesh.cpp')
-rw-r--r-- | indra/newview/llviewerjointmesh.cpp | 166 |
1 files changed, 92 insertions, 74 deletions
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 123dcc8eb4..9bb4aa4cf9 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -47,7 +47,6 @@ static LLPointer<LLVertexBuffer> sRenderBuffer = NULL; static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD; -LLMatrix4 gBlendMat; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -884,89 +883,108 @@ BOOL LLViewerJointMesh::updateLOD(F32 pixel_area, BOOL activate) return (valid != activate); } + void LLViewerJointMesh::updateGeometry() { - if (mValid && mMesh && mFace && - mMesh->hasWeights() && - mFace->mVertexBuffer.notNull() && - LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) == 0) + if (!(mValid + && mMesh + && mFace + && mMesh->hasWeights() + && mFace->mVertexBuffer.notNull() + && LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) == 0)) { - uploadJointMatrices(); - LLStrider<LLVector3> o_vertices; - LLStrider<LLVector3> o_normals; + return; + } + + uploadJointMatrices(); - //get vertex and normal striders - LLVertexBuffer *buffer = mFace->mVertexBuffer; - buffer->getVertexStrider(o_vertices, 0); - buffer->getNormalStrider(o_normals, 0); + LLStrider<LLVector3> o_vertices; + LLStrider<LLVector3> o_normals; + //get vertex and normal striders + LLVertexBuffer *buffer = mFace->mVertexBuffer; + buffer->getVertexStrider(o_vertices, 0); + buffer->getNormalStrider(o_normals, 0); + + F32 last_weight = F32_MAX; + LLMatrix4 gBlendMat; + LLMatrix3 gBlendRotMat; + + const F32* weights = mMesh->getWeights(); + const LLVector3* coords = mMesh->getCoords(); + const LLVector3* normals = mMesh->getNormals(); + for (U32 index = 0; index < mMesh->getNumVertices(); index++) + { + U32 bidx = index + mMesh->mFaceVertexOffset; + + // blend by first matrix + F32 w = weights[index]; + + // Maybe we don't have to change gBlendMat. + // Profiles of a single-avatar scene on a Mac show this to be a very + // common case. JC + if (w == last_weight) { - LLVector4 tpos0, tnorm0, tpos1, tnorm1, tbinorm0, tbinorm1; - F32 last_weight = F32_MAX; - LLMatrix3 gBlendRotMat; + o_vertices[bidx] = coords[index] * gBlendMat; + o_normals[bidx] = normals[index] * gBlendRotMat; + continue; + } + + last_weight = w; + S32 joint = llfloor(w); + w -= joint; - for (U32 index= 0; index < mMesh->getNumVertices(); index++) - { - // blend by first matrix - F32 w = mMesh->getWeights()[index]; - - if (w != last_weight) - { - last_weight = w; - - S32 joint = llfloor(w); - w -= joint; - - LLMatrix4 &m0 = gJointMat[joint+1]; - LLMatrix4 &m1 = gJointMat[joint+0]; - LLMatrix3 &n0 = gJointRot[joint+1]; - LLMatrix3 &n1 = gJointRot[joint+0]; - - if (w == 1.0f) - { - gBlendMat = m0; - gBlendRotMat = n0; - } - else - { - gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w); - gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w); - gBlendMat.mMatrix[VX][VZ] = lerp(m1.mMatrix[VX][VZ], m0.mMatrix[VX][VZ], w); - - gBlendMat.mMatrix[VY][VX] = lerp(m1.mMatrix[VY][VX], m0.mMatrix[VY][VX], w); - gBlendMat.mMatrix[VY][VY] = lerp(m1.mMatrix[VY][VY], m0.mMatrix[VY][VY], w); - gBlendMat.mMatrix[VY][VZ] = lerp(m1.mMatrix[VY][VZ], m0.mMatrix[VY][VZ], w); - - gBlendMat.mMatrix[VZ][VX] = lerp(m1.mMatrix[VZ][VX], m0.mMatrix[VZ][VX], w); - gBlendMat.mMatrix[VZ][VY] = lerp(m1.mMatrix[VZ][VY], m0.mMatrix[VZ][VY], w); - gBlendMat.mMatrix[VZ][VZ] = lerp(m1.mMatrix[VZ][VZ], m0.mMatrix[VZ][VZ], w); - - gBlendMat.mMatrix[VW][VX] = lerp(m1.mMatrix[VW][VX], m0.mMatrix[VW][VX], w); - gBlendMat.mMatrix[VW][VY] = lerp(m1.mMatrix[VW][VY], m0.mMatrix[VW][VY], w); - gBlendMat.mMatrix[VW][VZ] = lerp(m1.mMatrix[VW][VZ], m0.mMatrix[VW][VZ], w); - - gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w); - gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w); - gBlendRotMat.mMatrix[VX][VZ] = lerp(n1.mMatrix[VX][VZ], n0.mMatrix[VX][VZ], w); - - gBlendRotMat.mMatrix[VY][VX] = lerp(n1.mMatrix[VY][VX], n0.mMatrix[VY][VX], w); - gBlendRotMat.mMatrix[VY][VY] = lerp(n1.mMatrix[VY][VY], n0.mMatrix[VY][VY], w); - gBlendRotMat.mMatrix[VY][VZ] = lerp(n1.mMatrix[VY][VZ], n0.mMatrix[VY][VZ], w); - - gBlendRotMat.mMatrix[VZ][VX] = lerp(n1.mMatrix[VZ][VX], n0.mMatrix[VZ][VX], w); - gBlendRotMat.mMatrix[VZ][VY] = lerp(n1.mMatrix[VZ][VY], n0.mMatrix[VZ][VY], w); - gBlendRotMat.mMatrix[VZ][VZ] = lerp(n1.mMatrix[VZ][VZ], n0.mMatrix[VZ][VZ], w); - } - } + // No lerp required in this case. + if (w == 1.0f) + { + gBlendMat = gJointMat[joint+1]; + o_vertices[bidx] = coords[index] * gBlendMat; + gBlendRotMat = gJointRot[joint+1]; + o_normals[bidx] = normals[index] * gBlendRotMat; + continue; + } + + // Try to keep all the accesses to the matrix data as close + // together as possible. This function is a hot spot on the + // Mac. JC + LLMatrix4 &m0 = gJointMat[joint+1]; + LLMatrix4 &m1 = gJointMat[joint+0]; + + gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w); + gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w); + gBlendMat.mMatrix[VX][VZ] = lerp(m1.mMatrix[VX][VZ], m0.mMatrix[VX][VZ], w); - // write result - U32 bidx = index + mMesh->mFaceVertexOffset; + gBlendMat.mMatrix[VY][VX] = lerp(m1.mMatrix[VY][VX], m0.mMatrix[VY][VX], w); + gBlendMat.mMatrix[VY][VY] = lerp(m1.mMatrix[VY][VY], m0.mMatrix[VY][VY], w); + gBlendMat.mMatrix[VY][VZ] = lerp(m1.mMatrix[VY][VZ], m0.mMatrix[VY][VZ], w); - o_vertices[bidx] = mMesh->getCoords()[index] * gBlendMat; - o_normals[bidx] = mMesh->getNormals()[index] * gBlendRotMat; - } - } + gBlendMat.mMatrix[VZ][VX] = lerp(m1.mMatrix[VZ][VX], m0.mMatrix[VZ][VX], w); + gBlendMat.mMatrix[VZ][VY] = lerp(m1.mMatrix[VZ][VY], m0.mMatrix[VZ][VY], w); + gBlendMat.mMatrix[VZ][VZ] = lerp(m1.mMatrix[VZ][VZ], m0.mMatrix[VZ][VZ], w); + + gBlendMat.mMatrix[VW][VX] = lerp(m1.mMatrix[VW][VX], m0.mMatrix[VW][VX], w); + gBlendMat.mMatrix[VW][VY] = lerp(m1.mMatrix[VW][VY], m0.mMatrix[VW][VY], w); + gBlendMat.mMatrix[VW][VZ] = lerp(m1.mMatrix[VW][VZ], m0.mMatrix[VW][VZ], w); + + o_vertices[bidx] = coords[index] * gBlendMat; + + LLMatrix3 &n0 = gJointRot[joint+1]; + LLMatrix3 &n1 = gJointRot[joint+0]; + + gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w); + gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w); + gBlendRotMat.mMatrix[VX][VZ] = lerp(n1.mMatrix[VX][VZ], n0.mMatrix[VX][VZ], w); + + gBlendRotMat.mMatrix[VY][VX] = lerp(n1.mMatrix[VY][VX], n0.mMatrix[VY][VX], w); + gBlendRotMat.mMatrix[VY][VY] = lerp(n1.mMatrix[VY][VY], n0.mMatrix[VY][VY], w); + gBlendRotMat.mMatrix[VY][VZ] = lerp(n1.mMatrix[VY][VZ], n0.mMatrix[VY][VZ], w); + + gBlendRotMat.mMatrix[VZ][VX] = lerp(n1.mMatrix[VZ][VX], n0.mMatrix[VZ][VX], w); + gBlendRotMat.mMatrix[VZ][VY] = lerp(n1.mMatrix[VZ][VY], n0.mMatrix[VZ][VY], w); + gBlendRotMat.mMatrix[VZ][VZ] = lerp(n1.mMatrix[VZ][VZ], n0.mMatrix[VZ][VZ], w); + + o_normals[bidx] = normals[index] * gBlendRotMat; } } |