0

I was doing a skeletal animation renderer and I've run into some problems. I wrote my own Collada Loader and everything is loaded fine (I have checked it multiple times), I got the skinning and skeleton data ready for the drawing.

The way I understand it you have to first multiply your joints by the inverse bind transform so as to have them in the center of your world coordinate system, and then depending on the animation multiply by the joints animated matrix (concatination of the joint hierarchies local joint transforms) to transform the joint to the correct world position.

I'll paste the code below, to not deal with interpolation of the frames I try to render the FIRST frame of each Joint Animation so I can focus only on the skinning.

static void
update_animator(Animator* animator)
{
    if (animator->anim == NULL)return;
    increase_animation_time(animator);
    //this is the array holding the animated local bind transforms for each joint,
    //if there is no animation in a certain joint its simply m4d(1.f)
    mat4 *local_animated_transforms= (mat4*)malloc(sizeof(mat4) *joints_count);
    for (i32 i = 0; i < 44; ++i)
    {
        local_animated_transforms[i] = m4d(1.f);
    }

    for (u32 i = 0; i < animator->anim->joint_anims_count; ++i)
    {
        JointKeyFrame current_pose = animator->anim->joint_animations[i].keyframes[0];
        u32 animation_index = current_pose.joint_index;
        mat4 local_animated_transform = translate_mat4(current_pose.transform.position) * quat_to_mat4(current_pose.transform.rotation);
        local_animated_transforms[animation_index] = local_animated_transform;
    }
    for (u32 i = 0; i < joints_count;++i)
        calc_animated_transform(animator, animator->model.joints, local_animated_transforms, i);
}

static void
calc_animated_transform(Animator *animator, Joint *joints, mat4 *local_transforms, u32 index)
{
    //here we get the animated joint transform meaning the world pos of the joint in the animation
    mat4 animated_joint_transform = concat_local_transforms(joints, local_transforms, index); 
    //here we multiply by inv bind transform to get the world pos relative to the original bone transforms
    joints[index].animated_transform =animated_joint_transform * joints[index].inv_bind_transform;
}

And this is how the model looks: image

Any help is appreciated!

  • I use both in the engine tbh.. but in this animation system since my matrices are column major I kept it opengl only. – user14279931 Nov 14 '20 at 09:48
  • final joint transform=parentJointTransform[inWorldSpace(multiply this joint's parent local transform with this joints local transform and that again becomes the parentJointTransform for all its children)]*joint transform[from animation in local joint space]*inverseJointTransform[of this joint inWorldSpace] – Sync it Nov 20 '20 at 05:32
  • Also you may want to load the transpose of the matrix if you are loading from colladae files – Sync it Nov 20 '20 at 05:32

0 Answers0