diff options
| author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2015-09-24 11:35:19 -0400 | 
|---|---|---|
| committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2015-09-24 11:35:19 -0400 | 
| commit | 2da22ad9fc92b255f9ec63dee11cf56342c2ac33 (patch) | |
| tree | c338fe314e1aead6a07d269493e360ec8a34a657 /indra | |
| parent | 7f19cb367e6182fff78d66738087601470faa9fa (diff) | |
SL-227 WIP - initial pass at consolidating skinning code. Less duplication of functionality, still needs more cleanup.
Diffstat (limited to 'indra')
| -rwxr-xr-x | indra/llcharacter/lljoint.h | 2 | ||||
| -rwxr-xr-x | indra/newview/lldrawpoolavatar.cpp | 191 | ||||
| -rwxr-xr-x | indra/newview/lldrawpoolavatar.h | 2 | ||||
| -rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 59 | ||||
| -rwxr-xr-x | indra/newview/llvovolume.cpp | 54 | 
5 files changed, 139 insertions, 169 deletions
| diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index d9101c04ca..b3bf588d79 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -42,6 +42,8 @@  const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15;  // BENTO JOINT COUNT LIMIT  const U32 LL_CHARACTER_MAX_JOINTS = 152; // must be divisible by 4! +const U32 LL_MAX_JOINTS_PER_MESH_OBJECT = 152; +  // FIXME BENTO - these should be higher than the joint_num of any  // other joint, to avoid conflicts in updateMotionsByType()  const U32 LL_HAND_JOINT_NUM = (LL_CHARACTER_MAX_JOINTS-1); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index f1bfe4ecb2..7ccc779ba4 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -55,9 +55,6 @@ static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;  static U32 sBufferUsage = GL_STREAM_DRAW_ARB;  static U32 sShaderLevel = 0; -// BENTO JOINT COUNT LIMIT -#define JOINT_COUNT 152 -  LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;  BOOL	LLDrawPoolAvatar::sSkipOpaque = FALSE;  BOOL	LLDrawPoolAvatar::sSkipTransparent = FALSE; @@ -1463,7 +1460,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  	}  } -void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) +void LLDrawPoolAvatar::getRiggedGeometry( +    LLFace* face, +    LLPointer<LLVertexBuffer>& buffer, +    U32 data_mask, +    const LLMeshSkinInfo* skin, +    LLVolume* volume, +    const LLVolumeFace& vol_face)  {  	face->setGeomIndex(0);  	face->setIndicesIndex(0); @@ -1472,7 +1475,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>  	face->setTextureIndex(255);  	if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) -	{ //make a new buffer +	{ +        // make a new buffer  		if (sShaderLevel > 0)  		{  			buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); @@ -1484,7 +1488,8 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>  		buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);  	}  	else -	{ //resize existing buffer +	{ +        //resize existing buffer  		buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);  	} @@ -1498,9 +1503,9 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>  	m = m.inverse().transpose();  	F32 mat3[] =  -	{ m.m[0], m.m[1], m.m[2], -		m.m[4], m.m[5], m.m[6], -		m.m[8], m.m[9], m.m[10] }; +        { m.m[0], m.m[1], m.m[2], +          m.m[4], m.m[5], m.m[6], +          m.m[8], m.m[9], m.m[10] };  	LLMatrix3 mat_normal(mat3);				 @@ -1527,14 +1532,98 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>  	{  		face->clearState(LLFace::TEXTURE_ANIM);  	} - -  	face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);  	buffer->flush();  } -void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) +// static +void LLDrawPoolAvatar::initSkinningMatrixPalette( +    LLMatrix4* mat, +    S32 count,  +    const LLMeshSkinInfo* skin, +    LLVOAvatar *avatar) +{ +    for (U32 j = 0; j < count; ++j) +    { +        LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); +        if (!joint) +        { +            joint = avatar->getJoint("mPelvis"); +        } +        if (joint) +        { +            mat[j] = skin->mInvBindMatrix[j]; +            mat[j] *= joint->getWorldMatrix(); +        } +    } +} + +// static +void LLDrawPoolAvatar::getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat) +{ +    final_mat.clear(); + +    S32 idx[4]; + +    LLVector4 wght; + +    F32 scale = 0.f; +    for (U32 k = 0; k < 4; k++) +    { +        F32 w = weights[k]; + +        idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)LL_MAX_JOINTS_PER_MESH_OBJECT-1); + +        wght[k] = w - floorf(w); +        scale += wght[k]; +    } +    if (handle_bad_scale && scale <= 0.f) +    { +        wght = LLVector4(1.0f, 0.0f, 0.0f, 0.0f); +    } +    else +    { +        // This is enforced  in unpackVolumeFaces() +        llassert(scale>0.f); +        wght *= 1.f/scale; +    } + +    for (U32 k = 0; k < 4; k++) +    { +        F32 w = wght[k]; + +        LLMatrix4a src; +        src.setMul(mat[idx[k]], w); + +        final_mat.add(src); +    } +} + +bool operator==(const LLMatrix4a& a, const LLMatrix4a& b) +{ +    for (S32 i=0; i<4; i++) +        for (S32 j=0; j<4; j++) +        { +            if (a.mMatrix[i][j] != b.mMatrix[i][j]) +            { +                return false; +            } +        } +    return true; +} + +bool operator!=(const LLMatrix4a& a, const LLMatrix4a& b) +{ +    return !(a==b); +} + +void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( +    LLVOAvatar* avatar, +    LLFace* face, +    const LLMeshSkinInfo* skin, +    LLVolume* volume, +    const LLVolumeFace& vol_face)  {  	LLVector4a* weight = vol_face.mWeights;  	if (!weight) @@ -1597,23 +1686,10 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  		LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL;  		//build matrix palette -		LLMatrix4a mp[JOINT_COUNT]; -		LLMatrix4* mat = (LLMatrix4*) mp; +		LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; +        U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT); -		U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT); -		for (U32 j = 0; j < count; ++j) -		{ -			LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); -			if (!joint) -			{ -				joint = avatar->getJoint("mPelvis"); -			} -			if (joint) -			{ -				mat[j] = skin->mInvBindMatrix[j]; -				mat[j] *= joint->getWorldMatrix(); -			} -		} +        initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);  		LLMatrix4a bind_shape_matrix;  		bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -1621,36 +1697,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  		for (U32 j = 0; j < buffer->getNumVerts(); ++j)  		{  			LLMatrix4a final_mat; -			final_mat.clear(); - -			S32 idx[4]; - -			LLVector4 wght; - -			F32 scale = 0.f; -			for (U32 k = 0; k < 4; k++) -			{ -				F32 w = weight[j][k]; - -				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++) -			{ -				F32 w = wght[k]; - -				LLMatrix4a src; -				src.setMul(mp[idx[k]], w); - -				final_mat.add(src); -			} - +			LLMatrix4a final_mat2; +            getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat);  			LLVector4a& v = vol_face.mPositions[j];  			LLVector4a t; @@ -1730,30 +1778,17 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  		if (buff)  		{  			if (sShaderLevel > 0) -			{ //upload matrix palette to shader -				LLMatrix4 mat[JOINT_COUNT]; - -				U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT); +			{ +                // upload matrix palette to shader +				LLMatrix4 mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; +				U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT); +                initSkinningMatrixPalette(mat, count, skin, avatar); -				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]; -						mat[i] *= joint->getWorldMatrix(); -					} -				} -				  				stop_glerror(); -				F32 mp[JOINT_COUNT*9]; +				F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*9]; -				F32 transp[JOINT_COUNT*3]; +				F32 transp[LL_MAX_JOINTS_PER_MESH_OBJECT*3];  				for (U32 i = 0; i < count; ++i)  				{ diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index b9d2204052..af063ee74e 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -134,6 +134,8 @@ public:  	void endDeferredRiggedBump();  	void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face); +    static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); +    static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat);  	void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,  									  LLFace* facep,   									  const LLMeshSkinInfo* skin,  diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 851e2d2eb7..7e5d3a9f29 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -5026,6 +5026,7 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget )  	pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() );  }	 +  //-----------------------------------------------------------------------------  // render()  //----------------------------------------------------------------------------- @@ -5571,50 +5572,19 @@ BOOL LLModelPreview::render()  							//quick 'n dirty software vertex skinning  							//build matrix palette -							 -							LLMatrix4 mat[64]; -							for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j) -							{ -								LLJoint* joint = getPreviewAvatar()->getJoint(model->mSkinInfo.mJointNames[j]); -								if (joint) -								{ -									mat[j] = model->mSkinInfo.mInvBindMatrix[j]; -									mat[j] *= joint->getWorldMatrix(); -								} -							} + +							LLMatrix4 mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; +                            U32 count = llmin((U32) model->mSkinInfo.mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT); +                            LLDrawPoolAvatar::initSkinningMatrixPalette(mat, count, &model->mSkinInfo, getPreviewAvatar());  							for (U32 j = 0; j < buffer->getNumVerts(); ++j)  							{ -								LLMatrix4 final_mat; -								final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f; - -								LLVector4 wght; -								S32 idx[4]; - -								F32 scale = 0.f; -								for (U32 k = 0; k < 4; k++) -								{ -									F32 w = weight[j].mV[k]; +                                LLMatrix4a final_mata; +                                LLDrawPoolAvatar::getPerVertexSkinMatrix(weight[j].mV, (LLMatrix4a*)mat, true, final_mata); -									idx[k] = (S32) floorf(w); -									wght.mV[k] = w - floorf(w); -									scale += wght.mV[k]; -								} - -								wght *= 1.f/scale; - -								for (U32 k = 0; k < 4; k++) -								{ -									F32* src = (F32*) mat[idx[k]].mMatrix; -									F32* dst = (F32*) final_mat.mMatrix; - -									F32 w = wght.mV[k]; - -									for (U32 l = 0; l < 16; l++) -									{ -										dst[l] += src[l]*w; -									} -								} +                                // BENTO GROSS KLUDGERY +								LLMatrix4 final_mat; +                                memcpy(&final_mat,&final_mata,sizeof(LLMatrix4a));  								//VECTORIZE THIS  								LLVector3 v(face.mPositions[j].getF32ptr()); @@ -5792,7 +5762,14 @@ void LLFloaterModelPreview::refresh()  }  //static -void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ) +void LLModelPreview::textureLoadedCallback( +    BOOL success, +    LLViewerFetchedTexture *src_vi, +    LLImageRaw* src, +    LLImageRaw* src_aux, +    S32 discard_level, +    BOOL final, +    void* userdata )  {  	LLModelPreview* preview = (LLModelPreview*) userdata;  	preview->refresh(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index eefe452c14..5e010a4712 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4164,27 +4164,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  	//build matrix palette  	// BENTO JOINT COUNT LIMIT -	static const size_t kMaxJoints = 152; +	static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; -	LLMatrix4a mp[kMaxJoints]; -	LLMatrix4* mat = (LLMatrix4*) mp; -	 +	LLMatrix4a mat[kMaxJoints];  	U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints); -	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(); -		} -	} +    LLDrawPoolAvatar::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar);  	for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)  	{ @@ -4208,37 +4192,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  				for (U32 j = 0; j < dst_face.mNumVertices; ++j)  				{  					LLMatrix4a final_mat; -					final_mat.clear(); - -					S32 idx[4]; - -					LLVector4 wght; - -					F32 scale = 0.f; -					for (U32 k = 0; k < 4; k++) -					{ -						F32 w = weight[j][k]; - -						idx[k] = (S32) floorf(w); -						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++) -					{ -						F32 w = wght[k]; - -						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 -                        S32 index = llclamp((S32)idx[k],(S32)0,(S32)kMaxJoints-1); -						src.setMul(mp[index], w); -						final_mat.add(src); -					} - +                    LLDrawPoolAvatar::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat);  					LLVector4a& v = vol_face.mPositions[j];  					LLVector4a t; | 
