Original Post
Hi everyone!
I'm building a Direct3D based game engine.
I use my own file format for static / skinned meshes.
The exporter is based on an article from The Game Engine Architecture book and The NVidia nv-exporter sample (So it is the shader code).
My problem is that the bones I export do not "influence" properly the vertices, this way I get some strange skin deformations.
My approach was:
(I) In the exporter
I'm building a Direct3D based game engine.
I use my own file format for static / skinned meshes.
The exporter is based on an article from The Game Engine Architecture book and The NVidia nv-exporter sample (So it is the shader code).
My approach was:
(I) In the exporter
- Export initial bone position and orientation (quaternion) in world space (flip z with y)
- For every frame (sample) - export bone position and orientation (quaternion) also in world space (flip z with y)(II) In the engine
- Load initial bone position and orientation
- D3DXMatrixRotationQuaternion(&mQ, &Q);
- D3DXMatrixTranslate(&mT, &T);
- D3DXMatrixMultiply(&matBone, &mQ, &mT);
- D3DXMatrixInverse(&matInvBose, NULL, &matBone); - Update the bone's matrice based on the key and send to shader
- The same as above except I don't invert matInvBone
- Set the shader matrice as matBone * matInvBindPose
This code decomposes the transform matrices and swaps Z with Y:
static void GetIGameTransform(Matrix3 m, geo::VERT3 &T, geo::VERT4 &Q)
{
m.NoScale();
AffineParts ap;
decomp_affine(m, ≈);
T.set(ap.t.x, ap.t.z, ap.t.y);
Q.set(ap.q.x, ap.q.z, ap.q.y, ap.q.w);
}
This code gets the initial bone transform matrices:
// get initial bone matrix
for (int b = 0; b < boneIDs.Count(); b++)
{
// Get parent
...
// Get its transform matrix
GMatrix mat;
pSkin->GetInitBoneTM(pCurrent, mat);
geo::VERT4 Q;
geo::VERT3 T;
GetIGameTransform(mat.ExtractMatrix3(), T, Q);
SkeletonJoint* pJoint = new SkeletonJoint(name, parent, T, Q);
pSkeleton->AddJoint(pJoint);
}
The following code exports bones animation:
geo::VERT3 T;
geo::VERT4 Q;
IGameNode * node = boneIDs[iNode]->pNode; // pSkin->GetIGameBone(vertex, bone);
GetIGameTransform(node->GetWorldTM(t).ExtractMatrix3(), T, Q);
pSQT->SetRotation(Q);
pSQT->SetTranslation(T);
pKey->AddSQT(pSQT);
And the update code:
Skeleton* pSkeleton = m_pClip->GetSkeleton();
for (unsigned int i = 0; i < pSkeleton->m_joints.Count(); i++)
{
SkeletonJoint* pJoint = pSkeleton->m_joints;
AnimationPose* pAnimation = m_pClip->m_samples[m_iKey];
SQT* pSQT = pAnimation->m_jointPoses;
#ifndef EXPORTER
D3DXMATRIX matTmp, matT, matQ;
D3DXMatrixTranslation(&matT, pSQT->T.x, pSQT->T.y, pSQT->T.z);
D3DXMatrixRotationQuaternion(&matQ, &pSQT->Q);
matTmp = matQ * matT;
m_globalPoses = matTmp * pJoint->m_InvBindPose;
#endif
}
The results:
, when the initial bone matrice == animation matrice (M * M[sup]-1[/sup]=matrix identity)



Thank you!
- Load initial bone position and orientation