#include <fbxsdk.h>
#include "../Common/Common.h"
#include "DisplayCommon.h"
const char * SAMPLE_FILENAME = "JointHierarchy.fbx";
FbxAMatrix CalculateGlobalTransform(FbxNode* pNode);
void CompareTransformations( FbxNode* pNode, FbxScene* pScene );
int main(int argc, char** argv)
{
FbxManager* lSdkManager = NULL;
FbxScene* lScene = NULL;
bool lResult;
InitializeSdkObjects(lSdkManager, lScene);
FbxString lFilePath("");
for( int i = 1, c = argc; i < c; ++i )
{
if( FbxString(argv[i]) == "-test" ) continue;
else if( lFilePath.IsEmpty() ) lFilePath = argv[i];
}
if( lFilePath.IsEmpty() ) lFilePath = SAMPLE_FILENAME;
FBXSDK_printf("\n\nFile: %s\n\n", lFilePath.Buffer());
lResult = LoadScene(lSdkManager, lScene, lFilePath.Buffer());
if(lResult == false)
{
FBXSDK_printf("\n\nAn error occurred while loading the scene...");
}
else
{
CompareTransformations( lScene->GetRootNode(), lScene );
}
DestroySdkObjects(lSdkManager, lResult);
return 0;
}
void CompareTransformations(FbxNode* pNode, FbxScene * pScene)
{
FbxAnimEvaluator* lEvaluator = pScene->GetEvaluator();
if( pNode != pScene->GetRootNode())
{
DisplayString(pNode->GetName());
FbxNode* lParentNode = pNode->GetParent();
FbxAMatrix lGlobal, lLocal;
lGlobal= lEvaluator->GetNodeGlobalTransform( pNode);
lLocal = lEvaluator->GetNodeLocalTransform(pNode);
FbxAMatrix lParentTransform,lLocalTransform, lGlobalTransform;
lGlobalTransform = CalculateGlobalTransform(pNode);
if(lParentNode)
{
lParentTransform = CalculateGlobalTransform(lParentNode);
lLocalTransform = lParentTransform.Inverse() * lGlobalTransform;
}
else
lLocalTransform = lGlobalTransform;
if(lGlobal == lGlobalTransform)
{
for(int i = 0; i<4; ++i)
{
FbxString lHeader("GlobalTransform Row_");
FbxString lIndex(i);
lHeader += lIndex;
lHeader += ": ";
Display4DVector(lHeader, lGlobal.GetRow(i));
}
FBXSDK_printf("\n");
}
else
{
FBXSDK_printf("Error: The two global transform results are not equal!\n");
for(int i = 0; i<4; ++i)
{
FbxString lHeader("KFbxEvaluatorGlobalTransform Row_");
FbxString lIndex(i);
lHeader += lIndex;
lHeader += ": ";
Display4DVector(lHeader, lGlobal.GetRow(i));
}
FBXSDK_printf("\n");
for(int i = 0; i<4; ++i)
{
FbxString lHeader("FromScratchGlobalTransform Row_");
FbxString lIndex(i);
lHeader += lIndex;
lHeader += ": ";
Display4DVector(lHeader, lGlobalTransform.GetRow(i));
}
FBXSDK_printf("\n");
}
if(lLocal == lLocalTransform)
{
for(int i = 0; i<4; ++i)
{
FbxString lHeader("LocalTransform Row_");
FbxString lIndex(i);
lHeader += lIndex;
lHeader += ": ";
Display4DVector(lHeader, lLocal.GetRow(i));
}
FBXSDK_printf("\n");
}
else
{
FBXSDK_printf("Error: The two local transform results are not equal!\n");
for(int i = 0; i<4; ++i)
{
FbxString lHeader("KFbxEvaluatorLocalTransform Row_");
FbxString lIndex(i);
lHeader += lIndex;
lHeader += ": ";
Display4DVector(lHeader, lLocal.GetRow(i));
}
FBXSDK_printf("\n");
for(int i = 0; i<4; ++i)
{
FbxString lHeader("FromScratchLocalTransform Row_");
FbxString lIndex(i);
lHeader += lIndex;
lHeader += ": ";
Display4DVector(lHeader, lLocalTransform.GetRow(i));
}
FBXSDK_printf("\n");
}
}
int lChildCount = pNode->GetChildCount();
for( int i = 0; i<lChildCount; i++)
{
CompareTransformations(pNode->GetChild(i), pScene);
}
}
FbxAMatrix CalculateGlobalTransform(FbxNode* pNode)
{
FbxAMatrix lTranlationM, lScalingM, lScalingPivotM, lScalingOffsetM, lRotationOffsetM, lRotationPivotM, \
lPreRotationM, lRotationM, lPostRotationM, lTransform;
FbxAMatrix lParentGX, lGlobalT, lGlobalRS;
if(!pNode)
{
lTransform.SetIdentity();
return lTransform;
}
FbxVector4 lTranslation = pNode->LclTranslation.Get();
lTranlationM.SetT(lTranslation);
FbxVector4 lRotation = pNode->LclRotation.Get();
FbxVector4 lPreRotation = pNode->PreRotation.Get();
FbxVector4 lPostRotation = pNode->PostRotation.Get();
lRotationM.SetR(lRotation);
lPreRotationM.SetR(lPreRotation);
lPostRotationM.SetR(lPostRotation);
FbxVector4 lScaling = pNode->LclScaling.Get();
lScalingM.SetS(lScaling);
FbxVector4 lScalingOffset = pNode->ScalingOffset.Get();
FbxVector4 lScalingPivot = pNode->ScalingPivot.Get();
FbxVector4 lRotationOffset = pNode->RotationOffset.Get();
FbxVector4 lRotationPivot = pNode->RotationPivot.Get();
lScalingOffsetM.SetT(lScalingOffset);
lScalingPivotM.SetT(lScalingPivot);
lRotationOffsetM.SetT(lRotationOffset);
lRotationPivotM.SetT(lRotationPivot);
FbxNode* lParentNode = pNode->GetParent();
if(lParentNode)
{
lParentGX = CalculateGlobalTransform(lParentNode);
}
else
{
lParentGX.SetIdentity();
}
FbxAMatrix lLRM, lParentGRM;
FbxVector4 lParentGR = lParentGX.GetR();
lParentGRM.SetR(lParentGR);
lLRM = lPreRotationM * lRotationM * lPostRotationM;
FbxAMatrix lLSM, lParentGSM, lParentGRSM, lParentTM;
FbxVector4 lParentGT = lParentGX.GetT();
lParentTM.SetT(lParentGT);
lParentGRSM = lParentTM.Inverse() * lParentGX;
lParentGSM = lParentGRM.Inverse() * lParentGRSM;
lLSM = lScalingM;
FbxTransform::EInheritType lInheritType = pNode->InheritType.Get();
if(lInheritType == FbxTransform::eInheritRrSs)
{
lGlobalRS = lParentGRM * lLRM * lParentGSM * lLSM;
}
else if(lInheritType == FbxTransform::eInheritRSrs)
{
lGlobalRS = lParentGRM * lParentGSM * lLRM * lLSM;
}
else if(lInheritType == FbxTransform::eInheritRrs)
{
FbxAMatrix lParentLSM;
FbxVector4 lParentLS = lParentNode->LclScaling.Get();
lParentLSM.SetS(lParentLS);
FbxAMatrix lParentGSM_noLocal = lParentGSM * lParentLSM.Inverse();
lGlobalRS = lParentGRM * lLRM * lParentGSM_noLocal * lLSM;
}
else
{
FBXSDK_printf("error, unknown inherit type! \n");
}
lTransform = lTranlationM * lRotationOffsetM * lRotationPivotM * lPreRotationM * lRotationM * lPostRotationM * lRotationPivotM.Inverse()\
* lScalingOffsetM * lScalingPivotM * lScalingM * lScalingPivotM.Inverse();
FbxVector4 lLocalTWithAllPivotAndOffsetInfo = lTransform.GetT();
FbxVector4 lGlobalTranslation = lParentGX.MultT(lLocalTWithAllPivotAndOffsetInfo);
lGlobalT.SetT(lGlobalTranslation);
lTransform = lGlobalT * lGlobalRS;
return lTransform;
}