diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 094a9eaf40..3223520b80 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1748,6 +1748,14 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* for (U32 j = 0; j < count; ++j) { LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); + if (!joint) + { + joint = avatar->getJoint("mPelvis"); + } + if (!joint) + { + LL_DEBUGS("Avatar") << "Failed to find " << skin->mJointNames[j] << LL_ENDL; + } if (joint) { mat[j] = skin->mInvBindMatrix[j]; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c5f0b37029..fb769f896e 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4289,11 +4289,23 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons for (U32 j = 0; j < maxJoints; ++j) { LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); + if (!joint) + { + // Fall back to a point inside the avatar if mesh is + // rigged to an unknown joint. + joint = avatar->getJoint("mPelvis"); + } if (joint) { mat[j] = skin->mInvBindMatrix[j]; mat[j] *= joint->getWorldMatrix(); } + else + { + // This shouldn't be possible unless the avatar skeleton + // is corrupt. + llassert(false); + } } for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) @@ -4337,7 +4349,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons // scale += wght[k]; // } // - // wght *= 1.f/scale; + //if (scale > 0.f) + //{ + // wght *= 1.f / scale; + //} LL_ALIGN_16( S32 idx[4] ); LL_ALIGN_16( F32 wght[4] ); @@ -4351,12 +4366,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons _mScale = _mm_add_ss( _mScale, _mm_shuffle_ps( _mScale, _mScale, 1) ); _mScale = _mm_shuffle_ps( _mScale, _mScale, 0 ); - _mWeight = _mm_div_ps( _mWeight, _mScale ); - - _mm_store_ps( wght, _mWeight ); + if (_mScale.m128_f32[0] > 0.f) + { + _mWeight = _mm_div_ps( _mWeight, _mScale ); + _mm_store_ps( wght, _mWeight ); + } // - + else + { + // Complete weighting fail - all zeroes. Just + // pick some values that add up to 1.0 so we + // don't wind up with garbage vertices + // pointing off at (0,0,0) + wght[0] = 1.f; + wght[1] = 0.f; + wght[2] = 0.f; + wght[3] = 0.f; + } for (U32 k = 0; k < 4; k++) { @@ -4364,23 +4391,8 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLMatrix4a src; // Insure ref'd bone is in our clamped array of mats - llassert(idx[k] < kMaxJoints); - // clamp k to kMaxJoints to avoid reading garbage off stack in release - - // k will always be lower than kMaxJoints, as k runs from [0,3] - // Second we should check against maxJoints, as this can be lower thab kMaxJoints. - // And third is is probably better to not cram it all into one line, as that makes - // errors as below slip by easily. - - // src.setMul(mp[idx[(k < kMaxJoints) ? k : 0]], w); - - S32 l = idx[k]; - if( l >= maxJoints ) - l = 0; - src.setMul( mp[ l ], w ); - - // - + // clamp idx to maxJoints to avoid reading garbage off stack in release + src.setMul(mp[(idx[k]