diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index eb66d35363..b2de9b0ee8 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4645,6 +4645,7 @@ LLVolumeFace::LLVolumeFace() : mTexCoords(NULL), mIndices(NULL), mWeights(NULL), + mWeightsScrubbed(FALSE), mOctree(NULL), mOptimized(FALSE) { @@ -4670,6 +4671,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mTexCoords(NULL), mIndices(NULL), mWeights(NULL), + mWeightsScrubbed(FALSE), mOctree(NULL) { mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); @@ -4741,6 +4743,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) ll_aligned_free_16(mWeights); mWeights = NULL; } + mWeightsScrubbed = src.mWeightsScrubbed; } if (mNumIndices) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 3cd17dfa84..073290ab15 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -956,6 +956,8 @@ public: // mWeights.size() should be empty or match mVertices.size() LLVector4a* mWeights; + mutable BOOL mWeightsScrubbed; + LLOctreeNode* mOctree; //whether or not face has been cache optimized diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 798a39848a..d66ebea5c9 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1696,8 +1696,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVolume* volume, const LLVolumeFace& vol_face) { - LLVector4a* weight = vol_face.mWeights; - if (!weight) + LLVector4a* weights = vol_face.mWeights; + if (!weights) { return; } @@ -1708,6 +1708,12 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); + + if (!vol_face.mWeightsScrubbed) + { + LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); + vol_face.mWeightsScrubbed = TRUE; + } if (buffer.isNull() || buffer->getTypeMask() != data_mask || @@ -1762,7 +1768,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; U32 count = LLSkinningUtil::getMeshJointCount(skin); LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); - LLSkinningUtil::checkSkinWeights(weight, buffer->getNumVerts(), skin); + LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -1773,8 +1779,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLMatrix4a final_mat; // Use the SSE2 version - // LLSkinningUtil::getPerVertexSkinMatrix( weight[ j ].getF32ptr(), mat, false, final_mat, max_joints ); - FSSkinningUtil::getPerVertexSkinMatrixSSE( weight[ j ], mat, false, final_mat, max_joints ); + // LLSkinningUtil::getPerVertexSkinMatrix( weights[ j ].getF32ptr(), mat, false, final_mat, max_joints ); + FSSkinningUtil::getPerVertexSkinMatrixSSE( weights[ j ], mat, false, final_mat, max_joints ); // LLVector4a& v = vol_face.mPositions[j]; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index d3ac721efa..3343db9421 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -64,11 +64,13 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin // needed for handling of any legacy bad data. if (!avatar->getJoint(skin->mJointNames[j])) { -// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup -// skin->mJointNames[ j ] = "mPelvis"; - skin->mJointNames[ j ] = JointKey::construct( "mPelvis" ); -// - } + // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + //LL_DEBUGS("Avatar") << "Mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL; + //skin->mJointNames[ j ] = "mPelvis"; + LL_DEBUGS("Avatar") << "Mesh rigged to invalid joint" << skin->mJointNames[j].mName << LL_ENDL; + skin->mJointNames[ j ] = JointKey::construct( "mPelvis" ); + // + } } skin->mInvalidJointsScrubbed = true; } @@ -143,6 +145,24 @@ void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, con #endif } +void LLSkinningUtil::scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) +{ + const S32 max_joints = skin->mJointNames.size(); + for (U32 j=0; j