0

スケルタル アニメーション レンダラーを実行していたところ、いくつかの問題が発生しました。独自の Collada Loader を作成し、すべて正常にロードされました (何度も確認しました)。スキニングとスケルトン データを描画用に準備しました。

私が理解している方法では、最初にジョイントを逆バインド変換で乗算して、それらをワールド座標系の中心に配置する必要があります。次に、アニメーションに応じて、ジョイントのアニメーション化されたマトリックスを乗算します (ローカルのジョイント階層の連結ジョイント トランスフォーム) を使用して、ジョイントを正しいワールド位置に変換します。

フレームの補間を処理しないように、以下にコードを貼り付けます。各ジョイント アニメーションの最初のフレームをレンダリングして、スキニングだけに集中できるようにします。

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;
}

モデルは次のようになります。 画像

どんな助けでも大歓迎です!

4

0 に答える 0