summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rwxr-xr-xindra/newview/llvovolume.cpp30
1 files changed, 25 insertions, 5 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 267061b83d..1f07d93cc7 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4174,6 +4174,8 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
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)
@@ -4181,6 +4183,12 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
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)
@@ -4220,8 +4228,21 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
wght[k] = w - floorf(w);
scale += wght[k];
}
-
- wght *= 1.f/scale;
+ if (scale > 0.f)
+ {
+ wght *= 1.f / scale;
+ }
+ 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++)
{
@@ -4229,9 +4250,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
- src.setMul(mp[idx[(k < kMaxJoints) ? k : 0]], w);
+ // clamp idx to maxJoints to avoid reading garbage off stack in release
+ src.setMul(mp[(idx[k]<maxJoints)?idx[k]:0], w);
final_mat.add(src);
}