We’re having some problems getting our skinned mesh animation to work correctly when converting an FBX to our own format. Whenever animation is applied, the model seems to rotate 90 degrees about the X axis. I’m sure it has to be something to do with either the PreRotation or the coordinate system conversion, but I’m not sure exactly what. The steps we go through are:
The FBX is saved out with Y-Up from 3DS Max. It contains a mesh which is skinned using CAT.
Each node has its original transformation stored as Translation, Rotation Quaternion and Scale, using the following code:
Then when we are rendering, we calculate the skinning matrices like so:
// Get the transformation for the bone const MathsNS::Matrix4x4& boneTransform = pNodeInstance->GetTransform();
// Get the inverse transform for the original bone node const MathsNS::Matrix4x4& invBoneTransform = CurrentMesh->m_BoneInvBindPoseMatrices[boneIndex];
// Set the shader parameter for this bone boneMatrices.push_back(boneTransform * invBoneTransform);
Like I mentioned, the whole thing seems to work fine, and animates OK, but the mesh is rotated 90 degrees on the X axis. If we replace the last line with:
The mesh faces the correct way, so my thinking is that the inverse bind pose matrices and everything are OK, but the animation transformations or maybe the default pose transformations are not retrieved properly. When rendering, all mesh / bone node transformations are calculated by constructing the matrix from the transforms retrieved in the first code segment and multiplying by the relative transformation matrices constructed from the data in the second code segment.
Does anyone have any idea what we’re doing wrong, or why we might be seeing this 90 degree rotation? I thought using EvaluateLocalTransform was supposed to take all of the Pre/Post rotation stuff into consideration. Maybe there’s a step we’ve missed or something?
There are two things looks suspicious:
1. “The FBX is saved out with Y-Up from 3DS Max.” The default setting of 3DS Max is Z-up, so save it out with Y-up will introduce a 90 degree rotation on X axis, does that one considered properly?
2. “all mesh / bone node transformations are calculated by constructing the matrix from the transforms retrieved in the first code segment”. Here the code calls EvaluateLocalTransform, then extract TRSQ from the matrix, and then combine them back to a matrix later when necessary. This matrix extraction and combination process looks vulnerable. Can you use the matrix from EvaluateLocalTransform directly?
I thought the FBX SDK was supposed to take the whole Y-Up / Z-Up conversion into account when using EvaluateLocalTransform. Does it not do this? It does seem to rotate everything when we export using Z-Up
I’ll try using the matrix directly, but that will take a bit of time to modify the pipeline. If anyone has any other ideas, please let me know.
I think I’ve found the problem. The engine was multiplying by the nodes transformation matrix as well as the skinning matrices. We needed to ignore the transformations on the mesh nodes that were skinned.