Joao Pincho
Joao Pincho

Reputation: 979

Miscalculating skeleton matrices from assimp

After loading a model with assimp, all the bone data, nodes, etc, I went on a two step task to implement skinning.

If I use just the vertex data with the node hierarchy, I am able to render the model correctly. No skinning, no bone data is sent to the shader, nothing. There are only two meshes but around 60 nodes, specifying parts of the skeleton. The two nodes to which the meshes are attached both have identity matrices, loaded from the file.

no bones, simple node hierarchy

After implementing skinning in the vertex shader, without loading any animation, letting it be the default pose, the model appears all deformed. same model, but deformed

I checked the matrices that are loaded, and some of them are not identity matrices. Shouldn't they be, for the bind pose?

if I pass an identity matrix for every bone, the model appears correctly once again. What am I doing wrong here?

This is the code I'm using to calculate the node hierarchy

struct MeshTreeNode
    {
    std::string Name;
    glm::mat4 DefaultTransformationMatrix;
    std::vector <uint32_t> MeshIndices;
    std::vector <int> ChildNodes;
    int ParentNode;
    };
void ModelCalcMatrices ( const std::vector <MeshTreeNode> &NodeTree, std::vector <glm::mat4> &OutputMatrices, std::vector <NodeMeshIndexPair> &OutputMeshIndices, const unsigned CurrentNodeIndex = 0, const glm::mat4 &CurrentMatrix = glm::identity<glm::mat4> () );

void ModelCalcMatrices ( const std::vector <MeshTreeNode> &NodeTree, std::vector <glm::mat4> &OutputMatrices, std::vector <NodeMeshIndexPair> &OutputMeshIndices, const unsigned CurrentNodeIndex, const glm::mat4 &CurrentMatrix )
    {
    glm::mat4 NewMatrix = NodeTree[CurrentNodeIndex].DefaultTransformationMatrix * CurrentMatrix;
    OutputMatrices.push_back ( NewMatrix );
    // If there are any meshes to be drawn at this node, add them and their corresponding nodes to the vectors.
    for ( unsigned MeshIterator = 0; MeshIterator < NodeTree[CurrentNodeIndex].MeshIndices.size (); ++MeshIterator )
        {
        OutputMeshIndices.push_back ( NodeMeshIndexPair ( CurrentNodeIndex, MeshIterator ) );
        }
    // Process children
    for ( unsigned ChildIterator = 0; ChildIterator < NodeTree[CurrentNodeIndex].ChildNodes.size (); ++ChildIterator )
        {
        ModelCalcMatrices ( NodeTree, OutputMatrices, OutputMeshIndices, NodeTree[CurrentNodeIndex].ChildNodes[ChildIterator], NewMatrix );
        }
    }

I pass it the vector with all nodes as loaded by assimp, and expect an equal-sized vector of matrices to come out. Also outputs another vector with the nodes that actually have some mesh to render.

Upvotes: 0

Views: 12

Answers (0)

Related Questions