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 | |
parent | 7f19cb367e6182fff78d66738087601470faa9fa (diff) |
SL-227 WIP - initial pass at consolidating skinning code. Less duplication of functionality, still needs more cleanup.
-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; |