#include "SDK_Utility.h"
KFbxSdkManager* gSdkManager = NULL;
KFbxScene* gScene = NULL;
KFbxFileTexture* gTexture = NULL;
KFbxSurfacePhong* gMaterial = NULL;
int gCubeNumber = 1;
int gCubeRotationAxis = 1;
double gCubeXPos = 0.0;
double gCubeYPos = 20.0;
double gCubeZPos = 0.0;
KFbxAnimLayer* gAnimLayer = NULL;
KString gAppPath;
#ifdef IOS_REF
#undef IOS_REF
#define IOS_REF (*(pSdkManager->GetIOSettings()))
#endif
bool InitializeSdkObjects(
KFbxSdkManager*& pSdkManager,
KFbxScene*& pScene
)
{
pSdkManager = KFbxSdkManager::Create();
if (!pSdkManager)
{
return false;
}
KFbxIOSettings * ios = KFbxIOSettings::Create(pSdkManager, IOSROOT );
pSdkManager->SetIOSettings(ios);
pScene = KFbxScene::Create(pSdkManager,"");
if(pScene == NULL) return false;
return true;
}
void DestroySdkObjects(
KFbxSdkManager* pSdkManager
)
{
if (pSdkManager) pSdkManager->Destroy();
}
bool CreateScene()
{
if(InitializeSdkObjects(gSdkManager, gScene) == false)
{
return false;
}
KFbxAnimStack* lAnimStack = KFbxAnimStack::Create(gScene, "Animation stack camera animation");
gAnimLayer = KFbxAnimLayer::Create(gScene, "Base Layer");
lAnimStack->AddMember(gAnimLayer);
KFbxNode* lMarker = CreateMarker(gScene, "Marker");
KFbxNode* lCamera = CreateCamera(gScene, "Camera");
CreateTexture(gScene);
CreateMaterial(gScene);
SetCameraPointOfInterest(lCamera, lMarker);
SetMarkerDefaultPosition(lMarker);
SetCameraDefaultPosition(lCamera);
AnimateCamera(lCamera, gAnimLayer);
KFbxNode* lRootNode = gScene->GetRootNode();
lRootNode->AddChild(lMarker);
lRootNode->AddChild(lCamera);
gScene->GetGlobalSettings().SetDefaultCamera((char *)lCamera->GetName());
return true;
}
void CreateCube(bool pWithMaterial, bool pWithTexture, bool pAnimate)
{
KString lCubeName = "Cube number ";
lCubeName += KString(gCubeNumber);
CreateCubeDetailed( lCubeName.Buffer(),
gCubeXPos,
gCubeYPos,
gCubeZPos,
gCubeRotationAxis,
pWithMaterial,
pWithTexture,
pAnimate
);
gCubeNumber++;
if(gCubeXPos >= 0.0)
{
gCubeXPos += 50.0;
gCubeXPos *= -1.0;
gCubeRotationAxis++;
}
else
{
gCubeXPos *= -1.0;
}
gCubeYPos += 30.0;
if(gCubeRotationAxis > 2) gCubeRotationAxis = 0;
}
void RemoveCubes()
{
if(gSdkManager == NULL) return;
int nc = gScene->GetNodeCount();
if(nc <= 3) return;
for(int i=nc-1; i >= 3; i--)
{
KFbxNode *node = gScene->GetNode(i);
gScene->RemoveNode(node);
KFbxAnimCurveNode* lCurveNode = node->LclRotation.GetCurveNode(gAnimLayer);
if(lCurveNode != NULL)
{
lCurveNode->Destroy(true, true);
}
node->Destroy(true, true);
}
SetInitialCubeData();
}
void CreateCubeDetailed( char* pCubeName,
double pX,
double pY,
double pZ,
int pRotateAxe,
bool pWithMaterial,
bool pWithTexture,
bool pAnimate
)
{
KFbxNode* lCube = CreateCubeMesh(gScene, pCubeName);
lCube->LclTranslation.Set(KFbxVector4(pX, pY, pZ));
if(pAnimate)
{
AnimateCube(lCube, gAnimLayer, pRotateAxe);
}
if(pWithTexture)
{
if (!pWithMaterial)
AddMaterials(lCube->GetMesh());
}
if(pWithMaterial)
{
AddMaterials(lCube->GetMesh());
}
gScene->GetRootNode()->AddChild(lCube);
}
bool Export(
const char* pFilename,
int pFileFormat
)
{
return SaveScene(gSdkManager, gScene, pFilename, pFileFormat, true);
}
bool SaveScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pFilename, int pFileFormat, bool pEmbedMedia)
{
if(pSdkManager == NULL) return false;
if(pScene == NULL) return false;
if(pFilename == NULL) return false;
bool lStatus = true;
KFbxExporter* lExporter = KFbxExporter::Create(pSdkManager, "");
if( pFileFormat < 0 || pFileFormat >= pSdkManager->GetIOPluginRegistry()->GetWriterFormatCount() )
{
pFileFormat = pSdkManager->GetIOPluginRegistry()->GetNativeWriterFormat();
if (!pEmbedMedia)
{
int lFormatIndex, lFormatCount = pSdkManager->GetIOPluginRegistry()->GetWriterFormatCount();
for (lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++)
{
if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex))
{
KString lDesc =pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex);
char *lASCII = "ascii";
if (lDesc.Find(lASCII)>=0)
{
pFileFormat = lFormatIndex;
break;
}
}
}
}
}
if(lExporter->Initialize(pFilename, pFileFormat, pSdkManager->GetIOSettings() ) == false)
{
return false;
}
IOS_REF.SetBoolProp(EXP_FBX_MATERIAL, true);
IOS_REF.SetBoolProp(EXP_FBX_TEXTURE, true);
IOS_REF.SetBoolProp(EXP_FBX_EMBEDDED, pEmbedMedia);
IOS_REF.SetBoolProp(EXP_FBX_SHAPE, true);
IOS_REF.SetBoolProp(EXP_FBX_GOBO, true);
IOS_REF.SetBoolProp(EXP_FBX_ANIMATION, true);
IOS_REF.SetBoolProp(EXP_FBX_GLOBAL_SETTINGS, true);
lStatus = lExporter->Export(pScene);
lExporter->Destroy();
return lStatus;
}
const char *GetWriterSFNFilters()
{
int nbWriters = gSdkManager->GetIOPluginRegistry()->GetWriterFormatCount();
KString s;
int i=0;
for(i=0; i < nbWriters; i++)
{
s += gSdkManager->GetIOPluginRegistry()->
GetWriterFormatDescription(i);
s += "|*.";
s += gSdkManager->GetIOPluginRegistry()->
GetWriterFormatExtension(i);
s += "|";
}
int nbChar = int(strlen(s.Buffer())) + 1;
char *filter = new char[ nbChar ];
memset(filter, 0, nbChar);
strcpy(filter, s.Buffer());
for(i=0; i < int(strlen(s.Buffer())); i++)
{
if(filter[i] == '|')
{
filter[i] = 0;
}
}
return filter;
}
const char *GetFileFormatExt(
const int pWriteFileFormat
)
{
char *buf = new char[10];
memset(buf, 0, 10);
buf[0] = '.';
const char * ext = gSdkManager->GetIOPluginRegistry()->
GetWriterFormatExtension(pWriteFileFormat);
strcat(buf, ext);
return buf;
}
const KFbxNode* GetRootNode()
{
return gScene->GetRootNode();
}
const char * GetRootNodeName()
{
return GetRootNode()->GetName();
}
KString GetNodeNameAndAttributeTypeName(const KFbxNode* pNode)
{
KString s = pNode->GetName();
KFbxNodeAttribute::EAttributeType lAttributeType;
if(pNode->GetNodeAttribute() == NULL)
{
s += " (No node attribute type)";
}
else
{
lAttributeType = (pNode->GetNodeAttribute()->GetAttributeType());
switch (lAttributeType)
{
case KFbxNodeAttribute::eMARKER: s += " (Marker)"; break;
case KFbxNodeAttribute::eSKELETON: s += " (Skeleton)"; break;
case KFbxNodeAttribute::eMESH: s += " (Mesh)"; break;
case KFbxNodeAttribute::eCAMERA: s += " (Camera)"; break;
case KFbxNodeAttribute::eLIGHT: s += " (Light)"; break;
case KFbxNodeAttribute::eBOUNDARY: s += " (Boundary)"; break;
case KFbxNodeAttribute::eOPTICAL_MARKER: s += " (Optical marker)"; break;
case KFbxNodeAttribute::eOPTICAL_REFERENCE: s += " (Optical reference)"; break;
case KFbxNodeAttribute::eCAMERA_SWITCHER: s += " (Camera switcher)"; break;
case KFbxNodeAttribute::eNULL: s += " (Null)"; break;
case KFbxNodeAttribute::ePATCH: s += " (Patch)"; break;
case KFbxNodeAttribute::eNURB: s += " (NURB)"; break;
case KFbxNodeAttribute::eNURBS_SURFACE: s += " (Nurbs surface)"; break;
case KFbxNodeAttribute::eNURBS_CURVE: s += " (NURBS curve)"; break;
case KFbxNodeAttribute::eTRIM_NURBS_SURFACE: s += " (Trim nurbs surface)"; break;
case KFbxNodeAttribute::eUNIDENTIFIED: s += " (Unidentified)"; break;
}
}
return s;
}
KString GetDefaultTranslationInfo(
const KFbxNode* pNode
)
{
KFbxVector4 v4;
v4 = ((KFbxNode*)pNode)->LclTranslation.Get();
return KString("Translation (X,Y,Z): ") + KString(v4.GetAt(0)) + ", " + KString(v4.GetAt(1)) + ", " + KString(v4.GetAt(2));
}
KString GetNodeInfo(
const KFbxNode* pNode
)
{
KString s;
int lMaterialCount = pNode->GetMaterialCount();
KFbxSurfacePhong* lMaterial = NULL;
bool lTextureExist = false;
if( lMaterialCount > 0)
{
s+= "[Material: Yes] ";
for( int i = 0; i < lMaterialCount; ++i)
{
lMaterial = (KFbxSurfacePhong*)pNode->GetMaterial( i);
if( lMaterial->Diffuse.GetSrcObjectCount( KFbxFileTexture::ClassId) > 0)
{
lTextureExist = true;
break;
}
}
}
else
{
s+= "[Material: No] ";
s+= "[Texture: No] ";
}
if( lTextureExist) s+= "[Texture: Yes] ";
else s+= "[Texture: No] ";
bool anim = false;
KFbxAnimCurveNode* lCurveNode = NULL;
lCurveNode =((KFbxNode* )pNode)->LclRotation.GetCurveNode(gAnimLayer);
if(lCurveNode != NULL) anim = true;
lCurveNode = ((KFbxNode* )pNode)->LclTranslation.GetCurveNode(gAnimLayer);
if(lCurveNode != NULL) anim = true;
if(anim == true)
{
s+= "[Animation: Yes] ";
}
else
{
s+= "[Animation: No] ";
}
return s;
}
KFbxNode* CreateMarker(KFbxScene* pScene, char* pName)
{
KFbxMarker* lMarker = KFbxMarker::Create(pScene,pName);
KFbxNode* lNode = KFbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lMarker);
return lNode;
}
KFbxNode* CreateCamera(KFbxScene* pScene, char* pName)
{
KFbxCamera* lCamera = KFbxCamera::Create(pScene,pName);
lCamera->SetFormat(KFbxCamera::eNTSC);
KFbxNode* lNode = KFbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lCamera);
return lNode;
}
void SetCameraPointOfInterest(KFbxNode* pCamera, KFbxNode* pPointOfInterest)
{
pCamera->SetTarget(pPointOfInterest);
}
void SetMarkerDefaultPosition(KFbxNode* pMarker)
{
pMarker->LclTranslation.Set(KFbxVector4(0.0, 40.0, 0.0));
pMarker->LclRotation.Set(KFbxVector4(0.0, 0.0, 0.0));
pMarker->LclScaling.Set(KFbxVector4(1.0, 1.0, 1.0));
}
void SetCameraDefaultPosition(KFbxNode* pCamera)
{
KFbxVector4 lCameraLocation(0.0, 200.0, -100.0);
pCamera->LclTranslation.Set(lCameraLocation);
}
void AnimateCamera(KFbxNode* pCamera, KFbxAnimLayer* pAnimLayer)
{
KFbxAnimCurve* lCurve = NULL;
KTime lTime;
int lKeyIndex = 0;
pCamera->LclTranslation.GetCurveNode(pAnimLayer, true);
lCurve = pCamera->LclTranslation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_T_X, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 0.0, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lTime.SetSecondDouble(20.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 500.0, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lCurve->KeyModifyEnd();
}
lCurve = pCamera->LclTranslation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_T_Y, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 0.0, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lTime.SetSecondDouble(20.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 800.0, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lCurve->KeyModifyEnd();
}
}
void AnimateCube(KFbxNode* pCube, KFbxAnimLayer* pAnimLayer, int pRotAxe)
{
KFbxAnimCurve* lCurve = NULL;
KTime lTime;
int lKeyIndex = 0;
pCube->LclRotation.GetCurveNode(pAnimLayer, true);
if(pRotAxe == 0) lCurve = pCube->LclRotation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_R_X, true);
else if(pRotAxe == 1) lCurve = pCube->LclRotation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_R_Y, true);
else if(pRotAxe == 2) lCurve = pCube->LclRotation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_R_Z, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 0.0, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lTime.SetSecondDouble(20.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, -3500, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lCurve->KeyModifyEnd();
}
}
KFbxNode* CreateCubeMesh(KFbxScene* pScene, char* pName)
{
int i, j;
KFbxMesh* lMesh = KFbxMesh::Create(pScene,pName);
KFbxVector4 lControlPoint0(-50, 0, 50);
KFbxVector4 lControlPoint1(50, 0, 50);
KFbxVector4 lControlPoint2(50, 100, 50);
KFbxVector4 lControlPoint3(-50, 100, 50);
KFbxVector4 lControlPoint4(-50, 0, -50);
KFbxVector4 lControlPoint5(50, 0, -50);
KFbxVector4 lControlPoint6(50, 100, -50);
KFbxVector4 lControlPoint7(-50, 100, -50);
KFbxVector4 lNormalXPos(1, 0, 0);
KFbxVector4 lNormalXNeg(-1, 0, 0);
KFbxVector4 lNormalYPos(0, 1, 0);
KFbxVector4 lNormalYNeg(0, -1, 0);
KFbxVector4 lNormalZPos(0, 0, 1);
KFbxVector4 lNormalZNeg(0, 0, -1);
lMesh->InitControlPoints(24);
KFbxVector4* lControlPoints = lMesh->GetControlPoints();
lControlPoints[0] = lControlPoint0;
lControlPoints[1] = lControlPoint1;
lControlPoints[2] = lControlPoint2;
lControlPoints[3] = lControlPoint3;
lControlPoints[4] = lControlPoint1;
lControlPoints[5] = lControlPoint5;
lControlPoints[6] = lControlPoint6;
lControlPoints[7] = lControlPoint2;
lControlPoints[8] = lControlPoint5;
lControlPoints[9] = lControlPoint4;
lControlPoints[10] = lControlPoint7;
lControlPoints[11] = lControlPoint6;
lControlPoints[12] = lControlPoint4;
lControlPoints[13] = lControlPoint0;
lControlPoints[14] = lControlPoint3;
lControlPoints[15] = lControlPoint7;
lControlPoints[16] = lControlPoint3;
lControlPoints[17] = lControlPoint2;
lControlPoints[18] = lControlPoint6;
lControlPoints[19] = lControlPoint7;
lControlPoints[20] = lControlPoint1;
lControlPoints[21] = lControlPoint0;
lControlPoints[22] = lControlPoint4;
lControlPoints[23] = lControlPoint5;
KFbxGeometryElementNormal* lGeometryElementNormal= lMesh->CreateElementNormal();
lGeometryElementNormal->SetMappingMode(KFbxGeometryElement::eBY_CONTROL_POINT);
lGeometryElementNormal->SetReferenceMode(KFbxGeometryElement::eDIRECT);
lGeometryElementNormal->GetDirectArray().Add(lNormalZPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalZPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalZPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalZPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalXPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalXPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalXPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalXPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalZNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalZNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalZNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalZNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalXNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalXNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalXNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalXNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalYPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalYPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalYPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalYPos);
lGeometryElementNormal->GetDirectArray().Add(lNormalYNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalYNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalYNeg);
lGeometryElementNormal->GetDirectArray().Add(lNormalYNeg);
int lPolygonVertices[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
KFbxGeometryElementUV* lUVDiffuseElement = lMesh->CreateElementUV( "DiffuseUV");
K_ASSERT( lUVDiffuseElement != NULL);
lUVDiffuseElement->SetMappingMode(KFbxGeometryElement::eBY_POLYGON_VERTEX);
lUVDiffuseElement->SetReferenceMode(KFbxGeometryElement::eINDEX_TO_DIRECT);
KFbxVector2 lVectors0(0, 0);
KFbxVector2 lVectors1(1, 0);
KFbxVector2 lVectors2(1, 1);
KFbxVector2 lVectors3(0, 1);
lUVDiffuseElement->GetDirectArray().Add(lVectors0);
lUVDiffuseElement->GetDirectArray().Add(lVectors1);
lUVDiffuseElement->GetDirectArray().Add(lVectors2);
lUVDiffuseElement->GetDirectArray().Add(lVectors3);
lUVDiffuseElement->GetIndexArray().SetCount(24);
for(i = 0; i < 6; i++)
{
lMesh->BeginPolygon(-1, -1, -1, false);
for(j = 0; j < 4; j++)
{
lMesh->AddPolygon(lPolygonVertices[i*4 + j]);
lUVDiffuseElement->GetIndexArray().SetAt(i*4+j, j);
}
lMesh->EndPolygon ();
}
KFbxNode* lNode = KFbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lMesh);
lNode->SetShadingMode(KFbxNode::eTEXTURE_SHADING);
lNode->LclScaling.Set(KFbxVector4(0.3, 0.3, 0.3));
return lNode;
}
void CreateTexture(KFbxScene* pScene)
{
gTexture = KFbxFileTexture::Create(pScene,"Diffuse Texture");
KString lTexPath = gAppPath + "\\Crate.jpg";
gTexture->SetFileName(lTexPath.Buffer());
gTexture->SetTextureUse(KFbxTexture::eSTANDARD);
gTexture->SetMappingType(KFbxTexture::eUV);
gTexture->SetMaterialUse(KFbxFileTexture::eMODEL_MATERIAL);
gTexture->SetSwapUV(false);
gTexture->SetTranslation(0.0, 0.0);
gTexture->SetScale(1.0, 1.0);
gTexture->SetRotation(0.0, 0.0);
}
void CreateMaterial(KFbxScene* pScene)
{
KString lMaterialName = "material";
KString lShadingName = "Phong";
fbxDouble3 lBlack(0.0, 0.0, 0.0);
fbxDouble3 lRed(1.0, 0.0, 0.0);
fbxDouble3 lDiffuseColor(0.75, 0.75, 0.0);
gMaterial = KFbxSurfacePhong::Create(pScene, lMaterialName.Buffer());
gMaterial->Emissive .Set(lBlack);
gMaterial->Ambient .Set(lRed);
gMaterial->Diffuse .Set(lDiffuseColor);
gMaterial->TransparencyFactor .Set(40.5);
gMaterial->ShadingModel .Set(lShadingName);
gMaterial->Shininess .Set(0.5);
if (gTexture)
gMaterial->Diffuse.ConnectSrcObject(gTexture);
}
void AddMaterials(KFbxMesh* pMesh)
{
KFbxGeometryElementMaterial* lMaterialElement = pMesh->CreateElementMaterial();
lMaterialElement->SetMappingMode(KFbxGeometryElement::eBY_POLYGON);
lMaterialElement->SetReferenceMode(KFbxGeometryElement::eINDEX_TO_DIRECT);
KFbxNode* lNode = pMesh->GetNode();
if(lNode == NULL)
return;
lNode->AddMaterial(gMaterial);
lMaterialElement->GetIndexArray().SetCount(6);
for(int i=0; i<6; ++i)
lMaterialElement->GetIndexArray().SetAt(i,0);
}
void SetInitialCubeData()
{
gCubeNumber = 1;
gCubeRotationAxis = 1;
gCubeXPos = 0.0;
gCubeYPos = 20.0;
gCubeZPos = 0.0;
}