From 2ea8df0593d520b86bcf958263622218f76ac113 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 26 Aug 2015 10:49:02 -0400 Subject: SL-205 WIP - support for 152-joint rigged meshes with both hardware and software skinning. --- indra/newview/lldrawpoolavatar.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index f828b56f7f..6c9107cb76 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -55,7 +55,8 @@ static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK; static U32 sBufferUsage = GL_STREAM_DRAW_ARB; static U32 sShaderLevel = 0; -#define JOINT_COUNT 52 +// BENTO JOINT COUNT LIMIT +#define JOINT_COUNT 152 LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL; BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE; -- cgit v1.2.3 From 9d44aaab46eff6d16ff50d8b6c12df821f637761 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 8 Sep 2015 12:56:44 -0400 Subject: SL-216 WIP, SL-220 WIP - stray triangles in hw skinning path --- indra/newview/lldrawpoolavatar.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 6c9107cb76..9dd4c2ce0d 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1639,7 +1639,21 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* scale += wght[k]; } - wght *= 1.f/scale; + 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; + } for (U32 k = 0; k < 4; k++) { -- cgit v1.2.3 From 2da22ad9fc92b255f9ec63dee11cf56342c2ac33 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 24 Sep 2015 11:35:19 -0400 Subject: SL-227 WIP - initial pass at consolidating skinning code. Less duplication of functionality, still needs more cleanup. --- indra/newview/lldrawpoolavatar.cpp | 191 ++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 78 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') 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& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) +void LLDrawPoolAvatar::getRiggedGeometry( + LLFace* face, + LLPointer& 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 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 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 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 { 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) { -- cgit v1.2.3 From 924e4292e7a2a11ef01a5703e52116037180aa06 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 24 Sep 2015 13:29:57 -0400 Subject: SL-227 WIP - trimmed unused code. --- indra/newview/lldrawpoolavatar.cpp | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 7ccc779ba4..76c89865a5 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1600,24 +1600,6 @@ void LLDrawPoolAvatar::getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, boo } } -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, @@ -1697,7 +1679,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( for (U32 j = 0; j < buffer->getNumVerts(); ++j) { LLMatrix4a final_mat; - LLMatrix4a final_mat2; getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat); LLVector4a& v = vol_face.mPositions[j]; -- cgit v1.2.3 From 5460c0f4c80660f93723a80d464c0a5ebd97921a Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 28 Sep 2015 11:53:01 -0400 Subject: SL-227 WIP - standardize usage of shared skinning code and handle additional error case in weights. --- indra/newview/lldrawpoolavatar.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 76c89865a5..b3821fda85 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1544,6 +1544,8 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette( const LLMeshSkinInfo* skin, LLVOAvatar *avatar) { + // 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]); @@ -1557,6 +1559,14 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette( 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(); + } } // static @@ -1573,6 +1583,12 @@ void LLDrawPoolAvatar::getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, boo { F32 w = weights[k]; + // BENTO potential optimizations + // - Do clamping in unpackVolumeFaces() (once instead of every time) + // - int vs floor: if we know w is + // >= 0.0, we can use int instead of floorf; the latter + // allegedly has a lot of overhead due to ieeefp error + // checking which we should not need. idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)LL_MAX_JOINTS_PER_MESH_OBJECT-1); wght[k] = w - floorf(w); @@ -1670,7 +1686,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( //build matrix palette LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT); - initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); LLMatrix4a bind_shape_matrix; @@ -1761,9 +1776,9 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) if (sShaderLevel > 0) { // upload matrix palette to shader - LLMatrix4 mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + LLMatrix4a 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); + initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); stop_glerror(); @@ -1773,7 +1788,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) for (U32 i = 0; i < count; ++i) { - F32* m = (F32*) mat[i].mMatrix; + F32* m = (F32*) mat[i].mMatrix[0].getF32ptr(); U32 idx = i*9; -- cgit v1.2.3 From 74b8a487646cccb3260d02910ab5b16e274ec9ab Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 7 Oct 2015 15:38:40 -0400 Subject: SL-234 WIP - adjust max mesh object joints at run-time, including rebuilding shaders --- indra/newview/lldrawpoolavatar.cpp | 49 ++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index b3821fda85..5d78132f6d 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1537,6 +1537,18 @@ void LLDrawPoolAvatar::getRiggedGeometry( buffer->flush(); } +// static +U32 LLDrawPoolAvatar::getMaxJointCount() +{ + return llmin(LL_MAX_JOINTS_PER_MESH_OBJECT, gSavedSettings.getU32("MaxJointsPerMeshObject")); +} + +// static +U32 LLDrawPoolAvatar::getMeshJointCount(const LLMeshSkinInfo *skin) +{ + return llmin(getMaxJointCount(), skin->mJointNames.size()); +} + // static void LLDrawPoolAvatar::initSkinningMatrixPalette( LLMatrix4* mat, @@ -1555,6 +1567,26 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette( } if (joint) { +#if 0 + // BENTO HACK - test of simple push-to-ancestor complexity reduction scheme. + const std::string& name = joint->getName(); + S32 digit = name.back()-'0'; + while (joint->getParent() && (digit<=9) && (digit>=5)) + { + joint = joint->getParent(); + const std::string& name = joint->getName(); + digit = name.back()-'0'; + } + U32 j_remap = 0; + std::vector::const_iterator find_it = + std::find(skin->mJointNames.begin(), skin->mJointNames.end(), joint->getName()); + if (find_it != skin->mJointNames.end()) + { + j_remap = find_it - skin->mJointNames.begin(); + } + // BENTO for hack, use invBindMatrix of up-casted joint + mat[j] = skin->mInvBindMatrix[j_remap]; +#endif mat[j] = skin->mInvBindMatrix[j]; mat[j] *= joint->getWorldMatrix(); } @@ -1570,8 +1602,14 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette( } // static -void LLDrawPoolAvatar::getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat) +void LLDrawPoolAvatar::getPerVertexSkinMatrix( + F32* weights, + LLMatrix4a* mat, + bool handle_bad_scale, + LLMatrix4a& final_mat, + U32 max_joints) { + final_mat.clear(); S32 idx[4]; @@ -1589,7 +1627,7 @@ void LLDrawPoolAvatar::getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, boo // >= 0.0, we can use int instead of floorf; the latter // allegedly has a lot of overhead due to ieeefp error // checking which we should not need. - idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)LL_MAX_JOINTS_PER_MESH_OBJECT-1); + idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)max_joints-1); wght[k] = w - floorf(w); scale += wght[k]; @@ -1685,16 +1723,17 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( //build matrix palette LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT); + U32 count = getMeshJointCount(skin); initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); + const U32 max_joints = getMaxJointCount(); for (U32 j = 0; j < buffer->getNumVerts(); ++j) { LLMatrix4a final_mat; - getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat); + getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; LLVector4a t; @@ -1777,7 +1816,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { // upload matrix palette to shader LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT); + U32 count = getMeshJointCount(skin); initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); stop_glerror(); -- cgit v1.2.3 From 5b58bfb937f7f996c7f1b97f15b1c837aa23a463 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 7 Oct 2015 18:50:33 -0400 Subject: SL-234 WIP - mac build fix --- indra/newview/lldrawpoolavatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 5d78132f6d..e8f53e0f3d 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1546,7 +1546,7 @@ U32 LLDrawPoolAvatar::getMaxJointCount() // static U32 LLDrawPoolAvatar::getMeshJointCount(const LLMeshSkinInfo *skin) { - return llmin(getMaxJointCount(), skin->mJointNames.size()); + return llmin((U32)getMaxJointCount(), (U32)skin->mJointNames.size()); } // static -- cgit v1.2.3 From 58992e2cb4ae2787b85cff63c3ed680cd99fa8ce Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 16 Oct 2015 15:05:29 -0400 Subject: SL-234 WIP - Track which joints are part of base skeleton, remap non-base ones when not being rendered. --- indra/newview/lldrawpoolavatar.cpp | 201 ++++++++++++++++++++++++++++++++++--- 1 file changed, 185 insertions(+), 16 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index e8f53e0f3d..987a15c72d 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1549,6 +1549,156 @@ U32 LLDrawPoolAvatar::getMeshJointCount(const LLMeshSkinInfo *skin) return llmin((U32)getMaxJointCount(), (U32)skin->mJointNames.size()); } +bool getNameIndex(const std::string& name, std::vector& names, U32& result) +{ + std::vector::const_iterator find_it = + std::find(names.begin(), names.end(), name); + if (find_it != names.end()) + { + result = find_it - names.begin(); + return true; + } + else + { + return false; + } +} + +// Find a name table index that is also a valid joint on the +// avatar. Order of preference is: requested name, mPelvis, first +// valid match in names table. +U32 getValidJointIndex(const std::string& name, LLVOAvatar *avatar, std::vector& joint_names) +{ + U32 result; + if (avatar->getJoint(name) && getNameIndex(name,joint_names,result)) + { + return result; + } + if (getNameIndex("mPelvis",joint_names,result)) + { + return result; + } + for (U32 j=0; jgetJoint(joint_names[j])) + { + return j; + } + } + // BENTO how to handle? + LL_ERRS() << "no valid joints in joint_names" << LL_ENDL; + return 0; +} + +// Which joint will stand in for this joint? +U32 getProxyJointIndex(U32 joint_index, LLVOAvatar *avatar, std::vector& 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]); + llassert(joint); + // 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. + while (1) + { + if (include_enhanced || + joint->getSupport()==LLJoint::SUPPORT_BASE) + break; + LLJoint *parent = joint->getParent(); + if (!parent) + break; + if (!getNameIndex(parent->getName(), joint_names, j_proxy)) + { + break; + } + joint = parent; + } + return j_proxy; +#else + return 0; +#endif +} + +// static + +// Destructively remap the joints in skin info based on what joints +// are known in the avatar, and which are currently supported. This +// will also populate mJointRemap[] in the skin, which can be used to +// make the corresponding changes to the integer part of vertex +// weights. +// +// 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. +void LLDrawPoolAvatar::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin) +{ + // skip if already done. + if (!skin->mJointRemap.empty()) + { + return; + } + + // Compute the remap + std::vector j_proxy(skin->mJointNames.size()); + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + U32 j_rep = getProxyJointIndex(j, avatar, skin->mJointNames); + j_proxy[j] = j_rep; + } + S32 top = 0; + std::vector j_remap(skin->mJointNames.size()); + // Fill in j_remap for all joints that will make the cut. + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + if (j_proxy[j] == j) + { + // Joint will be included + j_remap[j] = top++; + } + } + // Then use j_proxy to fill in j_remap for the joints that will be discarded + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + if (j_proxy[j] != j) + { + j_remap[j] = j_remap[j_proxy[j]]; + } + } + + + // Apply the remap to mJointNames, mInvBindMatrix, and mAlternateBindMatrix + std::vector new_joint_names; + std::vector new_inv_bind_matrix; + std::vector new_alternate_bind_matrix; + + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + if (j_proxy[j] == j) + { + new_joint_names.push_back(skin->mJointNames[j]); + new_inv_bind_matrix.push_back(skin->mInvBindMatrix[j]); + if (!skin->mAlternateBindMatrix.empty()) + { + new_alternate_bind_matrix.push_back(skin->mAlternateBindMatrix[j]); + } + } + } + + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + 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->mJointRemap = j_remap; +} + // static void LLDrawPoolAvatar::initSkinningMatrixPalette( LLMatrix4* mat, @@ -1556,38 +1706,57 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette( const LLMeshSkinInfo* skin, LLVOAvatar *avatar) { + // BENTO ugly const cast + remapSkinInfoJoints(avatar, const_cast(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) { joint = avatar->getJoint("mPelvis"); } if (joint) { -#if 0 - // BENTO HACK - test of simple push-to-ancestor complexity reduction scheme. - const std::string& name = joint->getName(); - S32 digit = name.back()-'0'; - while (joint->getParent() && (digit<=9) && (digit>=5)) + if (!gSavedSettings.getBOOL("IncludeEnhancedSkeleton")) { - joint = joint->getParent(); - const std::string& name = joint->getName(); - digit = name.back()-'0'; + // 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::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]; } - U32 j_remap = 0; - std::vector::const_iterator find_it = - std::find(skin->mJointNames.begin(), skin->mJointNames.end(), joint->getName()); - if (find_it != skin->mJointNames.end()) + else { - j_remap = find_it - skin->mJointNames.begin(); + mat[j] = skin->mInvBindMatrix[j]; } - // BENTO for hack, use invBindMatrix of up-casted joint - mat[j] = skin->mInvBindMatrix[j_remap]; -#endif +#else mat[j] = skin->mInvBindMatrix[j]; +#endif mat[j] *= joint->getWorldMatrix(); } } -- cgit v1.2.3 From 6c6a95478ecd657c271354d93a6f98c90093bac5 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 19 Oct 2015 16:32:49 -0400 Subject: SL-234 WIP - remap skin weights to match included-joint logic --- indra/newview/lldrawpoolavatar.cpp | 113 ++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 57 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') 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& 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 " << 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(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; jgetJoint("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; jgetSupport()==LLJoint::SUPPORT_BASE) - break; - LLJoint *parent = joint->getParent(); - if (!parent) - break; - std::vector::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(imInvBindMatrix[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(skin)); LLPointer 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); -- cgit v1.2.3 From d365aa10f16c022970cefbfac8651fe01b5a9de8 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 21 Oct 2015 16:47:03 -0400 Subject: SL-234 WIP - moved LLSkinningUtil funcs to separate class/files. Remap weights where needed. Warn that related debug settings require restart to take effect. --- indra/newview/lldrawpoolavatar.cpp | 295 ++----------------------------------- 1 file changed, 10 insertions(+), 285 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index dff6cada9a..89233b8e32 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "lldrawpoolavatar.h" +#include "llskinningutil.h" #include "llrender.h" #include "llvoavatar.h" @@ -1537,282 +1538,6 @@ void LLDrawPoolAvatar::getRiggedGeometry( buffer->flush(); } -// static -U32 LLDrawPoolAvatar::getMaxJointCount() -{ - return llmin(LL_MAX_JOINTS_PER_MESH_OBJECT, gSavedSettings.getU32("MaxJointsPerMeshObject")); -} - -// static -U32 LLDrawPoolAvatar::getMeshJointCount(const LLMeshSkinInfo *skin) -{ - return llmin((U32)getMaxJointCount(), (U32)skin->mJointNames.size()); -} - -bool getNameIndex(const std::string& name, std::vector& names, U32& result) -{ - std::vector::const_iterator find_it = - std::find(names.begin(), names.end(), name); - if (find_it != names.end()) - { - result = find_it - names.begin(); - return true; - } - else - { - return false; - } -} - -// Find a name table index that is also a valid joint on the -// avatar. Order of preference is: requested name, mPelvis, first -// valid match in names table. -U32 getValidJointIndex(const std::string& name, LLVOAvatar *avatar, std::vector& joint_names) -{ - U32 result; - if (avatar->getJoint(name) && getNameIndex(name,joint_names,result)) - { - return result; - } - if (getNameIndex("mPelvis",joint_names,result)) - { - return result; - } - for (U32 j=0; jgetJoint(joint_names[j])) - { - return j; - } - } - // BENTO how to handle? - LL_ERRS() << "no valid joints in joint_names" << LL_ENDL; - return 0; -} - -// Which joint will stand in for this joint? -U32 getProxyJointIndex(U32 joint_index, LLVOAvatar *avatar, std::vector& joint_names) -{ - 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]); - llassert(joint); - // 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. - while (1) - { - if (include_enhanced || - joint->getSupport()==LLJoint::SUPPORT_BASE) - break; - LLJoint *parent = joint->getParent(); - if (!parent) - break; - if (!getNameIndex(parent->getName(), joint_names, j_proxy)) - { - break; - } - joint = parent; - } - return j_proxy; -} - -// static - -// Destructively remap the joints in skin info based on what joints -// are known in the avatar, and which are currently supported. This -// will also populate mJointRemap[] in the skin, which can be used to -// make the corresponding changes to the integer part of vertex -// weights. -// -// 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. - if (!skin->mJointRemap.empty()) - { - return; - } - - // Compute the remap - std::vector j_proxy(skin->mJointNames.size()); - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - U32 j_rep = getProxyJointIndex(j, avatar, skin->mJointNames); - j_proxy[j] = j_rep; - } - S32 top = 0; - std::vector j_remap(skin->mJointNames.size()); - // Fill in j_remap for all joints that will make the cut. - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - if (j_proxy[j] == j) - { - // Joint will be included - j_remap[j] = top++; - } - } - // Then use j_proxy to fill in j_remap for the joints that will be discarded - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - if (j_proxy[j] != j) - { - j_remap[j] = j_remap[j_proxy[j]]; - } - } - - - // Apply the remap to mJointNames, mInvBindMatrix, and mAlternateBindMatrix - std::vector new_joint_names; - std::vector new_inv_bind_matrix; - std::vector new_alternate_bind_matrix; - - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - if (j_proxy[j] == j) - { - new_joint_names.push_back(skin->mJointNames[j]); - new_inv_bind_matrix.push_back(skin->mInvBindMatrix[j]); - if (!skin->mAlternateBindMatrix.empty()) - { - new_alternate_bind_matrix.push_back(skin->mAlternateBindMatrix[j]); - } - } - } - - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - 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->mJointRemap = j_remap; -} - -// static -void LLDrawPoolAvatar::initSkinningMatrixPalette( - LLMatrix4* mat, - S32 count, - const LLMeshSkinInfo* skin, - LLVOAvatar *avatar) -{ - // 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]); - 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; jmJointRemap.size()>0) - { - // Check the weights are consistent with the current remap. - const S32 max_joints = skin->mJointNames.size(); - for (U32 j=0; j=0); - llassert(i= 0.0, we can use int instead of floorf; the latter - // allegedly has a lot of overhead due to ieeefp error - // checking which we should not need. - idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)max_joints-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); - } -} - void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVOAvatar* avatar, LLFace* face, @@ -1826,7 +1551,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( return; } // BENTO ugly const cast - remapSkinInfoJoints(avatar, const_cast(skin)); + LLSkinningUtil::remapSkinInfoJoints(avatar, const_cast(skin)); LLPointer buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); @@ -1835,7 +1560,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( if (!vol_face.mWeightsRemapped) { - remapSkinWeights(weight, vol_face.mNumVertices, skin); + LLSkinningUtil::remapSkinWeights(weight, vol_face.mNumVertices, skin); vol_face.mWeightsRemapped = TRUE; } @@ -1890,18 +1615,18 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( //build matrix palette LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = getMeshJointCount(skin); - initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); - checkSkinWeights(weight, buffer->getNumVerts(), skin); + U32 count = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + LLSkinningUtil::checkSkinWeights(weight, buffer->getNumVerts(), skin); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); - const U32 max_joints = getMaxJointCount(); + const U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < buffer->getNumVerts(); ++j) { LLMatrix4a final_mat; - getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); + LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; LLVector4a t; @@ -1984,8 +1709,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { // upload matrix palette to shader LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = getMeshJointCount(skin); - initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + U32 count = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); stop_glerror(); -- cgit v1.2.3 From 7b410df303d37a800ddd0024932729a574a00860 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 25 Nov 2015 15:07:26 -0500 Subject: SL-124 WIP - cleanup of comments and test code before going to project viewer. --- indra/newview/lldrawpoolavatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 89233b8e32..33c6d0b00a 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1550,7 +1550,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( { return; } - // BENTO ugly const cast + // FIXME ugly const cast LLSkinningUtil::remapSkinInfoJoints(avatar, const_cast(skin)); LLPointer buffer = face->getVertexBuffer(); -- cgit v1.2.3 From 278825191bdbcc61d398d85c9377c4e921423dde Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 23 Aug 2016 15:08:14 -0400 Subject: TEST - non-SSE code path for matrix ops used in mesh skinning. --- indra/newview/lldrawpoolavatar.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 843cd9b249..e9524189ed 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1628,6 +1628,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; LLVector4a dst; bind_shape_matrix.affineTransform(v, t); -- cgit v1.2.3 From 8230a9937f3bded847dae6c33e01b44158a7f8ee Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 18 Oct 2016 16:05:35 -0400 Subject: MAINT-6841 - removed the joint remapping code, since it was designed to support a feature we no longer have. This also incidentally fixes any bugs caused by the joint remapping code. --- indra/newview/lldrawpoolavatar.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index e9524189ed..517c69305a 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1550,19 +1550,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( return; } // FIXME ugly const cast - LLSkinningUtil::remapSkinInfoJoints(avatar, const_cast(skin)); + LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin)); LLPointer buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); - if (!vol_face.mWeightsRemapped) - { - LLSkinningUtil::remapSkinWeights(weight, vol_face.mNumVertices, skin); - vol_face.mWeightsRemapped = TRUE; - } - if (buffer.isNull() || buffer->getTypeMask() != data_mask || buffer->getNumVerts() != vol_face.mNumVertices || -- cgit v1.2.3 From 5fb30e5ad3615c0b0e9e67a94542dbb110e9ed95 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 11 Nov 2016 09:37:45 -0500 Subject: MAINT-6913 - (Via Sovereign Engineer and Shyotl Kuhr) Pack the skinned matrix and translation into a single mat3x4 for optimal data transfer to reduce uniform slot usage. --- indra/newview/lldrawpoolavatar.cpp | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 517c69305a..10311044d2 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1708,43 +1708,35 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) stop_glerror(); - F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*9]; - - F32 transp[LL_MAX_JOINTS_PER_MESH_OBJECT*3]; + F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12]; for (U32 i = 0; i < count; ++i) { F32* m = (F32*) mat[i].mMatrix[0].getF32ptr(); - U32 idx = i*9; + U32 idx = i*12; mp[idx+0] = m[0]; mp[idx+1] = m[1]; mp[idx+2] = m[2]; + mp[idx+3] = m[12]; - mp[idx+3] = m[4]; - mp[idx+4] = m[5]; - mp[idx+5] = m[6]; - - mp[idx+6] = m[8]; - mp[idx+7] = m[9]; - mp[idx+8] = m[10]; - - idx = i*3; + mp[idx+4] = m[4]; + mp[idx+5] = m[5]; + mp[idx+6] = m[6]; + mp[idx+7] = m[13]; - transp[idx+0] = m[12]; - transp[idx+1] = m[13]; - transp[idx+2] = m[14]; + mp[idx+8] = m[8]; + mp[idx+9] = m[9]; + mp[idx+10] = m[10]; + mp[idx+11] = m[14]; } - LLDrawPoolAvatar::sVertexProgram->uniformMatrix3fv(LLViewerShaderMgr::AVATAR_MATRIX, + LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, count, FALSE, (GLfloat*) mp); - LLDrawPoolAvatar::sVertexProgram->uniform3fv(LLShaderMgr::AVATAR_TRANSLATION, count, transp); - - stop_glerror(); } else -- cgit v1.2.3 From 93db7eacbd1e46c78f8f5d0071578b9bed3202ac Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 30 Nov 2016 14:03:54 -0500 Subject: SL-540 - fix for regression in handling of out-of-range joint indices in skin weights --- indra/newview/lldrawpoolavatar.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 10311044d2..499cf76bff 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1544,8 +1544,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVolume* volume, const LLVolumeFace& vol_face) { - LLVector4a* weight = vol_face.mWeights; - if (!weight) + LLVector4a* weights = vol_face.mWeights; + if (!weights) { return; } @@ -1556,6 +1556,12 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); + + if (!vol_face.mWeightsScrubbed) + { + LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); + vol_face.mWeightsScrubbed = TRUE; + } if (buffer.isNull() || buffer->getTypeMask() != data_mask || @@ -1610,7 +1616,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; U32 count = LLSkinningUtil::getMeshJointCount(skin); LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); - LLSkinningUtil::checkSkinWeights(weight, buffer->getNumVerts(), skin); + LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -1619,7 +1625,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( for (U32 j = 0; j < buffer->getNumVerts(); ++j) { LLMatrix4a final_mat; - LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); + LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; -- cgit v1.2.3