1
$\begingroup$

Let's say I have the following hierarchy:

Bone A
    Bone B
        Bone C

Here's how most tutorial is telling me how to calculate the finalMatrix to be sent to shader.

bonePoseToWorldPose(Joint * joint, glm::mat4 & parentTransform, glm::mat4 & globalInverseTransform) {
    joint->finalTransform = parentTransform * joint->localTransform; // local transform is the result of interpolating 2 keyframes
    for (int i = 0; i < joint->children.size(); i++) {
        bonePoseToWorldPose(joint->children[i], joint->finalTransform, globalInverseTransform);
    }
    joint->finalTransform = joint->finalTransform * joint->inverseBindTransform;  
}

Doing it this way, the final transform in bone C for example, would be localTransformA * localTransformB * localTransformC * jointInverseBindTransform.

Which does not make sense to me, and none of the tutorial satisfactorily explains that. Let's go back to the example again. the inverse bind transform would bring a vertex V from mesh space to bone space of Bone C. At bone space C, it would be multiplied with the localTransformC (or interpolated transform C), which I guess would set the model to our desired pose. But what are A and B doing there?

$\endgroup$

1 Answer 1

3
$\begingroup$

The bone transforms are relative to their parent in the hierarchy. That's the point of the hierarchy, i.e. when you move your arm, your hand and fingers go along with it. So when an animation (or whatever) changes the transform of A, then bones B and C are supposed to move along with it.

This is accomplished by defining bone B relative to A, and C relative to B, and so on.

Therefore, to get the final transform from bone local space to world space, you have to combine all the transforms from the current bone up the hierarchy to the root.

To put it another way:

  • The localTransform of C takes you to B's local space.
  • Then the localTransform of B takes you to A's local space.
  • Then the localTransform of A takes you to world space (since A is the root).
$\endgroup$
5
  • $\begingroup$ I thought the local transform of A should take you to B local space, then the local transform of B take you to C local space? for example, for a vertex in world space to get into C space, it needs to be multiplied by CBA*v. Then to get it from C space to world space you would get the inverse of it, which is (CBA)^-1 or A^-1*B^-1*C^-1? $\endgroup$ Commented May 11, 2018 at 4:40
  • 1
    $\begingroup$ @ManhNguyen Local transform takes you from the local space to the parent space, not the other way around. C space to world space would be ABC*v. $\endgroup$ Commented May 11, 2018 at 4:46
  • $\begingroup$ Usually the matrices are set up to describe object in parent space. But it is offcourse possible to store the inverses as the matrix like @ManhNguyen suggests. Ive never seen it done, somebody asked this i think and the answer was that for some reason it feels unnatural. Just as possible to set it up this way just like its possible to have a transposed matrix order in which case all calculations are reverse. So the dev needs to know this. $\endgroup$
    – joojaa
    Commented May 11, 2018 at 4:54
  • $\begingroup$ @ManhNguyen that wouldnt work if you wanted to have multiple separate objects. But if you shift your reasoning one node up then it would work. Modeller has some leeway in deciding how the computation happens, but it seems that describing the world as a function of objects is a bit out there, but possible. $\endgroup$
    – joojaa
    Commented May 11, 2018 at 5:07
  • $\begingroup$ @joojaa I followed the math you guys give me and the animation is only correct for 1 out of the 2 models I am working on. Both are loaded by Assimp. The only differences I can think of are that 1 is a fbx file and the other is a dae file and that 1 has multiple mesh not situated at root scene and the other does. Is there something I am missing? The Assimp loader is able to load both models correctly. $\endgroup$ Commented May 11, 2018 at 5:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.