#include <math.h>
#include <fbxsdk.h>
#include "../Common/Common.h"
#define SAMPLE_FILENAME "ExportScene02.fbx"
bool CreateScene(FbxScene* pScene);
FbxNode* CreateNurbs(FbxScene* pScene, const char* pName);
void MapStretchedShape(FbxScene* pScene, FbxNode* pNurbs);
void MapBoxShape(FbxScene* pScene, FbxNode* pNurbs);
void MapShapesOnNurbs(FbxScene* pScene, FbxNode* pNurbs);
void MapTexture(FbxScene* pScene, FbxNode* pNurbs);
void MapMaterial(FbxScene* pScene, FbxNode* pNurbs);
void AnimateNurbs(FbxNode* pNurbs, FbxScene* pScene);
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 0;
}
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 0;
}
DestroySdkObjects(lSdkManager, lResult);
return 0;
}
bool CreateScene(FbxScene* pScene)
{
FbxNode* lNurbs = CreateNurbs(pScene, "Nurbs");
MapShapesOnNurbs(pScene, lNurbs);
MapMaterial(pScene, lNurbs);
MapTexture(pScene, lNurbs);
FbxNode* lRootNode = pScene->GetRootNode();
lRootNode->AddChild(lNurbs);
AnimateNurbs(lNurbs, pScene);
return true;
}
FbxNode* CreateNurbs(FbxScene* pScene, const char* pName)
{
FbxNurbs* lNurbs = FbxNurbs::Create(pScene,pName);
lNurbs->SetOrder(4, 4);
lNurbs->SetStep(2, 2);
lNurbs->InitControlPoints(8, FbxNurbs::ePeriodic, 7, FbxNurbs::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));
FbxVector4* 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);
}
}
FbxNode* lNode = FbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lNurbs);
return lNode;
}
void MapStretchedShape(FbxScene* pScene, FbxBlendShapeChannel* lBlendShapeChannel)
{
FbxShape* lShape = FbxShape::Create(pScene,"StretchedShape");
FbxVector4 lExtremeRight(-250.0, 0.0, 0.0);
FbxVector4 lExtremeLeft(250.0, 0.0, 0.0);
lShape->InitControlPoints(8*7);
FbxVector4* 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(FbxScene* pScene, FbxBlendShapeChannel* lBlendShapeChannel)
{
FbxShape* lShape = FbxShape::Create(pScene,"BoxShape");
lShape->InitControlPoints(8*7);
FbxVector4* 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(FbxScene* pScene, FbxNode* pNurbs)
{
FbxBlendShape* lBlendShape = FbxBlendShape::Create(pScene,"MyBlendShape");
FbxBlendShapeChannel* lBlendShapeChannel01 = FbxBlendShapeChannel::Create(pScene,"MyBlendShapeChannel01");
FbxBlendShapeChannel* lBlendShapeChannel02 = FbxBlendShapeChannel::Create(pScene,"MyBlendShapeChannel02");
MapStretchedShape(pScene, lBlendShapeChannel01);
MapBoxShape(pScene, lBlendShapeChannel01);
MapBoxShape(pScene, lBlendShapeChannel02);
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel01);
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel02);
FbxGeometry* lGeometry = pNurbs->GetGeometry();
lGeometry->AddDeformer(lBlendShape);
};
void MapTexture(FbxScene* pScene, FbxNode* pNurbs)
{
FbxFileTexture* lTexture = FbxFileTexture::Create(pScene,"scene02.jpg");
pNurbs->SetShadingMode(FbxNode::eTextureShading);
lTexture->SetFileName("scene02.jpg");
lTexture->SetTextureUse(FbxTexture::eStandard);
lTexture->SetMappingType(FbxTexture::eCylindrical);
lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
lTexture->SetSwapUV(false);
lTexture->SetTranslation(0.45, -0.05);
lTexture->SetScale(4.0, 1.0);
lTexture->SetRotation(0.0, 0.0);
FbxSurfacePhong* lMaterial = pNurbs->GetSrcObject<FbxSurfacePhong>(0);
if (lMaterial)
lMaterial->Diffuse.ConnectSrcObject(lTexture);
lTexture=FbxFileTexture::Create(pScene, "grandient.jpg");
lTexture->SetFileName("gradient.jpg");
lTexture->SetTextureUse(FbxTexture::eStandard);
lTexture->SetMappingType(FbxTexture::eCylindrical);
lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
lTexture->SetSwapUV(false);
if (lMaterial)
lMaterial->Ambient.ConnectSrcObject(lTexture);
}
void MapMaterial(FbxScene* pScene, FbxNode* pNurbs)
{
FbxSurfacePhong* lMaterial = FbxSurfacePhong::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);
FbxNurbs* lNurbs = pNurbs->GetNurbs();
FbxGeometryElementMaterial* lGeometryElementMaterial = lNurbs->GetElementMaterial( 0);
if (!lGeometryElementMaterial)
{
lGeometryElementMaterial = lNurbs->CreateElementMaterial();
}
lGeometryElementMaterial->SetMappingMode(FbxGeometryElement::eAllSame);
lGeometryElementMaterial->SetReferenceMode(FbxGeometryElement::eDirect);
pNurbs->AddMaterial(lMaterial);
}
void AnimateNurbs(FbxNode* pNurbs, FbxScene* pScene)
{
FbxString lAnimStackName;
FbxTime lTime;
int lKeyIndex = 0;
lAnimStackName = "Morph sphere into box";
FbxAnimStack* lAnimStack = FbxAnimStack::Create(pScene, lAnimStackName);
FbxAnimLayer* lAnimLayer = FbxAnimLayer::Create(pScene, "Base Layer");
lAnimStack->AddMember(lAnimLayer);
FbxGeometry* lNurbsAttribute = (FbxGeometry*) pNurbs->GetNodeAttribute();
FbxAnimCurve* 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, FbxAnimCurveDef::eInterpolationCubic);
lTime.SetSecondDouble(1.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 75.0);
lCurve->KeySetInterpolation(lKeyIndex, FbxAnimCurveDef::eInterpolationCubic);
lTime.SetSecondDouble(1.25);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 0.0);
lCurve->KeySetInterpolation(lKeyIndex, FbxAnimCurveDef::eInterpolationCubic);
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, FbxAnimCurveDef::eInterpolationCubic);
lTime.SetSecondDouble(1.25);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySetValue(lKeyIndex, 100.0);
lCurve->KeySetInterpolation(lKeyIndex, FbxAnimCurveDef::eInterpolationCubic);
lCurve->KeyModifyEnd();
}
}