Use avatar-relative transforms when skinning via software, and translate to world coordinates after.

This commit is contained in:
Shyotl
2017-01-12 23:47:58 -06:00
parent aa7c5e652c
commit f62fded4bd
4 changed files with 23 additions and 5 deletions

View File

@@ -76,7 +76,8 @@ void LLSkinningUtil::initSkinningMatrixPalette(
LLMatrix4a* mat,
S32 count,
const LLMeshSkinInfo* skin,
LLVOAvatar *avatar)
LLVOAvatar *avatar,
bool relative_to_avatar)
{
for (U32 j = 0; j < (U32)count; ++j)
{
@@ -117,7 +118,14 @@ void LLSkinningUtil::initSkinningMatrixPalette(
{
LLMatrix4a bind;
bind.loadu((F32*)skin->mInvBindMatrix[j].mMatrix);
mat[j].setMul(joint->getWorldMatrix(), bind);
if (relative_to_avatar)
{
LLMatrix4a trans = joint->getWorldMatrix();
trans.translate_affine(avatar->getPosition() * -1.f);
mat[j].setMul(trans, bind);
}
else
mat[j].setMul(joint->getWorldMatrix(), bind);
}
else
{

View File

@@ -38,7 +38,7 @@ public:
static U32 getMaxJointCount();
static U32 getMeshJointCount(const LLMeshSkinInfo *skin);
static void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin);
static void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar);
static void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar, bool relative_to_avatar = false);
static void checkSkinWeights(const LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
static void getPerVertexSkinMatrix(const F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);

View File

@@ -9761,12 +9761,15 @@ void LLVOAvatar::updateSoftwareSkinnedVertices(const LLMeshSkinInfo* skin, const
//build matrix palette
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
U32 count = LLSkinningUtil::getMeshJointCount(skin);
LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, this);
LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, this, true);
LLSkinningUtil::checkSkinWeights(weight, buffer->getNumVerts(), skin);
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
LLVector4a av_pos;
av_pos.load3(getPosition().mV);
const U32 max_joints = LLSkinningUtil::getMaxJointCount();
for (U32 j = 0; j < (U32)buffer->getNumVerts(); ++j)
{
@@ -9778,6 +9781,8 @@ void LLVOAvatar::updateSoftwareSkinnedVertices(const LLMeshSkinInfo* skin, const
final_mat.mul(bind_shape_matrix);
final_mat.affineTransform(v, pos[j]);
pos[j].add(av_pos);
if (norm)
{
final_mat.invert();

View File

@@ -4107,7 +4107,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
LLMatrix4a mat[kMaxJoints];
U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin);
LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar);
LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar, true);
LLVector4a av_pos;
av_pos.load3(avatar->getPosition().mV);
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
@@ -4143,6 +4146,8 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
bind_shape_matrix.affineTransform(v, t);
final_mat.affineTransform(t, dst);
pos[j] = dst;
pos[j].add(av_pos);
}
//update bounding box