2

I have been trying to implement skeletal animation in my own 3D openGL/c++ game engine using ASSIMP to import the models.

I think that the problem is caused by the calculation of the bone matrices, loaded as uniform variables in the shader because if I assign them to identities, the mesh is loaded in its bind pose.

These are the functions I use to initialize and calculate the ready bone matrices:

    void Joint::AddToSceneGraph(GameObject* root)
    {
        GameObject* parent = root->FindChild(m_name);
        //m_globalInverseMatrix = inverse(root->GetTransform().GetMatrix());
        parent->AddComponent(this);
        while (parent->GetParent() != root)
            parent = parent->GetParent();

        parent->GetTransform().SetParent(NULL); (1)
    }

    mat4 Joint::GetMatrix()
    {
        mat4 ans = /*m_globalInverseMatrix*/GetTransform().GetMatrix()*m_offsetMatrix;
        return ans;
    }

Since I am trying to render the model in its bind pose I wont supply you the code of calculating animation matrices.

Some clarifications - I have a Transform class which has Transform* parent and whose GetMatrix() method calculates the matrix from the parent's one, scaling and translating vec3s and rotation quaternion so the relation between parent and child is taken in consideration. I assume that the parent's transform of the root joint has to be NULL thus its matrix - identity, which is the purpose of (1). Although I am not sure for this assumption, I am sure that the node with the root of the skeleton and the node, containing the meshes, are siblings.

Also I am not sure weather I should use m_globalInverseMatrix and furthermore what exactly is its purpose.

In general I think the main issue I have is misunderstanding of how ASSIMP calculates the offset matrix or so called inverse bind pose matrix and how to invert its effect. This issue results in the model looking "packed" in itself :

this is maybe the most famous md5 model

Community
  • 1
  • 1
pandicacao
  • 35
  • 5

1 Answers1

4

From the docs in Assimp, the offset matrix of the bones transforms from the mesh space to the bone space.

I managed to render the bind pos with a hierarchy similar to yours (if I have not misunderstood, you have a root node with two children, one spawning the skeleton hierarchy and the other spawning the mesh). What you have to do is set the m_globalInverseMatrix to the inverse transform of the node containing the mesh. Then, each bone's transform is:

boneTransform = m_globalInverseMatrix * boneHierarchyTransforms * boneOffsetMatrix

where the boneHierarchyTransform comes from traversing the tree up to each bone node and the boneOffsetMatrix is the one you mention and I referred to in the first paragraph.