Fixed an annoying showstopper regarding rigged attachment vertex corruption. Rigged meshes have can have poor weighting, causing potential div-by-zero issues.
This commit is contained in:
@@ -61,8 +61,6 @@ static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
|
||||
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
|
||||
static U32 sShaderLevel = 0;
|
||||
|
||||
#define JOINT_COUNT 52
|
||||
|
||||
LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
|
||||
BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE;
|
||||
BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE;
|
||||
@@ -1550,93 +1548,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
||||
}
|
||||
|
||||
if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
|
||||
{ //perform software vertex skinning for this face
|
||||
LLStrider<LLVector3> position;
|
||||
LLStrider<LLVector3> normal;
|
||||
|
||||
bool has_normal = buffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
|
||||
buffer->getVertexStrider(position);
|
||||
|
||||
if (has_normal)
|
||||
{
|
||||
buffer->getNormalStrider(normal);
|
||||
}
|
||||
|
||||
LLVector4a* pos = (LLVector4a*) position.get();
|
||||
|
||||
LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL;
|
||||
|
||||
//build matrix palette
|
||||
LLMatrix4a mp[JOINT_COUNT];
|
||||
LLMatrix4* mat = (LLMatrix4*) mp;
|
||||
|
||||
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("mRoot");
|
||||
}
|
||||
if (joint)
|
||||
{
|
||||
mat[j] = skin->mInvBindMatrix[j];
|
||||
mat[j] *= joint->getWorldMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
LLMatrix4a bind_shape_matrix;
|
||||
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
|
||||
|
||||
for (U32 j = 0; j < (U32)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), 0, S32(count-1));
|
||||
wght[k] = w - floorf(w);
|
||||
scale += wght[k];
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
LLVector4a& v = vol_face.mPositions[j];
|
||||
LLVector4a t;
|
||||
LLVector4a dst;
|
||||
bind_shape_matrix.affineTransform(v, t);
|
||||
final_mat.affineTransform(t, dst);
|
||||
pos[j] = dst;
|
||||
|
||||
if (norm)
|
||||
{
|
||||
LLVector4a& n = vol_face.mNormals[j];
|
||||
bind_shape_matrix.rotate(n, t);
|
||||
final_mat.rotate(t, dst);
|
||||
dst.normalize3fast();
|
||||
norm[j] = dst;
|
||||
}
|
||||
}
|
||||
{
|
||||
avatar->updateSoftwareSkinnedVertices(skin, weight, vol_face, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user