0
\$\begingroup\$

I have been using assimp to import rigged models and animations. I followed this tutorial for skeletal animation and I have got it done properly. The part that I am trying to do now is to orient a certain mesh by using transformation matrix, which represents change from the initial orientation of bone For example, rotating left hand of the model by a 90 deg angle shall make the hand vertical if it's initially horizontal. To achieve this I have taken the following steps:

  1. map each bone with its bone offset matrix, given by pBoneData[BoneIndex].BoneOffset below. This BoneOffset matrix transforms from mesh space to bone space.
  2. find the parent bone in a mesh i.e. body part,
  3. get the matrix for orienting the mesh, and save this matrix for parent bone of that mesh, given by pBoneData[BoneIndex].rotTransform. For all the other bones in a mesh, the orientation matrix is identity matrix;
  4. traverse the node heirarchy and assign final transformation for each bone as:

    void rag::BoneTransform(const aiScene* mScene)
    {
    aiNode* pNode = mScene->mRootNode;
    readNode(pNode, IdentityMatrix);
    }
    
    //recursive process
    void rag::readNode(aiNode* pNode, Matrix4f& ParentTransform)
    {
     Matrix4f rot, GlobalTransformation;
     std::string NodeName(pNode->mName.data);
     Matrix4f NodeTransformation(pNode->mTransformation); 
    
     if (boneMapping.find(NodeName) != boneMapping.end())
     {
     //if node represents a bone, then take it`s unique index
     unsigned int BoneIndex = boneMapping[NodeName];
     //rot is the matrix that represents change in orientation of bone
     rot = pBoneData[BoneIndex].rotTransform;
     GlobalTransformation = ParentTransform * NodeTransformation;
     pBoneData[BoneIndex].FinalTransformation = GlobalInverseTransform * GlobalTransformation * pBoneData[BoneIndex].BoneOffset;
     }
    
     GlobalTransformation = ParentTransform * NodeTransformation;
    
    for (unsigned int i = 0 ; i < pNode->mNumChildren ; i++)
    readNode(pNode->mChildren[i], GlobalTransformation);
    
    }
    

If the function above is run as it is, it will display the model in the state it was while posing it in Blender, in T pose in my case. I am having problems on using 'rot' Matrix. One of the books that I read suggested multiplying the initialBoneOrientation with the changeMatrix. My initial thoughts was to sum 'rot' with NodeTransformation as both of these represent relative change from their parent Matrices. However, I got a totally disfigured model on doing so. Any thoughts on these is highly welcomed.

\$\endgroup\$
1
\$\begingroup\$

The animation data provided by the assimp library is expressed as absolute values, relative to the node/bone's parent; you just set the translation/rotation/scale specified by the animation directly on the node or bone being animated -- don't try to "combine" it with the initial orientation or any other value.

More detail in the assimp library documentation

To apply such an animation you need to identify the animation tracks that refer to actual bones in your mesh. Then for every track:

  1. Find the keys that lay right before the current anim time.
  2. Optional: interpolate between these and the following keys.
  3. Combine the calculated position, rotation and scaling to a tranformation matrix
  4. Set the affected node's transformation to the calculated matrix.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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