Jump to content
  • Advertisement
Sign in to follow this  

Calculate interpolated position in skeletal animation using assimp

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Guys, I've spent months on this skeletal animation loader and I'm finally really close, but I'm starting to hate everything about it.

I will state briefly what my problem is and I will greatly appreciate any help you can give. You can post everything, even if it sounds stupid, don't worry.


I already loaded all the information I need from that fat aiScene tree.


Now with the actual problem:

The problem arises when I change this line in the vertex shader:


gl_Position = MVP * vec4( position, 1.0f );        // When I use this line, I can see the model perfectly fine, but just as a static object.
to this:
gl_Position = MVP * BoneTransform * vec4( position, 1.0f );       // Now it disappears somewhere, so the BoneTransform matrix is not calculated properly.
This means that the Bones matrices are messed up. I traced the error to this function:
void Model::CalcInterpolatedPosition(aiVector3D& Out, float AnimationTime, const aiNodeAnim* pNodeAnim)
    if (pNodeAnim->mNumPositionKeys == 1) {
        Out = pNodeAnim->mPositionKeys[0].mValue;
    uint PositionIndex = FindPosition(AnimationTime, pNodeAnim);
    uint NextPositionIndex = (PositionIndex + 1);
    assert(NextPositionIndex < pNodeAnim->mNumPositionKeys);
    float DeltaTime = (float)(pNodeAnim->mPositionKeys[NextPositionIndex].mTime - pNodeAnim->mPositionKeys[PositionIndex].mTime);
    float Factor = (AnimationTime - (float)pNodeAnim->mPositionKeys[PositionIndex].mTime) / DeltaTime;
    //assert(Factor >= 0.0f && Factor <= 1.0f);
    const aiVector3D& Start = pNodeAnim->mPositionKeys[PositionIndex].mValue;
    const aiVector3D& End = pNodeAnim->mPositionKeys[NextPositionIndex].mValue;
    aiVector3D Delta = End - Start;
    Out = Start + Factor * Delta;
The commented line with the assert function fails. And I have no idea what this Factor is, I don't know what is the problem, but I know that the AnimationTime variable is calculated like this in a previous function:

    float TicksPerSecond = this->scene->mAnimations[0]->mTicksPerSecond != 0 ?
                            this->scene->mAnimations[0]->mTicksPerSecond : 25.0f;
    float TimeInTicks = TimeInSeconds * TicksPerSecond;
    float AnimationTime = fmod(TimeInTicks, this->scene->mAnimations[0]->mDuration);

TimeInSeconds is the time since the application started in seconds, it works correctly, I tested it.


So why would this assert function fail?

( the model and animations are OK, because I downloaded it from turbosquid and I tested it in Blender and it works, so there must be something wrong in the function, but this was the function the guy used in this tutorial: ) http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html

Edited by Heelp

Share this post

Link to post
Share on other sites



The model has been working FOR 2 F*CKIN DAYS, but I had SCALED it without knowing to 0.02f.( I used that scale for my previous model ).

And the model was SO SMALL that I couldn't see it for TWO DAYS. Today I saw some very very small guy walking in the air, rotated 90 degrees, and I'm celebrating now.

I just wanted to tell you that it's working and I'm super happy.

Edited by Heelp

Share this post

Link to post
Share on other sites
Don't know if this goes here, but something I thoought I should share, one of those "gotcha"s if you aren't careful. I've successfully created my own skinned mesh file format and loader, and one of the things that almost slipped by me is the correct construction of bone matrices from bone vectors. When bones are assembled and wights are assigned (normally in the the tpose format), the bone matrix must comprise of the inverse transformation matrix constructed from the tpose bone position/orientation multiplied by the transformation matrix constructed from the desired pose bone position/orientation (if that makes sense).

So if poses[0] is the tpose and poses is the desired pose, v is a tpose vertex assigned to bones[j], then the vertex transformed v_t is

v_t = poses.bones[j].matrix() * poses[0].bones[j].inverse_matrix() * vector(v.xyz,1.0);

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!