# Assimp and Skinning transforms

This topic is 697 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Trying to wrap my head around skinning transforms for skeletal animations. Using assimp to parse model data and GLM as math library (right-handed)

Here's how I understand it, the order in which transforms are done:

// calculate translation/rotation/scaling (TRS) of each bone and concatenate it with its parent
foreach bone in boneList
MAT4_bone = calculate TRS-matrix based on time
MAT4_parent = get parent TRS-matrix of bone
MAT4_bone = MAT4_parent * MAT4_bone

// after, apply bone offset and inverse root matrix
// why is the inverse root matrix needed anyway?
MAT4_rootInvMatrix = the inverse of the root matrix of the scene
foreach bone in boneList
MAT4_bone = the (now) absolute TRS matrix of a bone
MAT4_offset = the bones offset matrix given by assimp
MAT4_final = MAT4_rootInvMatrix * MAT4_bone * MAT4_offset

As far as I can tell, each assimp nodes original mTransform is just discard and not used at all?

And in code:

void AnimationUpdater::Update(const Milliseconds elapsedTime)
{
for (AnimationInstance& animationInstance : mActiveAnimations)
{
const BoneIndex bonesBegin = animationInstance.mBoneRange.first;
const BoneIndex bonesEnd = animationInstance.mBoneRange.second;

// mBoneTransforms - the final skinning transforms

// root has no parent
// note: root is always front
Mat4& rootTransform = mBoneTransforms.at(bonesBegin);
rootTransform = animation.InterpolateBoneTransform(bonesBegin, elapsedTime);

// interpolate bone animations
// parens always appear before their children
const uint32_t numBones = bonesEnd - bonesBegin;
for (uint32_t boneOffset = 1; boneOffset < numBones; ++boneOffset)
{
const BoneIndex bone = bonesBegin + boneOffset;
const BoneIndex parentBone = animation.GetParentIndex(bone);
const Mat4& parentTransform = mBoneTransforms.at(parentBone);

Mat4& transform = mBoneTransforms.at(bone);
transform = parentTransform * animation.InterpolateBoneTransform(bone, elapsedTime);
}

const Mat4& rootInverseTransform = animation.GetInverseRootMatrix();
for (uint32_t boneOffset = 1; boneOffset < numBones; ++boneOffset)
{
const BoneIndex bone = bonesBegin + boneOffset;
const Mat4& boneOffsetTransform = animation.GetBoneOffsetTransform(bone);

Mat4& transform = mBoneTransforms.at(bone);
transform = rootInverseTransform * transform * boneOffsetTransform;
}
}
}

Yet it all looks like a tangled mess during rendering. Is there anything obvious I'm missing here?

Edited by KaiserJohan

##### Share on other sites

There's a lot of things that can go wrong. Start with the basics like is the mesh scaled and rotated the same as the armature at identity and are the bone heads where you expect them to be?

##### Share on other sites

Alright, I've pretty much solved it I believe, just a few finishing touches.

If it helps anyone, I re-arranged assimps bone hierarchy into a custom parent-before-child container and forgot to map assimp bone indices to these (re-arranged) bone indices and thus the vertices picked the wrong bone transforms in the shader.

As a starter, try replacing all the bone transforms with identity matrices and make sure it renders correctly.

Also try a tool like assimps modelviewer (http://www.open3mod.com/) to inspect the node/bone hierarchy and compare it to yours.

1. 1
Rutin
24
2. 2
3. 3
JoeJ
18
4. 4
5. 5

• 38
• 23
• 13
• 13
• 17
• ### Forum Statistics

• Total Topics
631712
• Total Posts
3001849
×