Exporting FBX to DirectX File Format

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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?