#include <fbxsdk.h>
#include "../Common/Common.h"
#define SAMPLE_FILENAME "Instances.fbx"
int gNbCubes = 10;
bool CreateScene(KFbxSdkManager* pSdkManager, KFbxScene* pScene);
KFbxNode* CreateCube(KFbxScene* pScene, const char* pName);
KFbxNode* CreateCubeInstance(KFbxScene* pScene, const char* pName, KFbxMesh* pFirstCube);
KFbxAnimCurve* CreateAnimCurve(KFbxScene* pScene);
void AnimateCube(KFbxNode* pCube, KFbxAnimLayer* pAnimLayer, KFbxAnimCurve* pAnimCurve, int pRotAxis);
int main(int argc, char** argv)
{
KFbxSdkManager* lSdkManager = NULL;
KFbxScene* lScene = NULL;
bool lResult;
InitializeSdkObjects(lSdkManager, lScene);
if (argc > 2)
{
gNbCubes = atoi(argv[2]);
if (gNbCubes < 1)
{
gNbCubes = 1;
}
}
lResult = CreateScene(lSdkManager, lScene);
if(lResult == false)
{
printf("\n\nAn error occurred while creating the scene...\n");
DestroySdkObjects(lSdkManager);
return 0;
}
if(argc > 1)
{
lResult = SaveScene(lSdkManager, lScene, argv[1]);
}
else
{
lResult = SaveScene(lSdkManager, lScene, SAMPLE_FILENAME);
}
if(lResult == false)
{
printf("\n\nAn error occurred while saving the scene...\n");
DestroySdkObjects(lSdkManager);
return 0;
}
DestroySdkObjects(lSdkManager);
return 0;
}
bool CreateScene(KFbxSdkManager *pSdkManager, KFbxScene* pScene)
{
double lX = 0.0;
double lY = 20.0;
double lZ = 0.0;
KFbxMesh* lCubeMesh = NULL;
KFbxNode* lCubeNode = NULL;
KFbxAnimStack* lAnimStack = KFbxAnimStack::Create(pScene, "Cube Animation Stack");
KFbxAnimLayer* lAnimLayer = KFbxAnimLayer::Create(pScene, "Base Layer");
lAnimStack->AddMember(lAnimLayer);
for (int i = 0; i < gNbCubes; i++)
{
KString lCubeName = "Cube ";
lCubeName += (i+1);
if (i == 0)
{
lCubeNode = CreateCube(pScene, lCubeName.Buffer());
lCubeMesh = lCubeNode->GetMesh();
}
else
{
lCubeNode = CreateCubeInstance(pScene, lCubeName.Buffer(), lCubeMesh);
}
lCubeNode->LclTranslation.Set(KFbxVector4(lX, lY, lZ));
KFbxAnimCurve* lAnimCurve = CreateAnimCurve(pScene);
AnimateCube(lCubeNode, lAnimLayer, lAnimCurve, i%3);
if (lX >= 0)
{
lX += 50;
}
else
{
lX -= 50;
}
lX *= -1.0;
lY += 30.0;
}
return true;
}
void AnimateCube(KFbxNode* pCube, KFbxAnimLayer* pAnimLayer, KFbxAnimCurve* pAnimCurve, int pRotAxis)
{
KFbxAnimCurveNode *lCurveNode = pCube->LclRotation.GetCurveNode(pAnimLayer, true);
if(pRotAxis == 0)
{
lCurveNode->ConnectToChannel(pAnimCurve, KFCURVENODE_R_X);
}
else if(pRotAxis == 1)
{
lCurveNode->ConnectToChannel(pAnimCurve, KFCURVENODE_R_Y);
}
else if(pRotAxis == 2)
{
lCurveNode->ConnectToChannel(pAnimCurve, KFCURVENODE_R_Z);
}
}
KFbxNode* CreateCube(KFbxScene* pScene, const 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;
KFbxLayer* lLayer = lMesh->GetLayer(0);
if (lLayer == NULL)
{
lMesh->CreateLayer();
lLayer = lMesh->GetLayer(0);
}
KFbxLayerElementNormal* lLayerElementNormal= KFbxLayerElementNormal::Create(lMesh, "");
lLayerElementNormal->SetMappingMode(KFbxLayerElement::eBY_CONTROL_POINT);
lLayerElementNormal->SetReferenceMode(KFbxLayerElement::eDIRECT);
lLayerElementNormal->GetDirectArray().Add(lNormalZPos);
lLayerElementNormal->GetDirectArray().Add(lNormalZPos);
lLayerElementNormal->GetDirectArray().Add(lNormalZPos);
lLayerElementNormal->GetDirectArray().Add(lNormalZPos);
lLayerElementNormal->GetDirectArray().Add(lNormalXPos);
lLayerElementNormal->GetDirectArray().Add(lNormalXPos);
lLayerElementNormal->GetDirectArray().Add(lNormalXPos);
lLayerElementNormal->GetDirectArray().Add(lNormalXPos);
lLayerElementNormal->GetDirectArray().Add(lNormalZNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalZNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalZNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalZNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalXNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalXNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalXNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalXNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalYPos);
lLayerElementNormal->GetDirectArray().Add(lNormalYPos);
lLayerElementNormal->GetDirectArray().Add(lNormalYPos);
lLayerElementNormal->GetDirectArray().Add(lNormalYPos);
lLayerElementNormal->GetDirectArray().Add(lNormalYNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalYNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalYNeg);
lLayerElementNormal->GetDirectArray().Add(lNormalYNeg);
lLayer->SetNormals(lLayerElementNormal);
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 };
KFbxLayerElementUV* lUVDiffuseLayer = KFbxLayerElementUV::Create(lMesh, "DiffuseUV");
lUVDiffuseLayer->SetMappingMode(KFbxLayerElement::eBY_POLYGON_VERTEX);
lUVDiffuseLayer->SetReferenceMode(KFbxLayerElement::eINDEX_TO_DIRECT);
lLayer->SetUVs(lUVDiffuseLayer, KFbxLayerElement::eDIFFUSE_TEXTURES);
KFbxVector2 lVectors0(0, 0);
KFbxVector2 lVectors1(1, 0);
KFbxVector2 lVectors2(1, 1);
KFbxVector2 lVectors3(0, 1);
lUVDiffuseLayer->GetDirectArray().Add(lVectors0);
lUVDiffuseLayer->GetDirectArray().Add(lVectors1);
lUVDiffuseLayer->GetDirectArray().Add(lVectors2);
lUVDiffuseLayer->GetDirectArray().Add(lVectors3);
lUVDiffuseLayer->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]);
lUVDiffuseLayer->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));
pScene->GetRootNode()->AddChild(lNode);
return lNode;
}
KFbxNode* CreateCubeInstance(KFbxScene* pScene, const char* pName, KFbxMesh* pFirstCube)
{
KFbxNode* lNode = KFbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(pFirstCube);
lNode->LclScaling.Set(KFbxVector4(0.3, 0.3, 0.3));
pScene->GetRootNode()->AddChild(lNode);
return lNode;
}
KFbxAnimCurve* CreateAnimCurve(KFbxScene* pScene)
{
KTime lTime;
int lKeyIndex = 0;
KFbxAnimCurve* lAnimCurve = KFbxAnimCurve::Create(pScene, "Cube Animation");
lAnimCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lAnimCurve->KeyAdd(lTime);
lAnimCurve->KeySet(lKeyIndex, lTime, 0.0, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lTime.SetSecondDouble(20.0);
lKeyIndex = lAnimCurve->KeyAdd(lTime);
lAnimCurve->KeySet(lKeyIndex, lTime, -3600, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lAnimCurve->KeyModifyEnd();
return lAnimCurve;
}