diff options
| -rwxr-xr-x | indra/llmath/llvolume.cpp | 1 | ||||
| -rwxr-xr-x | indra/llmath/llvolume.h | 4 | ||||
| -rwxr-xr-x | indra/newview/lldrawpoolavatar.cpp | 113 | ||||
| -rwxr-xr-x | indra/newview/lldrawpoolavatar.h | 2 | ||||
| -rwxr-xr-x | indra/newview/llvovolume.cpp | 1 | 
5 files changed, 64 insertions, 57 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8608e45a91..206330fd53 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4568,6 +4568,7 @@ LLVolumeFace::LLVolumeFace() :  	mTexCoords(NULL),  	mIndices(NULL),  	mWeights(NULL), +    mWeightsRemapped(FALSE),  	mOctree(NULL),  	mOptimized(FALSE)  { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 1da2d0c6b1..33e1403a14 100755 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -953,6 +953,10 @@ public:  	// mWeights.size() should be empty or match mVertices.size()    	LLVector4a* mWeights; +    // Whether or not the weights have been cleaned up and remapped +    // based on currently supported joints. +    mutable BOOL mWeightsRemapped; +  	LLOctreeNode<LLVolumeTriangle>* mOctree;  	//whether or not face has been cache optimized diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 987a15c72d..dff6cada9a 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1593,7 +1593,6 @@ U32 getValidJointIndex(const std::string& name, LLVOAvatar *avatar, std::vector<  // Which joint will stand in for this joint?   U32 getProxyJointIndex(U32 joint_index, LLVOAvatar *avatar, std::vector<std::string>& joint_names)  { -#if 1      bool include_enhanced = gSavedSettings.getBOOL("IncludeEnhancedSkeleton");      U32 j_proxy = getValidJointIndex(joint_names[joint_index], avatar, joint_names);      LLJoint *joint = avatar->getJoint(joint_names[j_proxy]); @@ -1618,9 +1617,6 @@ U32 getProxyJointIndex(U32 joint_index, LLVOAvatar *avatar, std::vector<std::str          joint = parent;      }      return j_proxy; -#else -    return 0; -#endif  }  // static @@ -1634,6 +1630,8 @@ U32 getProxyJointIndex(U32 joint_index, LLVOAvatar *avatar, std::vector<std::str  // This will throw away joint info for any joints that are not known  // in the avatar, or not currently flagged to support based on the  // debug setting for IncludeEnhancedSkeleton. +// +// static  void LLDrawPoolAvatar::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin)  {  	// skip if already done. @@ -1693,9 +1691,9 @@ void LLDrawPoolAvatar::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* s          LL_INFOS() << "Starting joint[" << j << "] = " << skin->mJointNames[j] << " j_remap " << j_remap[j] << " ==> " << new_joint_names[j_remap[j]] << LL_ENDL;      } -    //skin->mJointNames = new_joint_names; -    //skin->mInvBindMatrix = new_inv_bind_matrix; -    //skin->mAlternateBindMatrix = new_alternate_bind_matrix; +    skin->mJointNames = new_joint_names; +    skin->mInvBindMatrix = new_inv_bind_matrix; +    skin->mAlternateBindMatrix = new_alternate_bind_matrix;      skin->mJointRemap = j_remap;  } @@ -1706,67 +1704,59 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette(      const LLMeshSkinInfo* skin,      LLVOAvatar *avatar)  { -    // BENTO ugly const cast -    remapSkinInfoJoints(avatar, const_cast<LLMeshSkinInfo*>(skin)); -          // BENTO - switching to use Matrix4a and SSE might speed this up.      // Note that we are mostly passing Matrix4a's to this routine anyway, just dubiously casted.      for (U32 j = 0; j < count; ++j)      {          LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); -#if 1 // Don't need this stuff if we've already remapped/cleaned up above -        if (!joint) +        mat[j] = skin->mInvBindMatrix[j]; +        mat[j] *= joint->getWorldMatrix(); +    } +} + +// Transform the weights based on the remap info stored in skin. Note +// that this is destructive and non-idempotent, so we need to keep +// track of whether we've done it already. If the desired remapping +// changes, the viewer must be restarted. +// +// static +void LLDrawPoolAvatar::remapSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) +{ +    llassert(skin->mJointRemap.size()>0); // Must call remapSkinInfoJoints() first, which this checks for. +    const U32* remap = &skin->mJointRemap[0]; +    const S32 max_joints = skin->mJointNames.size(); +    for (U32 j=0; j<num_vertices; j++) +    { +        F32 *w = weights[j].getF32ptr(); + +        for (U32 k=0; k<4; ++k)          { -            joint = avatar->getJoint("mPelvis"); +            S32 i = llfloor(w[k]); +            F32 f = w[k]-i; +            i = llclamp(i,0,max_joints-1); +            w[k] = remap[i] + f;          } -        if (joint) +    } +} + +// static +void LLDrawPoolAvatar::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) +{ +    if (skin->mJointRemap.size()>0) +    { +        // Check the weights are consistent with the current remap. +        const S32 max_joints = skin->mJointNames.size(); +        for (U32 j=0; j<num_vertices; j++)          { -            if (!gSavedSettings.getBOOL("IncludeEnhancedSkeleton")) -            { -                // BENTO - test of simple push-to-base-ancestor -                // complexity reduction scheme.  Find the first -                // ancestor that's not flagged as extended, or the -                // last ancestor that's rigged in this mesh, whichever -                // comes first. -                U32 j_remap = 0; -                while (1) -                { -                    if (joint->getSupport()==LLJoint::SUPPORT_BASE) -                        break; -                    LLJoint *parent = joint->getParent(); -                    if (!parent) -                        break; -                    std::vector<std::string>::const_iterator find_it = -                        std::find(skin->mJointNames.begin(), skin->mJointNames.end(), parent->getName()); -                    if (find_it != skin->mJointNames.end()) -                    { -                        j_remap = find_it - skin->mJointNames.begin(); -                    } -                    else -                    { -                        break; -                    } -                    joint = parent; -                } -                mat[j] = skin->mInvBindMatrix[j_remap]; -            } -            else +            F32 *w = weights[j].getF32ptr(); + +            for (U32 k=0; k<4; ++k)              { -                mat[j] = skin->mInvBindMatrix[j]; +                S32 i = llfloor(w[k]); +                llassert(i>=0); +                llassert(i<max_joints);              } -#else -            mat[j] = skin->mInvBindMatrix[j]; -#endif -            mat[j] *= joint->getWorldMatrix(); -        }      } -    // This handles a bogus weights case that has turned up in -    // practice, without the overhead of zeroing every matrix.  We are -    // doing this here instead of in getPerVertexSkinMatrix so the fix -    // will also work in the HW skinning case. -    if (count < LL_MAX_JOINTS_PER_MESH_OBJECT) -    { -        mat[count].setIdentity();      }  } @@ -1835,12 +1825,20 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(  	{  		return;  	} +    // BENTO ugly const cast +    remapSkinInfoJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));  	LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();  	LLDrawable* drawable = face->getDrawable();  	U32 data_mask = face->getRiggedVertexBufferDataMask(); +    if (!vol_face.mWeightsRemapped) +    { +        remapSkinWeights(weight, vol_face.mNumVertices, skin);  +        vol_face.mWeightsRemapped = TRUE; +    } +  	if (buffer.isNull() ||   		buffer->getTypeMask() != data_mask ||  		buffer->getNumVerts() != vol_face.mNumVertices || @@ -1894,6 +1892,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(  		LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];          U32 count = getMeshJointCount(skin);          initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); +        checkSkinWeights(weight, buffer->getNumVerts(), skin);  		LLMatrix4a bind_shape_matrix;  		bind_shape_matrix.loadu(skin->mBindShapeMatrix); diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 27d4c949fd..8d6e95ba1a 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -138,6 +138,8 @@ public:      static U32 getMeshJointCount(const LLMeshSkinInfo *skin);      static void remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin);      static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); +    static void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); +    static void remapSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);      static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);  	void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,  									  LLFace* facep,  diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c09786b7c7..5d8558cb46 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4192,6 +4192,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  		if ( weight )  		{ +            LLDrawPoolAvatar::checkSkinWeights(weight, dst_face.mNumVertices, skin);  			LLMatrix4a bind_shape_matrix;  			bind_shape_matrix.loadu(skin->mBindShapeMatrix); | 
