1
\$\begingroup\$

I'm having an extremely difficult time trying to convert an FBX file into a format that can be used with DirectX. I've read a lot of articles on forums all over the internet and have followed instructions carefully but have not yet been successful in loading a skinned mesh from an FBX file.

As I understand it, I am required to set the 'Bone Offset' field of a DirectX skinned mesh frame to the inverse bind pose of the bone which I can get using FBX SDK like so:

            // iterate deformers( TODO: ACCOUNT FOR MULTIPLE DEFORMERS )
            for(int i = 0; i < ncDeformers && i < 1; ++i)
            {
                // skin
                FbxSkin *pSkin = (FbxSkin*)pMesh->GetDeformer(i, FbxDeformer::eSkin);
                if(pSkin == NULL)
                    continue;

            // bone count
            int ncBones = pSkin->GetClusterCount();

            // print
            printf("\n\t::Skin Found::");
            printf("\n\t\tBone Count: %i", ncBones);

            // iterate bones
            for (int boneIndex = 0; boneIndex < ncBones; ++boneIndex)
            {                       
                // cluster
                FbxCluster* cluster = pSkin->GetCluster(boneIndex);

                // bone ref
                FbxNode* pBone = cluster->GetLink();
                FbxNode* pParentBone = pBone->GetParent();

                // Get the bind pose
                FbxAMatrix bindPose,
                    inverseBindPose, 
                    transform;
                cluster->GetTransformMatrix(transform);
                cluster->GetTransformLinkMatrix(bindPose);

                // inverted global transform * transform
                inverseBindPose = bindPose.Inverse();

                // set bone offset
                pSkinnedMeshContext->SetBoneOffset(boneIndex, inverseBindPose);
    ...
}

Then I get animation like this:

// for each key
for (int keyIndex = 0; keyIndex < ncKeys; keyIndex++)
{
    // get time object
    FbxTime curtime = std::min(stop.Get(), start.Get() + (interval * keyIndex));

    // node transform at time T
    FbxAMatrix mKeyValue = pAnimEvaluator->GetNodeGlobalTransform(pNode, curtime);
}

Then in my renderer I have this:

Matrix[] maPalette = new Matrix[8];
for(int iBone = 0; iBone < boneCombination->BoneCount; ++iBone)
{
    Matrix mBoneTransformAtTimeT = maPalette[iBone] = meshContainer.BoneOffsets[iBone] * meshContainer.Palette[iBone].CombinedTransform;
}

effect.SetBoneTransforms(maPalette);

The model, however, is disfigured... skinned mesh: enter image description here

standard mesh: enter image description here

What is the proper way to evaluate the transforms for a skinned mesh when converting from FBX to DirectX 9?

\$\endgroup\$
  • \$\begingroup\$ Autodesk FBX is a complex file format, and you are trying to use the ancient and deprecated D3DX9 library for your animation control. I'd suggest taking a look at the DirectX SDK Samples Content Exporter which creates SDKMESH files as that might help shed some light on your problem. \$\endgroup\$ – Chuck Walbourn Jan 5 '16 at 6:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.