diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2021-03-22 23:45:25 +0200 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2021-03-23 01:08:38 +0200 | 
| commit | 9fc1b51ae85cbb1a25f4058c0866d29f99724183 (patch) | |
| tree | d513a68f25083068b55a6cb40eded609040ba544 /indra | |
| parent | 9a36df576313e98144deb95b28ed845c768c9960 (diff) | |
SL-14993 Crash accessing mInvBindMatrix
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llprimitive/llmodel.cpp | 30 | ||||
| -rw-r--r-- | indra/newview/llskinningutil.cpp | 34 | ||||
| -rw-r--r-- | indra/newview/llskinningutil.h | 1 | 
3 files changed, 22 insertions, 43 deletions
| diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index a2d9b4cd9b..702a1b5238 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -434,7 +434,7 @@ void LLModel::generateNormals(F32 angle_cutoff)  		if (vol_face.mNumIndices > 65535)  		{ -			LL_WARNS() << "Too many vertices for normal generation to work." << LL_ENDL; +			LL_WARNS("MESHSKININFO") << "Too many vertices for normal generation to work." << LL_ENDL;  			continue;  		} @@ -1100,7 +1100,7 @@ bool LLModel::loadModel(std::istream& is)  	{  		if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024))  		{ -			LL_WARNS() << "Mesh header parse error.  Not a valid mesh asset!" << LL_ENDL; +			LL_WARNS("MESHSKININFO") << "Mesh header parse error.  Not a valid mesh asset!" << LL_ENDL;  			return false;  		}  	} @@ -1132,7 +1132,7 @@ bool LLModel::loadModel(std::istream& is)  	if (header[lod_name[lod]]["offset"].asInteger() == -1 ||   		header[lod_name[lod]]["size"].asInteger() == 0 )  	{ //cannot load requested LOD -		LL_WARNS() << "LoD data is invalid!" << LL_ENDL; +		LL_WARNS("MESHSKININFO") << "LoD data is invalid!" << LL_ENDL;  		return false;  	} @@ -1195,7 +1195,7 @@ bool LLModel::loadModel(std::istream& is)  	}  	else  	{ -		LL_WARNS() << "unpackVolumeFaces failed!" << LL_ENDL; +		LL_WARNS("MESHSKININFO") << "unpackVolumeFaces failed!" << LL_ENDL;  	}  	return false; @@ -1223,7 +1223,7 @@ bool LLModel::isMaterialListSubset( LLModel* ref )  		if (!foundRef)  		{ -            LL_INFOS() << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL; +            LL_INFOS("MESHSKININFO") << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL;  			return false;  		}  	} @@ -1259,7 +1259,7 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn  	bool isASubset = isMaterialListSubset( ref );  	if ( !isASubset )  	{ -		LL_INFOS()<<"Material of model is not a subset of reference."<<LL_ENDL; +		LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL;  		return false;  	} @@ -1398,6 +1398,14 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)  			mInvBindMatrix.push_back(mat);  		} + +        if (mJointNames.size() != mInvBindMatrix.size()) +        { +            LL_WARNS("MESHSKININFO") << "Joints vs bind matrix count mismatch. Dropping joint bindings." << LL_ENDL; +            mJointNames.clear(); +            mJointNums.clear(); +            mInvBindMatrix.clear(); +        }  	}  	if (skin.has("bind_shape_matrix")) @@ -1842,14 +1850,14 @@ bool validate_face(const LLVolumeFace& face)  	{  		if (face.mIndices[i] >= face.mNumVertices)  		{ -			LL_WARNS() << "Face has invalid index." << LL_ENDL; +			LL_WARNS("MESHSKININFO") << "Face has invalid index." << LL_ENDL;  			return false;  		}  	}  	if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0)  	{ -		LL_WARNS() << "Face has invalid number of indices." << LL_ENDL; +		LL_WARNS("MESHSKININFO") << "Face has invalid number of indices." << LL_ENDL;  		return false;  	} @@ -1879,7 +1887,7 @@ bool validate_model(const LLModel* mdl)  {  	if (mdl->getNumVolumeFaces() == 0)  	{ -		LL_WARNS() << "Model has no faces!" << LL_ENDL; +		LL_WARNS("MESHSKININFO") << "Model has no faces!" << LL_ENDL;  		return false;  	} @@ -1887,13 +1895,13 @@ bool validate_model(const LLModel* mdl)  	{  		if (mdl->getVolumeFace(i).mNumVertices == 0)  		{ -			LL_WARNS() << "Face has no vertices." << LL_ENDL; +			LL_WARNS("MESHSKININFO") << "Face has no vertices." << LL_ENDL;  			return false;  		}  		if (mdl->getVolumeFace(i).mNumIndices == 0)  		{ -			LL_WARNS() << "Face has no indices." << LL_ENDL; +			LL_WARNS("MESHSKININFO") << "Face has no indices." << LL_ENDL;  			return false;  		} diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 1fb63c7444..f325315933 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -309,7 +309,8 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a      if (vol_face.mJointRiggingInfoTab.needsUpdate())      {          S32 num_verts = vol_face.mNumVertices; -        if (num_verts>0 && vol_face.mWeights && (skin->mJointNames.size()>0)) +        S32 num_joints = skin->mJointNames.size(); +        if (num_verts > 0 && vol_face.mWeights && num_joints > 0)          {              initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);              if (vol_face.mJointRiggingInfoTab.size()==0) @@ -343,7 +344,7 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a                      for (U32 k=0; k<4; ++k)                      {  						S32 joint_index = idx[k]; -                        if (wght[k] > 0.0f) +                        if (wght[k] > 0.0f && num_joints > joint_index)                          {                              S32 joint_num = skin->mJointNums[joint_index];                              if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) @@ -394,35 +395,6 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a      }  } -void LLSkinningUtil::updateRiggingInfo_(LLMeshSkinInfo* skin, LLVOAvatar *avatar, S32 num_verts, LLVector4a* weights, LLVector4a* positions, U8* joint_indices, LLJointRiggingInfoTab &rig_info_tab) -{ -    LL_RECORD_BLOCK_TIME(FTM_FACE_RIGGING_INFO); -    for (S32 i=0; i < num_verts; i++) -    { -        LLVector4a& pos  = positions[i]; -        LLVector4a& wght = weights[i]; -        for (U32 k=0; k<4; ++k) -        { -            S32 joint_num = skin->mJointNums[joint_indices[k]]; -            llassert(joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS); -            { -                rig_info_tab[joint_num].setIsRiggedTo(true); -                LLMatrix4a bind_shape; -                bind_shape.loadu(skin->mBindShapeMatrix); -                LLMatrix4a inv_bind; -                inv_bind.loadu(skin->mInvBindMatrix[joint_indices[k]]); -                LLMatrix4a mat; -                matMul(bind_shape, inv_bind, mat); -                LLVector4a pos_joint_space; -                mat.affineTransform(pos, pos_joint_space); -                pos_joint_space.mul(wght[k]); -                LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents(); -                update_min_max(extents[0], extents[1], pos_joint_space); -            } -        } -    } -} -  // This is used for extracting rotation from a bind shape matrix that  // already has scales baked in  LLQuaternion LLSkinningUtil::getUnscaledQuaternion(const LLMatrix4& mat4) diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 549aa6a29f..efe7c85997 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -67,7 +67,6 @@ namespace LLSkinningUtil      void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar);      void updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face); -    void updateRiggingInfo_(LLMeshSkinInfo* skin, LLVOAvatar *avatar, S32 num_verts, LLVector4a* weights, LLVector4a* positions, U8* joint_indices, LLJointRiggingInfoTab &rig_info_tab);  	LLQuaternion getUnscaledQuaternion(const LLMatrix4& mat4);  }; | 
