summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerjointmesh.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerjointmesh.cpp')
-rw-r--r--indra/newview/llviewerjointmesh.cpp166
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;
}
}