#include <fbxsdk.h>
#ifdef FBXSDK_ENV_WIN
#include <malloc.h>
#endif
#include "../MyOwnWriterReader/MyOwnWriterReader.h"
#include "../Common/Common.h"
#define SAMPLE_FILENAME "ExportScene05.fbx"
bool CreateScene(FbxScene* pScene);
void SetGlobalDefaultPosition(FbxNode* pNode, FbxAMatrix pGlobalPosition);
FbxAMatrix GetGlobalDefaultPosition(FbxNode* pNode);
int main(int argc, char** argv)
{
FbxManager* lSdkManager = NULL;
FbxScene* lScene = NULL;
bool lResult;
InitializeSdkObjects(lSdkManager, lScene);
lResult = CreateScene(lScene);
if(lResult == false)
{
FBXSDK_printf("\n\nAn error occurred while creating the scene...\n");
DestroySdkObjects(lSdkManager, lResult);
return 1;
}
const char* lSampleFileName = NULL;
for( int i = 1; i < argc; ++i )
{
if( FBXSDK_stricmp(argv[i], "-test") == 0 ) continue;
else if( !lSampleFileName ) lSampleFileName = argv[i];
}
if( !lSampleFileName ) lSampleFileName = SAMPLE_FILENAME;
lResult = SaveScene(lSdkManager, lScene, lSampleFileName);
if(lResult == false)
{
FBXSDK_printf("\n\nAn error occurred while saving the scene...\n");
DestroySdkObjects(lSdkManager, lResult);
return 1;
}
FBXSDK_printf("Writing to file with custom writer\n");
int lRegisteredCount;
int lPluginId;
lSdkManager->GetIOPluginRegistry()->RegisterWriter(CreateMyOwnWriter, GetMyOwnWriterInfo,
lPluginId, lRegisteredCount, FillOwnWriterIOSettings);
const char* lFileName = "CustomWriter.ABC";
FbxExporter* lExporter = FbxExporter::Create(lSdkManager, "");
int lFileFormat = lSdkManager->GetIOPluginRegistry()->FindWriterIDByExtension("ABC");
if(lExporter->Initialize(lFileName, lFileFormat, lSdkManager->GetIOSettings()) == false)
{
FBXSDK_printf("Call to FbxExporter::Initialize() failed.\n");
FBXSDK_printf("Error returned: %s\n\n", lExporter->GetStatus().GetErrorString());
DestroySdkObjects(lSdkManager, false);
return 1;
}
lResult = lExporter->Export(lScene);
if(lResult == false)
{
FBXSDK_printf("Error in write of our custom writer\n");
DestroySdkObjects(lSdkManager, lResult);
return 1;
}
lSdkManager->GetIOPluginRegistry()->RegisterReader(CreateMyOwnReader, GetMyOwnReaderInfo,
lPluginId, lRegisteredCount, FillOwnReaderIOSettings);
FbxImporter* lImporter = FbxImporter::Create(lSdkManager,"");
lResult = lImporter->Initialize(lFileName, -1, lSdkManager->GetIOSettings() );
lResult = lImporter->Import(lScene);
if(lResult == false)
{
FBXSDK_printf("There was a problem in the read of our custom reader\n");
DestroySdkObjects(lSdkManager, lResult);
return 1;
}
DestroySdkObjects(lSdkManager, lResult);
return 0;
}
bool CreateScene(FbxScene* pScene)
{
FbxVector4 lT, lR, lS;
FbxAMatrix lGM;
FbxNode* pNodeA = FbxNode::Create(pScene,"A");
FbxNode* pNodeB = FbxNode::Create(pScene,"B");
FbxNode* pNodeC = FbxNode::Create(pScene,"C");
FbxNode* pNodeD = FbxNode::Create(pScene,"D");
FbxSkeleton* lSkeletonA = FbxSkeleton::Create(pScene,"");
lSkeletonA->SetSkeletonType(FbxSkeleton::eRoot);
pNodeA->SetNodeAttribute(lSkeletonA);
FbxSkeleton* lSkeletonB = FbxSkeleton::Create(pScene,"");
lSkeletonB->SetSkeletonType(FbxSkeleton::eLimbNode);
pNodeB->SetNodeAttribute(lSkeletonB);
FbxSkeleton* lSkeletonC = FbxSkeleton::Create(pScene,"");
lSkeletonC->SetSkeletonType(FbxSkeleton::eLimbNode);
pNodeC->SetNodeAttribute(lSkeletonC);
FbxSkeleton* lSkeletonD = FbxSkeleton::Create(pScene,"");
lSkeletonD->SetSkeletonType(FbxSkeleton::eLimbNode);
pNodeD->SetNodeAttribute(lSkeletonD);
pNodeA->TranslationActive = true;
pNodeA->TranslationMinX = true;
pNodeA->TranslationMinY = true;
pNodeA->TranslationMinZ = true;
pNodeA->TranslationMin = FbxVector4(0.1, 0.2, 0.3);
pNodeA->TranslationMaxX = true;
pNodeA->TranslationMaxY = true;
pNodeA->TranslationMaxZ = true;
pNodeA->TranslationMax = FbxVector4(5.0, 1.0, 0.0);
pNodeA->UpdatePivotsAndLimitsFromProperties();
pNodeB->RotationActive = true;
pNodeB->RotationMaxX = true;
pNodeB->RotationMaxY = false;
pNodeB->RotationMaxZ = false;
pNodeB->RotationMax = FbxVector4(33.3, 0.0, 0.0);
pNodeB->UpdatePivotsAndLimitsFromProperties();
pNodeB->SetPivotState(FbxNode::eSourcePivot, FbxNode::ePivotActive);
pNodeB->SetRotationOrder(FbxNode::eSourcePivot, eSphericXYZ);
pNodeB->SetUseRotationSpaceForLimitOnly(FbxNode::eSourcePivot, false);
pNodeB->SetQuaternionInterpolation(FbxNode::eSourcePivot, eQuatInterpClassic);
pNodeB->SetRotationPivot(FbxNode::eSourcePivot, FbxVector4(11.1, 22.2, 33.3));
pNodeB->SetPreRotation(FbxNode::eSourcePivot, FbxVector4(15.0, 30.0, 45.0));
pNodeB->SetPostRotation(FbxNode::eSourcePivot, FbxVector4(-45.0, -30.0, -15.0));
pScene->GetRootNode()->AddChild(pNodeA);
pNodeA->AddChild(pNodeB);
pNodeB->AddChild(pNodeC);
pNodeC->AddChild(pNodeD);
lT.Set(0.0, 0.0, 0.0); lGM.SetT(lT);
lR.Set(0.0, 0.0, 45.0); lGM.SetR(lR);
SetGlobalDefaultPosition(pNodeA, lGM);
lT.Set(30.0, 20.0, 0.0); lGM.SetT(lT);
lR.Set(0.0, 0.0, 0.0); lGM.SetR(lR);
SetGlobalDefaultPosition(pNodeB, lGM);
lT.Set(55.0, 20.0, 0.0); lGM.SetT(lT);
lR.Set(0.0, 0.0, -40.0); lGM.SetR(lR);
SetGlobalDefaultPosition(pNodeC, lGM);
lT.Set(70.0, 10.0, 0.0); lGM.SetT(lT);
lR.Set(0.0, 0.0, 0.0); lGM.SetR(lR);
SetGlobalDefaultPosition(pNodeD, lGM);
FbxObjectMetaData* pFamilyMetaData = FbxObjectMetaData::Create(pScene, "Family");
FbxProperty::Create(pFamilyMetaData, FbxStringDT, "Level", "Level").Set(FbxString("Family"));
FbxProperty::Create(pFamilyMetaData, FbxStringDT, "Type", "Type").Set(FbxString("Wall"));
FbxProperty::Create(pFamilyMetaData, FbxFloatDT, "Width", "Width").Set(10.0f);
FbxProperty::Create(pFamilyMetaData, FbxDoubleDT, "Weight", "Weight").Set(25.0);
FbxProperty::Create(pFamilyMetaData, FbxDoubleDT, "Cost", "Cost").Set(1.25);
FbxObjectMetaData* pTypeMetaData = FbxCast<FbxObjectMetaData>(pFamilyMetaData->Clone(FbxObject::eReferenceClone, pScene));
pTypeMetaData->SetName("Type");
pTypeMetaData->FindProperty("Cost").Set(2500.0);
pTypeMetaData->FindProperty("Level").Set(FbxString("Type"));
FbxObjectMetaData* pInstanceMetaData = FbxCast<FbxObjectMetaData>(pTypeMetaData->Clone(FbxObject::eReferenceClone, pScene));
pInstanceMetaData->SetName("Instance");
FbxProperty::Create(pInstanceMetaData, FbxStringDT, "Sku", "Sku#").Set(FbxString("143914-10"));
pInstanceMetaData->FindProperty("Width").Set(1100.50f);
pInstanceMetaData->FindProperty("Type").Set(FbxString("Super Heavy Duty Wall"));
pInstanceMetaData->FindProperty("Level").Set(FbxString("Instance"));
pNodeA->ConnectSrcObject(pInstanceMetaData);
pNodeC->ConnectSrcObject(pInstanceMetaData);
pNodeD->ConnectSrcObject(pTypeMetaData);
return true;
}
void SetGlobalDefaultPosition(FbxNode* pNode, FbxAMatrix pGlobalPosition)
{
FbxAMatrix lLocalPosition;
FbxAMatrix lParentGlobalPosition;
if (pNode->GetParent())
{
lParentGlobalPosition = GetGlobalDefaultPosition(pNode->GetParent());
lLocalPosition = lParentGlobalPosition.Inverse() * pGlobalPosition;
}
else
{
lLocalPosition = pGlobalPosition;
}
pNode->LclTranslation.Set(lLocalPosition.GetT());
pNode->LclRotation.Set(lLocalPosition.GetR());
pNode->LclScaling.Set(lLocalPosition.GetS());
}
FbxAMatrix GetGlobalDefaultPosition(FbxNode* pNode)
{
FbxAMatrix lLocalPosition;
FbxAMatrix lGlobalPosition;
FbxAMatrix lParentGlobalPosition;
lLocalPosition.SetT(pNode->LclTranslation.Get());
lLocalPosition.SetR(pNode->LclRotation.Get());
lLocalPosition.SetS(pNode->LclScaling.Get());
if (pNode->GetParent())
{
lParentGlobalPosition = GetGlobalDefaultPosition(pNode->GetParent());
lGlobalPosition = lParentGlobalPosition * lLocalPosition;
}
else
{
lGlobalPosition = lLocalPosition;
}
return lGlobalPosition;
}