I'm trying to import a skeletal animation using FBX SDK. I followed this article, managing to load all the needed data, but when I try to display the animation the mesh falls apart. My knowledge of skeletal animation is fairly limited which may be the issue.
Here is the animation code
for (int i = 0; i < m_numTriangles; i++)
{
for (int j = 0; j < 3; j++)
{
currVertex = m_verticies[m_triangles[i].vertices[j]];
posVec1.Set(0, 0, 0);
normVec1 = currVertex.normal;
for (int k = 0; k < currVertex.blendingInfo.size(); ++k)
{
jointIndex = currVertex.blendingInfo[k].index;
jointWeight = currVertex.blendingInfo[k].weight;
if (jointWeight != 0)
{
transMat1 = m_skeleton.joints[jointIndex].animation[frameIndex1 - 1].transform;
temp = transMat1.MultT(currVertex);
posVec1 += temp*jointWeight;
}
}
glNormal3f(normVec1.mData[0], normVec1.mData[1], normVec1.mData[2]);
glVertex3f(posVec1.mData[0], posVec1.mData[1], posVec1.mData[2]);
}
}
I iterate over all the triangles, get the vertices, iterate over all the joints that affect said vertex, get the transformation matrix for the current frame and apply.
I believe the problem is with how I'm applying the matrix, but I don't know what I'm doing wrong. I think either I'm skipping a step or I'm misunderstanding what the transform matrix represents.
The article retrieves the global bind pose inverse as follows
currCluster->GetTransformMatrix(transformMatrix); // The transformation of the mesh at binding time
currCluster->GetTransformLinkMatrix(transformLinkMatrix); // The transformation of the cluster(joint) at binding time from joint space to world space
globalBindposeInverseMatrix = transformLinkMatrix.Inverse() * transformMatrix * geometryTransform;
This is done for each joint. Do I need to multiply this with the transform matrix before applying to vertex? Like this
transMat1 = m_skeleton.joints[jointIndex].animation[frameIndex1 - 1].transform * m_skeleton.joints[jointIndex].globalBindposeInverse;
Or do I need to also multiply each joints globalBindposeInverse with its parents first?
This is how the article calculates the transform for each frame of animation
for (FbxLongLong i = m_startFrame; i <= m_endFrame; ++i)
{
FbxTime currTime;
currTime.SetFrame(i, FbxTime::eFrames24);
currAnim.number = i;
FbxAMatrix currentTransformOffset = inNode->EvaluateGlobalTransform(currTime);
currentTransformOffset *= geometryTransform;
currAnim.transform = currCluster->GetLink()->EvaluateGlobalTransform(currTime);
currAnim.transform *= currentTransformOffset.Inverse();
m_skeleton.joints[currJointIndex].animation.push_back(currAnim);
}
I'm sorry if this is a trivial question, but I've been stuck on this for 4 days now.