|
Hello,
I still working on a ogre export and I saw some strange effects on bone translations.
I get correct bone Orientation but with the same matrix I get a translation reverted on some axes depending of the parent bone.
Should I use a different matrix for translations ?
Here my code.
matrix manipulation code :
inline Matrix3 UniformMatrix(Matrix3 orig_cur_mat, bool yUp) {
AffineParts parts;
Matrix3 mat;
Matrix3 YtoZ;
Matrix3 ZtoY;
GMatrix gmat;
gmat.SetRow(0, Point4(1, 0, 0, 0));
gmat.SetRow(1, Point4(0, 0, 1, 0));
gmat.SetRow(2, Point4(0, -1, 0, 0));
gmat.SetRow(3, Point4(0, 0, 0, 1));
YtoZ = gmat.ExtractMatrix3();
ZtoY = Inverse(YtoZ);
///Remove scaling from orig_cur_mat
//1) Decompose original and get decomposition info
decomp_affine(orig_cur_mat, &parts);
//2) construct 3x3 rotation from quaternion parts.q
parts.q.MakeMatrix(mat);
//3) construct position row from translation parts.t
mat.SetRow(3, parts.t);
if (yUp)
mat = YtoZ * mat * ZtoY;
return(mat); }
inline Matrix3 GetRelativeUniformMatrix(Matrix3 mat1, Matrix3 mat2, bool yUp) {
Matrix3 dest_mat;
//Decompose each matrix
Matrix3 cur_mat = UniformMatrix(mat1, yUp);
Matrix3 par_mat = UniformMatrix(mat2, yUp);
//then return relative matrix in coordinate space of parent
dest_mat = cur_mat * Inverse(par_mat);
return dest_mat; }
Now get the initial bone matrix
// Get mesh matrix at initial pose
ISkin* pskin = (ISkin*)m_pGameSkin->GetMaxModifier()->GetInterface(I_SKIN);
GMatrix GSkinTM;
m_pGameSkin->GetInitSkinTM(GSkinTM);
Matrix3 SkinTM = GSkinTM.ExtractMatrix3();
Matrix3 boneTM;
Matrix3 ParentTM;
if(pskin->GetBoneInitTM(pNode, boneTM, false) == SKIN_INVALID_NODE_PTR)
boneTM = pNode->GetNodeTM(firstFrame);
if(pskin->GetBoneInitTM(pNodeParent, ParentTM, false) == SKIN_INVALID_NODE_PTR)
ParentTM = pNodeParent->GetNodeTM(firstFrame);
Matrix3 localTM;
if(parentIdx >= 0)
{
localTM = GetRelativeUniformMatrix(boneTM, ParentTM, m_params.yUpAxis);
}
else // for root bone use the mesh
{
localTM = GetRelativeUniformMatrix(boneTM, ParentTM, m_params.yUpAxis) * Inverse(SkinTM);
}
m_joints[boneIndex].bindMatrix = localTM;
And now getting the relative matrix by time
INode* bone = j.pNode;
// Get the bone local matrix for this key
Matrix3 boneTM = GetRelativeUniformMatrix(bone, time, m_params.yUpAxis);
GMatrix GSkinTM;
m_pGameSkin->GetInitSkinTM(GSkinTM);
Matrix3 SkinTM = GSkinTM.ExtractMatrix3();
// for root bone use the mesh
if(j.parentIndex < 0)
boneTM = boneTM * Inverse(SkinTM);
Matrix3 relMat = boneTM * Inverse(j.bindMatrix);
AffineParts ap;
decomp_affine(relMat, &ap);
Point3 trans = ap.t * m_params.lum;
Point3 scale = ap.k;
Quat rot = ap.q;
// Notice that in Max we flip the w-component of the quaternion;
rot.w = -rot.w;
//create keyframe
skeletonKeyframe key;
key.time = 0;
// don't know why root translation are Z X reverted
// what matrix should I use for translations ?
if(IsBipedRoot(bone))
{
key.trans.x = -trans.z;
key.trans.y = trans.y;
key.trans.z = trans.x;
}
else if(IsBipedRoot(bone->GetParentNode()))
{
key.trans.x = trans.x;
key.trans.y = -trans.z;
key.trans.z = trans.y;
}
else
{
key.trans.x = trans.z;
key.trans.y = trans.x;
key.trans.z = trans.y;
}
key.rot = rot;
key.scale = scale;
return key;
So as you can see I use a strange hack to get the correct translation in some cases…
|