#include <math.h>
#include <fbxsdk.h>
#include "../Common/Common.h"
#define SAMPLE_FILENAME "ExportScene04.fbx"
bool CreateScene(KFbxScene* pScene);
KFbxNode* CreateLightGroup(KFbxScene* pScene, char* pName);
KFbxNode* CreateLight(KFbxScene* pScene, char* pName);
KFbxNode* CreateMarker(KFbxScene* pScene, char* pName);
KFbxNode* CreateCamera(KFbxScene* pScene, char* pName);
void SetCameraPointOfInterest(KFbxNode* pCamera, KFbxNode* pPointOfInterest);
void SetLightGroupDefaultPosition(KFbxNode* pLightGroup);
void SetLightDefaultPosition(KFbxNode* pLight, int pIndex);
void SetMarkerDefaultPosition(KFbxNode* pMarker);
void SetCamera1DefaultPosition(KFbxNode* pCamera);
void SetCamera2DefaultPosition(KFbxNode* pCamera);
void AnimateLightGroup(KFbxNode* pLightGroup, KFbxAnimLayer* pAnimLayer);
void AnimateLight(KFbxNode* pLight, int pIndex, KFbxAnimLayer* pAnimLayer);
void AnimateCamera(KFbxNode* pLightGroup, KFbxAnimLayer* pAnimLayer);
int main(int argc, char** argv)
{
KFbxSdkManager* lSdkManager = NULL;
KFbxScene* lScene = NULL;
bool lResult;
InitializeSdkObjects(lSdkManager, lScene);
lResult = CreateScene(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(KFbxScene* pScene)
{
KFbxNode* lLightGroup = CreateLightGroup(pScene, "LightGroup");
KFbxNode* lMarker = CreateMarker(pScene, "Marker");
KFbxNode* lCamera1 = CreateCamera(pScene, "Camera1");
KFbxNode* lCamera2 = CreateCamera(pScene, "Camera2");
pScene->GetGlobalSettings().SetAmbientColor(KFbxColor(1.0, 0.5, 0.2));
SetCameraPointOfInterest(lCamera1, lMarker);
SetCameraPointOfInterest(lCamera2, lCamera1);
SetLightGroupDefaultPosition(lLightGroup);
SetMarkerDefaultPosition(lMarker);
SetCamera1DefaultPosition(lCamera1);
SetCamera2DefaultPosition(lCamera2);
KFbxAnimStack* lAnimStack = KFbxAnimStack::Create(pScene, "Rotating lights");
KFbxAnimLayer* lAnimLayer = KFbxAnimLayer::Create(pScene, "Base Layer");
lAnimStack->AddMember(lAnimLayer);
KFbxNode* lRootNode = pScene->GetRootNode();
lRootNode->AddChild(lLightGroup);
lRootNode->AddChild(lMarker);
lRootNode->AddChild(lCamera1);
lCamera1->AddChild(lCamera2);
pScene->GetGlobalSettings().SetDefaultCamera(PRODUCER_PERSPECTIVE);
AnimateLightGroup(lLightGroup, lAnimLayer);
AnimateCamera(lCamera1, lAnimLayer);
return true;
}
KFbxNode* CreateLightGroup(KFbxScene* pScene, char* pName)
{
KString lLightName;
KFbxNode* lGroup = NULL;
KFbxNode* lNode = NULL;
KFbxLight* lLight = NULL;
int i;
lGroup = KFbxNode::Create(pScene,pName);
for(i = 0; i < 6; i++)
{
lLightName = pName;
lLightName += "-Light";
lLightName += i;
lNode = CreateLight(pScene, lLightName.Buffer());
lGroup->AddChild(lNode);
}
for (i = 0; i < 6; i++)
{
lLight = (KFbxLight*) lGroup->GetChild(i)->GetNodeAttribute();
lLight->FileName.Set("gobo.tif");
lLight->DrawGroundProjection.Set(true);
lLight->DrawVolumetricLight.Set(true);
lLight->DrawFrontFacingVolumetricLight.Set(false);
}
return lGroup;
}
KFbxNode* CreateLight(KFbxScene* pScene, char* pName)
{
KFbxLight* lLight = KFbxLight::Create(pScene,pName);
lLight->LightType.Set(KFbxLight::eSPOT);
lLight->CastLight.Set(true);
KFbxNode* lNode = KFbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lLight);
return lNode;
}
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->SetApertureMode(KFbxCamera::eVERTICAL);
lCamera->SetApertureWidth(0.816);
lCamera->SetApertureHeight(0.612);
lCamera->SetSqueezeRatio(0.5);
KFbxNode* lNode = KFbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lCamera);
return lNode;
}
void SetCameraPointOfInterest(KFbxNode* pCamera, KFbxNode* pPointOfInterest)
{
pCamera->SetTarget(pPointOfInterest);
}
void SetLightGroupDefaultPosition(KFbxNode* pLightGroup)
{
int i;
for (i = 0; i < pLightGroup->GetChildCount(); i++)
{
SetLightDefaultPosition(pLightGroup->GetChild(i), i);
}
pLightGroup->LclTranslation.Set(KFbxVector4(0.0, 15.0, 0.0));
pLightGroup->LclRotation.Set(KFbxVector4(0.0, 0.0, 0.0));
pLightGroup->LclScaling.Set(KFbxVector4(1.0, 1.0, 1.0));
}
void SetLightDefaultPosition(KFbxNode* pLight, int pIndex)
{
pLight->LclTranslation.Set(KFbxVector4((cos((double)pIndex) * 40.0), 0.0, (sin((double)pIndex) * 40.0)));
pLight->LclRotation.Set(KFbxVector4(20.0, (90.0 - pIndex * 60.0), 0.0));
pLight->LclScaling.Set(KFbxVector4(1.0, 1.0, 1.0));
fbxDouble3 lColor[6] =
{
fbxDouble3(1.0, 0.0, 0.0),
fbxDouble3(1.0, 1.0, 0.0),
fbxDouble3(0.0, 1.0, 0.0),
fbxDouble3(0.0, 1.0, 1.0),
fbxDouble3(0.0, 0.0, 1.0),
fbxDouble3(1.0, 0.0, 1.0)
};
KFbxLight* light = pLight->GetLight();
if (light)
{
light->Color.Set(lColor[pIndex % 6]);
light->Intensity.Set(33.0);
light->ConeAngle.Set(90.0);
light->Fog.Set(100.0);
}
}
void SetMarkerDefaultPosition(KFbxNode* pMarker)
{
pMarker->LclTranslation.Set(KFbxVector4(0.0, 0.0, 0.0));
pMarker->LclRotation.Set(KFbxVector4(0.0, 0.0, 0.0));
pMarker->LclScaling.Set(KFbxVector4(1.0, 1.0, 1.0));
}
void SetCamera1DefaultPosition(KFbxNode* pCamera)
{
KFbxVector4 lCameraLocation(0.0, 100.0, -300.0);
KFbxVector4 lDefaultPointOfInterest(1.0, 100.0, -300.0);
KFbxVector4 lNewPointOfInterest(0, 0, 0);
KFbxVector4 lRotation;
KFbxVector4 lScaling(1.0, 1.0, 1.0);
KFbxVector4::AxisAlignmentInEulerAngle(lCameraLocation, lDefaultPointOfInterest, lNewPointOfInterest, lRotation);
pCamera->LclTranslation.Set(lCameraLocation);
pCamera->LclRotation.Set(lRotation);
pCamera->LclScaling.Set(lScaling);
}
void SetCamera2DefaultPosition(KFbxNode* pCamera)
{
pCamera->LclTranslation.Set(KFbxVector4(-150.0, 0.0, 75.0));
}
void AnimateLightGroup(KFbxNode* pLightGroup, KFbxAnimLayer* pAnimLayer)
{
KFbxAnimCurve* lCurve = NULL;
KTime lTime;
int i;
int lKeyIndex = 0;
for (i = 0; i < pLightGroup->GetChildCount(); i++)
{
AnimateLight(pLightGroup->GetChild(i), i, pAnimLayer);
}
pLightGroup->LclRotation.GetCurveNode(pAnimLayer, true);
pLightGroup->LclTranslation.GetCurveNode(pAnimLayer, true);
lCurve = pLightGroup->LclRotation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_R_Y, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 0.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lTime.SetSecondDouble(10.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 5*360.0);
lCurve->KeyModifyEnd();
}
lCurve = pLightGroup->LclTranslation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_T_Y, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 15.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lTime.SetSecondDouble(5.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 200.0);
lCurve->KeyModifyEnd();
}
}
void AnimateLight(KFbxNode* pLight, int pIndex, KFbxAnimLayer* pAnimLayer)
{
KFbxAnimCurve* lCurve = NULL;
KTime lTime;
int i, j;
int lKeyIndex = 0;
KFbxLight* light = pLight->GetLight();
light->Intensity.GetCurveNode(pAnimLayer, true);
lCurve = light->Intensity.GetCurve<KFbxAnimCurve>(pAnimLayer, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 0.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lTime.SetSecondDouble(3.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 33.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lTime.SetSecondDouble(7.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 33.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lTime.SetSecondDouble(10.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 0.0);
lCurve->KeyModifyEnd();
}
light->Fog.GetCurveNode(pAnimLayer, true);
lCurve = light->Fog.GetCurve<KFbxAnimCurve>(pAnimLayer, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 0.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lTime.SetSecondDouble(3.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 33.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lTime.SetSecondDouble(7.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 33.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lTime.SetSecondDouble(10.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 0.0);
lCurve->KeyModifyEnd();
}
{
pLight->LclRotation.GetCurveNode(pAnimLayer, true);
light->ConeAngle.GetCurveNode(pAnimLayer, true);
lCurve = pLight->LclRotation.GetCurve<KFbxAnimCurve>(pAnimLayer, KFCURVENODE_R_X, true);
KFbxAnimCurve* lConeCurve = light->ConeAngle.GetCurve<KFbxAnimCurve>(pAnimLayer,true);
double lValue;
lCurve->KeyModifyBegin();
lConeCurve->KeyModifyBegin();
for (i = 0; i < 8; i++)
{
lTime.SetSecondDouble((double)i * 0.833333);
lValue = cos((((double)i) + (((double)pIndex) * 60.0)) * 72.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, float((lValue - 0.4) * 30.0));
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lKeyIndex = lConeCurve->KeyAdd(lTime);
lConeCurve->KeySetValue(lKeyIndex, float((2.0 - (lValue + 1.0)) * 45.0));
lConeCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
}
lTime.SetSecondDouble(10.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, -90.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lKeyIndex = lConeCurve->KeyAdd(lTime);
lConeCurve->KeySetValue(lKeyIndex, 180.0);
lConeCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lCurve->KeyModifyEnd();
lConeCurve->KeyModifyEnd();
}
{
fbxDouble3 lColor[6] =
{
fbxDouble3(1.0, 0.0, 0.0),
fbxDouble3(1.0, 1.0, 0.0),
fbxDouble3(0.0, 1.0, 0.0),
fbxDouble3(0.0, 1.0, 1.0),
fbxDouble3(0.0, 0.0, 1.0),
fbxDouble3(1.0, 0.0, 1.0)
};
KFbxAnimCurve* lCurve[3];
light->Color.GetCurveNode(pAnimLayer, true);
lCurve[0] = light->Color.GetCurve<KFbxAnimCurve>(pAnimLayer,KFCURVENODE_COLOR_RED, true);
lCurve[1] = light->Color.GetCurve<KFbxAnimCurve>(pAnimLayer,KFCURVENODE_COLOR_GREEN, true);
lCurve[2] = light->Color.GetCurve<KFbxAnimCurve>(pAnimLayer,KFCURVENODE_COLOR_BLUE, true);
if (lCurve[0] && lCurve[1] && lCurve[2])
{
lCurve[0]->KeyModifyBegin();
lCurve[1]->KeyModifyBegin();
lCurve[2]->KeyModifyBegin();
for (i = 0; i < 24; i++)
{
j = i + pIndex;
while (j > 5)
{
j -= 6;
}
lTime.SetSecondDouble((double)i * 0.4166666);
lKeyIndex = lCurve[0]->KeyAdd(lTime);
lCurve[0]->KeySetValue(lKeyIndex, (kFCurveDouble)lColor[j][0]);
lCurve[0]->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lKeyIndex = lCurve[1]->KeyAdd(lTime);
lCurve[1]->KeySetValue(lKeyIndex, (kFCurveDouble)lColor[j][1]);
lCurve[1]->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lKeyIndex = lCurve[2]->KeyAdd(lTime);
lCurve[2]->KeySetValue(lKeyIndex, (kFCurveDouble)lColor[j][2]);
lCurve[2]->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
}
lCurve[0]->KeyModifyEnd();
lCurve[1]->KeyModifyEnd();
lCurve[2]->KeyModifyEnd();
}
}
}
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(10.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 200.0);
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(10.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 300.0);
lCurve->KeyModifyEnd();
}
KFbxCamera* cam = pCamera->GetCamera();
cam->Roll.GetCurveNode(pAnimLayer, true);
lCurve = cam->Roll.GetCurve<KFbxAnimCurve>(pAnimLayer, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble (0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 0.0, KFbxAnimCurveDef::eINTERPOLATION_LINEAR);
lTime.SetSecondDouble(10.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 2*360.0);
lCurve->KeyModifyEnd();
}
}