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 6b2c1d5f104047af8aa71d01b7d8fbe9a0ad3493 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 14 Sep 2015 11:01:22 -0400 Subject: SL-133 WIP, SL-134 WIP - more extra joint handling --- indra/newview/lldrawpoolavatar.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'indra/newview/lldrawpoolavatar.cpp') diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index f828b56f7f..8bbc529244 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1553,7 +1553,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* (drawable && drawable->isState(LLDrawable::REBUILD_ALL))) { if (drawable && drawable->isState(LLDrawable::REBUILD_ALL)) - { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues + { + //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues for (S32 i = 0; i < drawable->getNumFaces(); ++i) { LLFace* facep = drawable->getFace(i); @@ -1570,13 +1571,15 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* buffer = face->getVertexBuffer(); } else - { //just rebuild this face + { + //just rebuild this face getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face); } } if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime()) - { //perform software vertex skinning for this face + { + //perform software vertex skinning for this face LLStrider position; LLStrider normal; @@ -1604,10 +1607,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* { joint = avatar->getJoint("mPelvis"); } - if (!joint) - { - LL_DEBUGS("Avatar") << "Failed to find " << skin->mJointNames[j] << LL_ENDL; - } if (joint) { mat[j] = skin->mInvBindMatrix[j]; @@ -1632,12 +1631,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* { F32 w = weight[j][k]; - idx[k] = llclamp((S32) floorf(w), 0, JOINT_COUNT-1); + 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++) @@ -1737,6 +1737,10 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) 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]; -- 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