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