#include <math.h>
#include <fbxsdk.h>
#include "../Common/Common.h"
#define SAMPLE_FILENAME "ExportScene02.fbx"
bool CreateScene(KFbxScene* pScene);
KFbxNode* CreateNurbs(KFbxScene* pScene, char* pName);
void MapStretchedShape(KFbxScene* pScene, KFbxNode* pNurbs);
void MapBoxShape(KFbxScene* pScene, KFbxNode* pNurbs);
void MapShapesOnNurbs(KFbxScene* pScene, KFbxNode* pNurbs);
void MapTexture(KFbxScene* pScene, KFbxNode* pNurbs);
void MapMaterial(KFbxScene* pScene, KFbxNode* pNurbs);
void AnimateNurbs(KFbxNode* pNurbs, KFbxScene* pScene);
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* lNurbs = CreateNurbs(pScene, "Nurbs");
MapShapesOnNurbs(pScene, lNurbs);
MapMaterial(pScene, lNurbs);
MapTexture(pScene, lNurbs);
KFbxNode* lRootNode = pScene->GetRootNode();
lRootNode->AddChild(lNurbs);
AnimateNurbs(lNurbs, pScene);
return true;
}
KFbxNode* CreateNurbs(KFbxScene* pScene, char* pName)
{
KFbxNurb* lNurbs = KFbxNurb::Create(pScene,pName);
lNurbs->SetOrder(4, 4);
lNurbs->SetStep(2, 2);
lNurbs->InitControlPoints(8, KFbxNurb::ePERIODIC, 7, KFbxNurb::eOPEN);
double lUKnotVector[] = { -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0 };
memcpy(lNurbs->GetUKnotVector(), lUKnotVector, lNurbs->GetUKnotCount()*sizeof(double));
double lVKnotVector[] = { 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 4.0, 4.0, 4.0 };
memcpy(lNurbs->GetVKnotVector(), lVKnotVector, lNurbs->GetVKnotCount()*sizeof(double));
KFbxVector4* lVector4 = lNurbs->GetControlPoints();
int i, j;
double lScale = 20.0;
double lPi = 3.14159;
double lYAngle[] = { 90.0, 90.0, 52.0, 0.0, -52.0, -90.0, -90.0 };
double lRadius[] = { 0.0, 0.283, 0.872, 1.226, 0.872, 0.283, 0.0};
for (i = 0; i < 7; i++)
{
for (j = 0; j < 8; j++)
{
double lX = lScale * lRadius[i] * cos(lPi/4*j);
double lY = lScale * sin(2*lPi/360*lYAngle[i]);
double lZ = lScale * lRadius[i] * sin(lPi/4*j);
double lWeight = 1.0;
lVector4[8*i + j].Set(lX, lY, lZ, lWeight);
}
}
KFbxNode* lNode = KFbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lNurbs);
return lNode;
}
void MapStretchedShape(KFbxScene* pScene, KFbxBlendShapeChannel* lBlendShapeChannel)
{
KFbxShape* lShape = KFbxShape::Create(pScene,"StretchedShape");
KFbxVector4 lExtremeRight(-250.0, 0.0, 0.0);
KFbxVector4 lExtremeLeft(250.0, 0.0, 0.0);
lShape->InitControlPoints(8*7);
KFbxVector4* lVector4 = lShape->GetControlPoints();
int i, j;
for (i = 0; i < 7; i++)
{
for (j = 0; j < 8; j++)
{
if (j < 3 || j > 6)
{
lVector4[8*i + j] = lExtremeLeft;
}
else
{
lVector4[8*i + j] = lExtremeRight;
}
}
}
lBlendShapeChannel->AddTargetShape(lShape);
}
void MapBoxShape(KFbxScene* pScene, KFbxBlendShapeChannel* lBlendShapeChannel)
{
KFbxShape* lShape = KFbxShape::Create(pScene,"BoxShape");
lShape->InitControlPoints(8*7);
KFbxVector4* lVector4 = lShape->GetControlPoints();
int i, j;
double lScale = 20.0;
double lWeight = 1.0;
double lX[] = { 0.9, 1.1, 0.0, -1.1, -0.9, -1.1, 0.0, 1.1 };
double lZ[] = { 0.0, 1.1, 0.9, 1.1, 0.0, -1.1, -0.9, -1.1 };
for (i = 0; i < 8; i++)
{
lVector4[i].Set(0.0, lScale, 0.0, lWeight);
}
for (i = 1; i < 6; i++)
{
double lY = 1.0 - 0.5 * (i - 1);
for (j = 0; j < 8; j++)
{
lVector4[8*i + j].Set(lScale*lX[j], lScale*lY, lScale*lZ[j], lWeight);
}
}
for (i = 48; i < 56; i++)
{
lVector4[i].Set(0.0, -lScale, 0.0, lWeight);
}
lBlendShapeChannel->AddTargetShape(lShape);
}
void MapShapesOnNurbs(KFbxScene* pScene, KFbxNode* pNurbs)
{
KFbxBlendShape* lBlendShape = KFbxBlendShape::Create(pScene,"MyBlendShape");
KFbxBlendShapeChannel* lBlendShapeChannel01 = KFbxBlendShapeChannel::Create(pScene,"MyBlendShapeChannel01");
KFbxBlendShapeChannel* lBlendShapeChannel02 = KFbxBlendShapeChannel::Create(pScene,"MyBlendShapeChannel02");
MapStretchedShape(pScene, lBlendShapeChannel01);
MapBoxShape(pScene, lBlendShapeChannel01);
MapBoxShape(pScene, lBlendShapeChannel02);
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel01);
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel02);
KFbxGeometry* lGeometry = pNurbs->GetGeometry();
lGeometry->AddDeformer(lBlendShape);
};
void MapTexture(KFbxScene* pScene, KFbxNode* pNurbs)
{
KFbxFileTexture* lTexture = KFbxFileTexture::Create(pScene,"scene02.jpg");
pNurbs->SetShadingMode(KFbxNode::eTEXTURE_SHADING);
lTexture->SetFileName("scene02.jpg");
lTexture->SetTextureUse(KFbxTexture::eSTANDARD);
lTexture->SetMappingType(KFbxTexture::eCYLINDRICAL);
lTexture->SetMaterialUse(KFbxFileTexture::eMODEL_MATERIAL);
lTexture->SetSwapUV(false);
lTexture->SetTranslation(0.45, -0.05);
lTexture->SetScale(4.0, 1.0);
lTexture->SetRotation(0.0, 0.0);
KFbxSurfacePhong* lMaterial = pNurbs->GetSrcObject<KFbxSurfacePhong>(0);
if (lMaterial)
lMaterial->Diffuse.ConnectSrcObject(lTexture);
lTexture=KFbxFileTexture::Create(pScene, "grandient.jpg");
lTexture->SetFileName("gradient.jpg");
lTexture->SetTextureUse(KFbxTexture::eSTANDARD);
lTexture->SetMappingType(KFbxTexture::eCYLINDRICAL);
lTexture->SetMaterialUse(KFbxFileTexture::eMODEL_MATERIAL);
lTexture->SetSwapUV(false);
if (lMaterial)
lMaterial->Ambient.ConnectSrcObject(lTexture);
}
void MapMaterial(KFbxScene* pScene, KFbxNode* pNurbs)
{
KFbxSurfacePhong* lMaterial = KFbxSurfacePhong::Create(pScene,"scene02");
fbxDouble3 lBlue(0.0, 0.0, 1.0);
fbxDouble3 lBlack(0.0, 0.0, 0.0);
lMaterial->Emissive.Set(lBlue);
lMaterial->Ambient.Set(lBlack);
lMaterial->Specular.Set(lBlack);
lMaterial->TransparencyFactor.Set(0.0);
lMaterial->Shininess.Set(0.0);
lMaterial->ReflectionFactor.Set(0.0);
KFbxNurb* lNurb = pNurbs->GetNurb();
KFbxGeometryElementMaterial* lGeometryElementMaterial = lNurb->GetElementMaterial( 0);
if (!lGeometryElementMaterial)
{
lGeometryElementMaterial = lNurb->CreateElementMaterial();
}
lGeometryElementMaterial->SetMappingMode(KFbxGeometryElement::eALL_SAME);
lGeometryElementMaterial->SetReferenceMode(KFbxGeometryElement::eDIRECT);
pNurbs->AddMaterial(lMaterial);
}
void AnimateNurbs(KFbxNode* pNurbs, KFbxScene* pScene)
{
KString lAnimStackName;
KTime lTime;
int lKeyIndex = 0;
lAnimStackName = "Morph sphere into box";
KFbxAnimStack* lAnimStack = KFbxAnimStack::Create(pScene, lAnimStackName);
KFbxAnimLayer* lAnimLayer = KFbxAnimLayer::Create(pScene, "Base Layer");
lAnimStack->AddMember(lAnimLayer);
KFbxGeometry* lNurbsAttribute = (KFbxGeometry*) pNurbs->GetNodeAttribute();
KFbxAnimCurve* lCurve = lNurbsAttribute->GetShapeChannel(0, 0, lAnimLayer, 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(1.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 75.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lTime.SetSecondDouble(1.25);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 0.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lCurve->KeyModifyEnd();
}
lCurve = lNurbsAttribute->GetShapeChannel(0, 1, lAnimLayer, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(1.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 0.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lTime.SetSecondDouble(1.25);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 100.0);
lCurve->KeySetInterpolation(lKeyIndex, KFbxAnimCurveDef::eINTERPOLATION_CUBIC);
lCurve->KeyModifyEnd();
}
}