Hi, I`m using Fbx SDK to export our simulated scene into Maya/3d Max. Currently my problem is that a character`s skeleton is animated correctly, but his mesh goes in the wrong direction and has some additional rotation (it is not distorted, the mesh is skinned correctly). This problem happens in Maya, in 3d Max all is right. I`ve attached an fbx file (which is not the original one written by me, but imported into the 3d max and then exported back to fbx). Maybe this happens because I don`t create the bind pose when i write the file using the SDK. Below is the code I use to process a skin, computeBindPose is called after the skin is processed, it is commented out because it does not fix the problem and makes the resulting fbx import time very long, it is taken from SDK sample and maybe I`ve adapted it in a wrong way:
SkinProxy::SkinProxy(const SkeletonProxyPtr& skeleton, FbxWriter* writer)
:
mSkeleton(skeleton),
mWriter(writer)
{
mFbxSkin = KFbxSkin::Create(mWriter->getFbxScene(), "");
}
//----------------------------------------------------------------------------------------
KFbxSkin* SkinProxy::getFbxSkin()
{
return mFbxSkin;
}
//----------------------------------------------------------------------------------------
void SkinProxy::addInfluence(unsigned int boneIndex, unsigned int vertexIndex, float weight, const Ogre::Mesh::IndexMap& indexMap)
{
//boneIndex = indexMap;
Clusters_t::iterator i = mClusters.find(boneIndex);
KFbxCluster* cluster = 0;
if(boneIndex >= mSkeleton->getOgreSkeleton()->getNumBones())
{
for (size_t v = 0; v < indexMap.size(); ++v)
{
if (indexMap
== boneIndex)
{
boneIndex = v;
break;
}
}
}
if (i == mClusters.end())
{
Ogre::Bone* ogreBone = mSkeleton->getOgreSkeleton()->getBone(boneIndex);
if (!ogreBone)
{
LOG_ERROR("Failed to find a bone in Ogre skeleton");
return;
}
const BoneProxy* proxy = mSkeleton->findBone(ogreBone->getHandle());
if (!proxy)
{
LOG_ERROR("Failed to find a bone " << ogreBone->getName() << " in FBX skeleton");
return;
}
cluster = KFbxCluster::Create(mWriter->getFbxScene(), "");
cluster->SetLinkMode(KFbxCluster::eTOTAL1);
cluster->SetLink(proxy->getFbxBone());
KFbxXMatrix transformMatrix, transformLinkMatrix;
transformMatrix.SetIdentity();
// all joints have the same transformMatrix.
cluster->SetTransformMatrix(transformMatrix);
//cluster->SetTransformAssociateModelMatrix(transformMatrix);
//cluster->SetTransformParentMatrix(transformMatrix);
// compute global transformation of each joint and set it as transformLinkMatrix.
transformLinkMatrix = cluster->GetLink()->EvaluateGlobalTransform();
cluster->SetTransformLinkMatrix(transformLinkMatrix);
mFbxSkin->AddCluster(cluster);
mClusters.insert(Clusters_t::value_type(boneIndex, cluster));
}
else
{
cluster = i->second;
}
cluster->AddControlPointIndex(vertexIndex, weight);
}
//----------------------------------------------------------------------------------------
void SkinProxy::computeBindPose()
{
/*for (auto root = mSkeleton->getFbxSkeletonRoots().begin(); root != mSkeleton->getFbxSkeletonRoots().end(); ++root)
{
KFbxNode* rootBone = *root;
//create a pose by the node array and set it as bindpose.
KFbxPose* pose = KFbxPose::Create(mWriter->getFbxScene(), rootBone->GetName());
pose->SetIsBindPose(true);
//add the bindpose to the scene.
processBone(rootBone, pose);
mWriter->getFbxScene()->AddPose(pose);
}*/
}
//----------------------------------------------------------------------------------------
void SkinProxy::processBone(KFbxNode* bone, KFbxPose* pose)
{
KFbxMatrix bindMatrix = bone->EvaluateGlobalTransform();
pose->Add(bone, bindMatrix);
for (int i = 0; i < bone->GetChildCount(); ++i)
{
processBone(bone->GetChild(i), pose);
}
}character_2.zip