Bones and Biped Matrix on translation

Bones and Biped Matrix on translation

Anonymous
Not applicable
582 Views
1 Reply
Message 1 of 2

Bones and Biped Matrix on translation

Anonymous
Not applicable
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.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...
0 Likes
583 Views
1 Reply
Reply (1)
Message 2 of 2

Anonymous
Not applicable
Up ^^ ?!

I still have the issue for the bones translations 😕
Any clue ?
0 Likes