Exporting FBX to DirectX File Format

Exporting FBX to DirectX File Format

Anonymous
Not applicable
704 Views
0 Replies
Message 1 of 1

Exporting FBX to DirectX File Format

Anonymous
Not applicable

I'm trying to write an FBX exporter in C++. I am having trouble converting skinning info. I have read many articles and posts on the subject but cannot get the skinned mesh to draw correctly. In my exporter I extract skinning info for each bone associated with the skeleton. Here is my inverse bind pose calc:

 

if(bHasDeformer)
        {
            pMeshElement->LinkEndChild(pSkinElement = new TiXmlElement("SkinInfo"));
            pSkinElement->SetAttribute("Count", ncDeformers);

            if(ncDeformers > 1)
                printf("\n\t!!Multiple deformers found...this application only supports one deformer per mesh!!");
                        
            // 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();

                TiXmlElement *pDeformerElement = NULL;
                pSkinElement->LinkEndChild(pDeformerElement = new TiXmlElement("Deformer"));
                pDeformerElement->SetAttribute("Count", ncBones);
                
                // 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();

                    // Get the bind pose
                    FbxAMatrix bindPoseMatrix,
                        transformMatrix,
                        geometryTransform;
                    cluster->GetTransformMatrix(transformMatrix);
                    cluster->GetTransformLinkMatrix(bindPoseMatrix);
                    geometryTransform = GetGeometryTransformation(pNode);
                    
                    // inverted global transform * transform - DIRECTX's Offset transform
                    bindPoseMatrix = bindPoseMatrix.Inverse();
                    
                    // insert key, valuej pair
                    g_mapBindPose.insert(std::pair<FbxNode*, FbxAMatrix>(pBone, bindPoseMatrix));

                    TiXmlElement *pBoneElement = NULL;
                    pDeformerElement->LinkEndChild(pBoneElement = new TiXmlElement("SubDeformer"));
                    pBoneElement->SetAttribute("Name", pBone->GetName());

                    // print
                    printf("\n\t\tBone %i: %s", boneIndex, pBone->GetName());

                    // local transform xml element
                    pBoneElement->LinkEndChild(pLS = new TiXmlElement("GScaling"));
                    pBoneElement->LinkEndChild(pLR = new TiXmlElement("GRotation"));
                    pBoneElement->LinkEndChild(pLT = new TiXmlElement("GTranslation"));
                    
                    // decomposed transform elements
                    vS = bindPoseMatrix.GetS();
                    vR = bindPoseMatrix.GetR();
                    vT = bindPoseMatrix.GetT();

                    // set transform attributes
                    pLS->SetDoubleAttribute("X", vS.Buffer()[0]);
                    pLS->SetDoubleAttribute("Y", vS.Buffer()[1]);
                    pLS->SetDoubleAttribute("Z", vS.Buffer()[2]);

                    pLR->SetDoubleAttribute("X", vR.Buffer()[0]);
                    pLR->SetDoubleAttribute("Y", vR.Buffer()[1]);
                    pLR->SetDoubleAttribute("Z", vR.Buffer()[2]);

                    pLT->SetDoubleAttribute("X", vT.Buffer()[0]);
                    pLT->SetDoubleAttribute("Y", vT.Buffer()[1]);
                    pLT->SetDoubleAttribute("Z", vT.Buffer()[2]);


                    // influence count
                    int ncVertexIndices = cluster->GetControlPointIndicesCount();
                    
                    // vertex indices and weights
                    int *pVertexIndices = cluster->GetControlPointIndices();
                    double *pVertexWeights = cluster->GetControlPointWeights();

                    // skin data elements
                    TiXmlElement *pBoneIndicesElement = NULL, *pBoneWeightsElement = NULL;
                    pBoneElement->LinkEndChild(pBoneIndicesElement = new TiXmlElement("Indices"));
                    pBoneElement->LinkEndChild(pBoneWeightsElement = new TiXmlElement("Weights"));
                    pBoneIndicesElement->SetAttribute("Count", ncVertexIndices);
                    pBoneWeightsElement->SetAttribute("Count", ncVertexIndices);

                    // clear streams
                    ss.str("");
                    ss.clear();
                    ssB.str("");
                    ssB.clear();

                    //iterate through all vertices influenced by this bone
                    for (int iBoneVertexIndex = 0; iBoneVertexIndex < ncVertexIndices; iBoneVertexIndex++)
                    {
                        bool bLast = iBoneVertexIndex == ncVertexIndices - 1;

                        // vertex
                        int niVertex = pVertexIndices[iBoneVertexIndex];
                        double fWeight = pVertexWeights[iBoneVertexIndex];

                        // stream skin data
                        ss << niVertex << (bLast ? "" : ", ");
                        ssB << fWeight << (bLast ? "" : ", ");
                    }

                    // link skin data
                    pBoneIndicesElement->LinkEndChild(new TiXmlText(ss.str()));
                    pBoneWeightsElement->LinkEndChild(new TiXmlText(ssB.str()));
                }
                
                // print new line
                printf("\n");
            }

 

The above code calculates what DirectX calls the 'offset' transform. Can someone please let me know what I am doing wrong?

 

 

0 Likes
705 Views
0 Replies
Replies (0)