I'm trying to implement skeletal animation on my 3D Enigne (DX 11). Skinning part is working fine, but there is little problem with bone matrices transformation. I'm using self made binary format which is based on Valve's SMD and already converted to left-handed coordinate system (Y-Z swap). So there is my bone-to-world code:
for(int i = 0; i < Model->numJoints; i++)
{
Bones[i].WorldPos = XMFLOAT3(0.0f, 0.0f, 0.0f);
Joint tmpJoint = Model->joints[i]; //bind-pose bone data (translation + orientation)
//Rotation matrix calculation
XMMATRIX RotX = XMMatrixRotationX(-tmpJoint.orientation.x);
XMMATRIX RotY = XMMatrixRotationY(-tmpJoint.orientation.y);
XMMATRIX RotZ = XMMatrixRotationZ(-tmpJoint.orientation.z);
//Rot * Translation
XMMATRIX Local = RotX * RotY * RotZ * XMMatrixTranslation(tmpJoint.pos.x, tmpJoint.pos.y, tmpJoint.pos.z);
XMMATRIX tmp;
if (Model->Skeleton.parentID[i] != -1)
{
Bones[i].global = Local * Bones[Model->Skeleton.parentID[i]].global;
}
else
Bones[i].global = Local;
XMVECTOR temp;
XMStoreFloat3(&Bones[i].WorldPos, XMVector3Transform(temp, Bones[i].global));
}
//line between 2 connected bones (aka skeleton)
bonePoints[i] = Bones[i].WorldPos; //bone position in world
bonePoints[i+1] = Bones[Model->Skeleton.parentID[i]].WorldPos; //parent bone position in world
as you can see at pictures below, calculated sekeleton looks deformed. I think something wrong with rotation calculation part, maby some extra transpose is missed. I tryed to change matrix multiplication order but without any success.