diff options
-rwxr-xr-x | indra/llmath/llvolume.cpp | 18 | ||||
-rwxr-xr-x | indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl | 3 | ||||
-rwxr-xr-x | indra/newview/lldrawpoolavatar.cpp | 22 | ||||
-rwxr-xr-x | indra/newview/llvovolume.cpp | 29 |
4 files changed, 35 insertions, 37 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c2198b91a7..cd417c913d 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2536,6 +2536,8 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U32 cur_influence = 0; LLVector4 wght(0,0,0,0); + U32 joints[4] = {0,0,0,0}; + LLVector4 joints_with_weights(0,0,0,0); while (joint != END_INFLUENCES && idx < weights.size()) { @@ -2543,7 +2545,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) influence |= ((U16) weights[idx++] << 8); F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f); - wght.mV[cur_influence++] = (F32) joint + w; + wght.mV[cur_influence] = w; + joints[cur_influence] = joint; + cur_influence++; if (cur_influence >= 4) { @@ -2554,8 +2558,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) joint = weights[idx++]; } } - - face.mWeights[cur_vertex].loadua(wght.mV); + F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW]; + if (wsum <= 0.f) + { + wght = LLVector4(0.99999f,0.f,0.f,0.f); + } + for (U32 k=0; k<4; k++) + { + joints_with_weights[k] = (F32) joints[k] + wght[k]; + } + face.mWeights[cur_vertex].loadua(joints_with_weights.mV); cur_vertex++; } diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 6cd38d8ef5..3060307b21 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -37,8 +37,7 @@ mat4 getObjectSkinnedTransform() index = min(index, vec4(51.0)); index = max(index, vec4( 0.0)); - float scale = 1.0/(w.x+w.y+w.z+w.w); - w *= scale; + w *= 1.0/(w.x+w.y+w.z+w.w); int i1 = int(index.x); int i2 = int(index.y); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index f828b56f7f..8bbc529244 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1553,7 +1553,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* (drawable && drawable->isState(LLDrawable::REBUILD_ALL))) { if (drawable && drawable->isState(LLDrawable::REBUILD_ALL)) - { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues + { + //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues for (S32 i = 0; i < drawable->getNumFaces(); ++i) { LLFace* facep = drawable->getFace(i); @@ -1570,13 +1571,15 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* buffer = face->getVertexBuffer(); } else - { //just rebuild this face + { + //just rebuild this face getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face); } } if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime()) - { //perform software vertex skinning for this face + { + //perform software vertex skinning for this face LLStrider<LLVector3> position; LLStrider<LLVector3> normal; @@ -1604,10 +1607,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* { joint = avatar->getJoint("mPelvis"); } - if (!joint) - { - LL_DEBUGS("Avatar") << "Failed to find " << skin->mJointNames[j] << LL_ENDL; - } if (joint) { mat[j] = skin->mInvBindMatrix[j]; @@ -1632,12 +1631,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* { F32 w = weight[j][k]; - idx[k] = llclamp((S32) floorf(w), 0, JOINT_COUNT-1); + idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)JOINT_COUNT-1); wght[k] = w - floorf(w); scale += wght[k]; } - + // This is enforced in unpackVolumeFaces() + llassert(scale>0.f); wght *= 1.f/scale; for (U32 k = 0; k < 4; k++) @@ -1737,6 +1737,10 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) for (U32 i = 0; i < count; ++i) { LLJoint* joint = avatar->getJoint(skin->mJointNames[i]); + if (!joint) + { + joint = avatar->getJoint("mPelvis"); + } if (joint) { mat[i] = skin->mInvBindMatrix[i]; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 1f07d93cc7..dabf6acecf 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4163,7 +4163,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } //build matrix palette - static const size_t kMaxJoints = 64; + static const size_t kMaxJoints = 52; LLMatrix4a mp[kMaxJoints]; LLMatrix4* mat = (LLMatrix4*) mp; @@ -4183,12 +4183,6 @@ 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) @@ -4228,21 +4222,9 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons wght[k] = w - floorf(w); scale += wght[k]; } - 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; - } + // This is enforced in unpackVolumeFaces() + llassert(scale>0.f); + wght *= 1.f / scale; for (U32 k = 0; k < 4; k++) { @@ -4251,7 +4233,8 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLMatrix4a src; // Insure ref'd bone is in our clamped array of mats // clamp idx to maxJoints to avoid reading garbage off stack in release - src.setMul(mp[(idx[k]<maxJoints)?idx[k]:0], w); + S32 index = llclamp((S32)idx[k],(S32)0,(S32)kMaxJoints-1); + src.setMul(mp[index], w); final_mat.add(src); } |