Jump to content
  • Advertisement
Sign in to follow this  

Quaternion Skinning

This topic is 1104 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I'm using Quaternion-Translation to animate my model, I don't want to use matrix. Each bone has vec3 rotation and vec3 position. I mean if I use matrix, it's just simply multiply matrix local parent with matrix local child to get the relative position, what about quaternion?
I know Quaternion is just a representation of rotation. I stored the rotation in quaternion and the position in vec3, how to get the default bind position depending the joint's parent and child? I've tried to multiply the parent quaternion with child quaternion and then sum the child position with parent position. And this is what I got:


While it should be like this:


Share this post

Link to post
Share on other sites
You need to rotate the child's local position by the parent's world rotation before adding it to its parent's world position to get the child's world position Edited by HappyCoder

Share this post

Link to post
Share on other sites

Thanks for the reply HappyCoder. Tried what you said but not all of the joints got the correct position.



Joint 0 has parent -1 (root)

Joint 1 has parent 0

Joint 2 has parent 1

Joint 3 has parent 2


However, every bone that connected to the root gets the correct position while the others don't. In the example case, the joint 0 and joint 1 get the correct position.




        pAnim.pBones[i].qWorld = Quaternion_FromEuler(pAnim.pBones[i].Rot);
        pAnim.pBones[i].vWorld.x = pAnim.pBones[i].Pos[0];
        pAnim.pBones[i].vWorld.y = pAnim.pBones[i].Pos[1];
        pAnim.pBones[i].vWorld.z = pAnim.pBones[i].Pos[2];
        int iRoot = pAnim.pBones[i].Parent;

        // Rotation
        pAnim.pBones[i].qLocal = pAnim.pBones[i].qWorld;        
        // Translation
        pAnim.pBones[i].vLocal = pAnim.pBones[i].vWorld;

        if (iRoot != -1)
            //pAnim.pBones[i].qLocal = Quaternion_Multiply(pAnim.pBones[iRoot].qLocal, pAnim.pBones[i].qLocal);
            pAnim.pBones[i].vLocal = Vector_Rotate(pAnim.pBones[i].vLocal, pAnim.pBones[iRoot].qLocal);

Vector_Rotate uses formula v'=qpq'. Please help.

Edited by DavidJr

Share this post

Link to post
Share on other sites

Hello, I manage to bind the default pose and store them in local Quaternion-Translation.

How to deform the bone and the mesh after I interpolate two quaternion? I interpolate the quaternions by SLERPing the quaternions.


I manage to deform the bone but the position is in accurate, and try to deform the mesh, it is completely messed up.


This is what I try after slerping the quaternions as qTransform and vTransform.


For Joints:

qLocal = qWorld * qTransform

vLocal = vWorld + vTransform


if has root qLocal = qLocal.parent * qLocal.child, rotate the vLocal by the qLocal.Parent and then add it to vLocal.


For mesh:

Rotate the vertex data by the joint ID and add the result to the vertex data.





Real position:



Any suggestion?

Share this post

Link to post
Share on other sites
You need to start with the root and work down the the tree

void visitBone(bone, parentRotation, parentPosition)
  bone.qWorld = Quaternion_Multiply(parentRotation, bone.qLocal);
  bone.vWorld = Vector_Rotate(bone.vLocal, parentRotation) + parentPosition;

  foreach (child in bone.children)
    visitBone(child, bone.qWorld, bone.vWorld);

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!