Hello,
I have been fighting for sometime now with exporting animations from Maya to my own engine using DirectX 11.
I export the fbx file with all its content in it.
So the problem i have is that the animation dosnt seem to rotate the joints correctly?
Please see the attached screenshots.
bindpose.png = Frame 1 (first keyframe is at frame 2), the bindpose, no animation applied.
frame30.png = Frame 30, rotation applied to two joints.
engine.png = Frame 30 of animation in engine, rotation != rotation in Maya
I use my custom tool to export data from the fbx file using the fbx sdk.
The following is how i extract the skeleton bind pose and inverse bind pose transforms using fbx sdk:
(Note: freeze transformation have been applied to the mesh, so i ignore the geometry transform since its just an identity)
FbxAMatrix localTransform = p_Node->EvaluateLocalTransform();
joint->m_Location = localTransform.GetT();
joint->m_Scale = localTransform.GetS();
joint->m_Rotation = localTransform.GetQ();
FbxAMatrix inverseBindTransform = p_Node->EvaluateGlobalTransform().Inverse();
joint->m_InverseLocation = inverseBindTransform.GetT();
joint->m_InverseScale = inverseBindTransform.GetS();
joint->m_InverseRotation = inverseBindTransform.GetQ();
Then i extract information about each join for all keyframes, in this example i only sample rotation:
for( int i=0; i<rotationCurve->KeyGetCount(); ++i ) {
FbxAnimCurveKey key = rotationCurve->KeyGet( i );
FbxTime time = key.GetTime();
FbxAMatrix transform = p_Node->EvaluateLocalTransform( time );
// setup frame
JointFrame frame;
frame.m_IsRotation = true;
frame.m_Frame = time.GetFrameCount( m_AnimFramerate );
frame.m_Rotation = transform.GetQ();
joint->m_RotationKeyframes.add( frame );
}
When i look at the rotation values from Maya i see that sometimes the axis of the quaternion is 0,0,0 assuming that the axis is mData[0-2].
So i must be doing something wrong here right?
Thats the fbx part.
Then in my engine i load the resources.
This is how i setup and update the skeleton transforms:
(Note: m_Rotation is a quaternion)
void pmJoint::computeMatrices( pmJoint * p_Parent ) {
if( m_IsDirty ) {
pmMath::matrixCreateTransform( &m_LocalTransform, m_Location, m_Scale, m_Rotation );
}
if( p_Parent ) {
if( p_Parent->m_IsDirty || m_IsDirty ) {
m_WorldTransform = m_LocalTransform * p_Parent->m_WorldTransform;
m_IsDirty = true;
}
} else if( m_IsDirty ) {
m_WorldTransform = m_LocalTransform;
}
for( pmUInt32 i=0; i<m_Children.count(); ++i ) {
m_Children[ i ]->computeMatrices( this );
}
}
So as you can see, all bones operate in their localspace using their parents world to update their world.
Then to get the render matrices i call this function:
void pmJoint::computeRenderMatrices() {
m_RenderTransform = m_InversBindTransform * m_WorldTransform;
for( pmUInt32 i=0; i<m_Children.count(); ++i ) {
m_Children[ i ]->computeRenderMatrices();
}
}
The animation part is simply lerping and slerping.
I get the problem no matter if i interpolate or just show keyframe poses, so i left that code out.
Any input, idea or crazy thought is welcome.
Im at a loss here.
↧