kalmiya

05-20-2017, 12:00 AM

Hello,

I'm experimenting with skinning and trying to do the calculation directly with the quaternion, but I'm stuck getting the translation to be the same as with the matrix. I

In the code-block below I know that the matrix is correct (mesh is displayed correctly). Now instead of using the matrix, I'm trying to do the same but directly using the quaternion. For verifying, I create a matrix out of the Quaternion + vector. The problem is that the 3x3 rotation-part of that matrix is correct but the translation isn't.

Question: How do I calculate the worldspace-translation using the current localspace-quaternion/translation + parent-worldspace-quaternion/translation ?

void _computeWorldPose(const Model& model, const Animation& anim, size_t frame, KeyFrame& keyframe)

{

// reserve space for the output

keyframe.pose.resize(model.rig.size());

keyframe.poseQ.resize(model.rig.size());

keyframe.poseT.resize(model.rig.size());

for (int b=0; b<model.rig.size(); b++)

{

// anim-bone-index may have different index as model-bone-index, lookup by name

int abid = anim.getIndexByName(model.rig[b].name);

if(abid!=-1)

{

Quaternion qq;

vector3 pos;

float scale;

unsigned int parentid = model.rig[b].ParentID;

anim.GetDataForKeyframe(abid, frame, qq, pos, scale);

// prepare the matrix

Quaternion q = qq.Inverse(); // (not entirely sure why, but with this the mesh is rendered correctly... )

matrix4 m4 = q.ToMatrix4();

m4.set_translation(pos);

// do calculation as Matrix and as Quaternion

keyframe.pose[b] = keyframe.pose[parentid] * m4;

keyframe.poseQ[b] = q * keyframe.poseQ[parentid];

keyframe.poseT[b] = q.transform(pos) + keyframe.poseT[parentid]; // ? what needs to be done here ?

// verify that we get the same result

matrix4 m(keyframe.poseQ[b], keyframe.poseT[b]);

if (keyframe.pose[b] != m) {

assert(0); // this fires, with the 3x3-rotation being identical, but translation is different

}

}

else

{

// "Root"

keyframe.pose[b].identity();

keyframe.poseQ[b] = Quaternion();

keyframe.poseT[b] = VECTOR3_ZERO;

}

}

}

I'm experimenting with skinning and trying to do the calculation directly with the quaternion, but I'm stuck getting the translation to be the same as with the matrix. I

In the code-block below I know that the matrix is correct (mesh is displayed correctly). Now instead of using the matrix, I'm trying to do the same but directly using the quaternion. For verifying, I create a matrix out of the Quaternion + vector. The problem is that the 3x3 rotation-part of that matrix is correct but the translation isn't.

Question: How do I calculate the worldspace-translation using the current localspace-quaternion/translation + parent-worldspace-quaternion/translation ?

void _computeWorldPose(const Model& model, const Animation& anim, size_t frame, KeyFrame& keyframe)

{

// reserve space for the output

keyframe.pose.resize(model.rig.size());

keyframe.poseQ.resize(model.rig.size());

keyframe.poseT.resize(model.rig.size());

for (int b=0; b<model.rig.size(); b++)

{

// anim-bone-index may have different index as model-bone-index, lookup by name

int abid = anim.getIndexByName(model.rig[b].name);

if(abid!=-1)

{

Quaternion qq;

vector3 pos;

float scale;

unsigned int parentid = model.rig[b].ParentID;

anim.GetDataForKeyframe(abid, frame, qq, pos, scale);

// prepare the matrix

Quaternion q = qq.Inverse(); // (not entirely sure why, but with this the mesh is rendered correctly... )

matrix4 m4 = q.ToMatrix4();

m4.set_translation(pos);

// do calculation as Matrix and as Quaternion

keyframe.pose[b] = keyframe.pose[parentid] * m4;

keyframe.poseQ[b] = q * keyframe.poseQ[parentid];

keyframe.poseT[b] = q.transform(pos) + keyframe.poseT[parentid]; // ? what needs to be done here ?

// verify that we get the same result

matrix4 m(keyframe.poseQ[b], keyframe.poseT[b]);

if (keyframe.pose[b] != m) {

assert(0); // this fires, with the 3x3-rotation being identical, but translation is different

}

}

else

{

// "Root"

keyframe.pose[b].identity();

keyframe.poseQ[b] = Quaternion();

keyframe.poseT[b] = VECTOR3_ZERO;

}

}

}