Quaternion Skinning

Started by
3 comments, last by HappyCoder 8 years, 5 months ago

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:

[attachment=29875:Quaternion.jpg]

While it should be like this:
[attachment=29876:Real.jpg]

Thanks

Advertisement
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
My current game project Platform RPG

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

example:

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.

Untitled.jpg


        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.

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.

Result:

Quaternion.jpg

Real position:

Real.jpg

Any suggestion?

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);
  }
}

My current game project Platform RPG

This topic is closed to new replies.

Advertisement