FBX2glTF/sdk/Windows/2019.2/samples/UI Examples/CubeCreator/SDK_Utility.cxx

799 lines
26 KiB
C++
Executable File

/****************************************************************************************
Copyright (C) 2015 Autodesk, Inc.
All rights reserved.
Use of this software is subject to the terms of the Autodesk license agreement
provided at the time of installation or download, or which otherwise accompanies
this software in either electronic or hard copy form.
****************************************************************************************/
#include "SDK_Utility.h"
// declare global
FbxManager* gSdkManager = NULL;
FbxScene* gScene = NULL;
FbxFileTexture* gTexture = NULL;
FbxSurfacePhong* gMaterial = NULL;
int gCubeNumber = 1; // Cube Number
int gCubeRotationAxis = 1; // Cube Rotation Axis 0==X, 1==Y, 2==Z
double gCubeXPos = 0.0; // initial CubXPos
double gCubeYPos = 20.0; // initial CubeYPos
double gCubeZPos = 0.0; // initial CubeZPos
FbxAnimLayer* gAnimLayer = NULL; // holder of animation curves
FbxString* gAppPath = NULL; // path where the application started
#ifdef IOS_REF
#undef IOS_REF
#define IOS_REF (*(pSdkManager->GetIOSettings()))
#endif
bool InitializeSdkObjects(FbxManager*& pManager, FbxScene*& pScene)
{
//The first thing to do is to create the FBX Manager which is the object allocator for almost all the classes in the SDK
pManager = FbxManager::Create();
if( !pManager )
{
FBXSDK_printf("Error: Unable to create FBX Manager!\n");
exit(1);
}
else FBXSDK_printf("Autodesk FBX SDK version %s\n", pManager->GetVersion());
//Create an IOSettings object. This object holds all import/export settings.
FbxIOSettings* ios = FbxIOSettings::Create(pManager, IOSROOT);
pManager->SetIOSettings(ios);
//Create an FBX scene. This object holds most objects imported/exported from/to files.
pScene = FbxScene::Create(pManager, "My Scene");
if( !pScene )
{
FBXSDK_printf("Error: Unable to create FBX scene!\n");
exit(1);
}
return true;
}
void DestroySdkObjects(FbxManager* pManager, bool pExitStatus)
{
//Delete the FBX Manager. All the objects that have been allocated using the FBX Manager and that haven't been explicitly destroyed are also automatically destroyed.
if( pManager ) pManager->Destroy();
if( pExitStatus ) FBXSDK_printf("Program Success!\n");
}
// to create a basic scene
bool CreateScene()
{
// Initialize the FbxManager and the FbxScene
if(InitializeSdkObjects(gSdkManager, gScene) == false)
{
return false;
}
// set the animation stack and use the unique AnimLayer to support all the animation
FbxAnimStack* lAnimStack = FbxAnimStack::Create(gScene, "Animation stack camera animation");
gAnimLayer = FbxAnimLayer::Create(gScene, "Base Layer");
lAnimStack->AddMember(gAnimLayer);
// create a marker
FbxNode* lMarker = CreateMarker(gScene, "Marker");
// create a camera
FbxNode* lCamera = CreateCamera(gScene, "Camera");
// create a single texture shared by all cubes
CreateTexture(gScene);
// create a material shared by all faces of all cubes
CreateMaterial(gScene);
// set the camera point of interest on the marker
SetCameraPointOfInterest(lCamera, lMarker);
// set the marker position
SetMarkerDefaultPosition(lMarker);
// set the camera position
SetCameraDefaultPosition(lCamera);
// animate the camera
AnimateCamera(lCamera, gAnimLayer);
// build a minimum scene graph
FbxNode* lRootNode = gScene->GetRootNode();
lRootNode->AddChild(lMarker);
lRootNode->AddChild(lCamera);
// set camera switcher as the default camera
gScene->GetGlobalSettings().SetDefaultCamera((char *)lCamera->GetName());
return true;
}
// create a new cube
void CreateCube(bool pWithTexture, bool pAnimate)
{
// make a new cube name
FbxString lCubeName = "Cube number ";
lCubeName += FbxString(gCubeNumber);
// create a new cube
CreateCubeDetailed( lCubeName.Buffer(),
gCubeXPos,
gCubeYPos,
gCubeZPos,
gCubeRotationAxis,
pWithTexture,
pAnimate
);
// compute for next cube creation
gCubeNumber++; // cube number
// set next pos
if(gCubeXPos >= 0.0)
{
gCubeXPos += 50.0;
gCubeXPos *= -1.0;
gCubeRotationAxis++; // change rotation axis
}
else
{
gCubeXPos *= -1.0;
}
// go up
gCubeYPos += 30.0;
if(gCubeRotationAxis > 2) gCubeRotationAxis = 0; // cube rotation
}
// to remove cubes only
void RemoveCubes()
{
if(gSdkManager == NULL) return;
// get the node count
int nc = gScene->GetNodeCount();
// we want to keep the root node, the marker node and the camera node
if(nc <= 3) return;
// remove other nodes (cube nodes)
// start from the end
for(int i=nc-1; i >= 3; i--)
{
FbxNode *node = gScene->GetNode(i);
gScene->RemoveNode(node);
// remove animation
FbxAnimCurveNode* lCurveNode = node->LclRotation.GetCurveNode(gAnimLayer);
if(lCurveNode != NULL)
{
lCurveNode->Destroy(true);
}
// remove from memory
node->Destroy(true);
}
// reset cube data
SetInitialCubeData();
}
// create a new cube
void CreateCubeDetailed( char* pCubeName,
double pX,
double pY,
double pZ,
int pRotateAxe,
bool pWithTexture,
bool pAnimate
)
{
FbxNode* lCube = CreateCubeMesh(gScene, pCubeName);
// set the cube position
lCube->LclTranslation.Set(FbxVector4(pX, pY, pZ));
if(pAnimate)
{
AnimateCube(lCube, gAnimLayer, pRotateAxe);
}
if(pWithTexture)
{
// if we asked to create the cube with a texture, we need
// a material present because the texture connects to the
// material DiffuseColor property
AddMaterials(lCube->GetMesh());
}
gScene->GetRootNode()->AddChild(lCube);
}
// to save a scene to a FBX file
bool Export(
const char* pFilename,
int pFileFormat
)
{
return SaveScene(gSdkManager, gScene, pFilename, pFileFormat, true); // true -> embed texture file
}
// to save a scene to a FBX file
bool SaveScene(FbxManager* pSdkManager, FbxDocument* 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;
// Create an exporter.
FbxExporter* lExporter = FbxExporter::Create(pSdkManager, "");
if( pFileFormat < 0 || pFileFormat >= pSdkManager->GetIOPluginRegistry()->GetWriterFormatCount() )
{
// Write in fall back format if pEmbedMedia is true
pFileFormat = pSdkManager->GetIOPluginRegistry()->GetNativeWriterFormat();
if (!pEmbedMedia)
{
//Try to export in ASCII if possible
int lFormatIndex, lFormatCount = pSdkManager->GetIOPluginRegistry()->GetWriterFormatCount();
for (lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++)
{
if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex))
{
FbxString lDesc =pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex);
char *lASCII = "ascii";
if (lDesc.Find(lASCII)>=0)
{
pFileFormat = lFormatIndex;
break;
}
}
}
}
}
// Initialize the exporter by providing a filename.
if(lExporter->Initialize(pFilename, pFileFormat, pSdkManager->GetIOSettings() ) == false)
{
return false;
}
// Set the export states. By default, the export states are always set to
// true except for the option eEXPORT_TEXTURE_AS_EMBEDDED. The code below
// shows how to change these states.
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);
// Export the scene.
lStatus = lExporter->Export(pScene);
// Destroy the exporter.
lExporter->Destroy();
return lStatus;
}
// to get the filters for the <Save file> dialog (description + file extention)
const char *GetWriterSFNFilters()
{
int nbWriters = gSdkManager->GetIOPluginRegistry()->GetWriterFormatCount();
FbxString s;
int i=0;
for(i=0; i < nbWriters; i++)
{
s += gSdkManager->GetIOPluginRegistry()->
GetWriterFormatDescription(i);
s += "|*.";
s += gSdkManager->GetIOPluginRegistry()->
GetWriterFormatExtension(i);
s += "|";
}
// replace | by \0
int nbChar = int(strlen(s.Buffer())) + 1;
char *filter = new char[ nbChar ];
memset(filter, 0, nbChar);
FBXSDK_strcpy(filter, nbChar, s.Buffer());
for(i=0; i < int(strlen(s.Buffer())); i++)
{
if(filter[i] == '|')
{
filter[i] = 0;
}
}
// the caller must delete this allocated memory
return filter;
}
// to get a file extention for a WriteFileFormat
const char *GetFileFormatExt(
const int pWriteFileFormat
)
{
char *buf = new char[10];
memset(buf, 0, 10);
// add a starting point .
buf[0] = '.';
const char * ext = gSdkManager->GetIOPluginRegistry()->
GetWriterFormatExtension(pWriteFileFormat);
FBXSDK_strcat(buf, 10, ext);
// the caller must delete this allocated memory
return buf;
}
// to get the root node
const FbxNode* GetRootNode()
{
return gScene->GetRootNode();
}
// to get the root node name
const char * GetRootNodeName()
{
return GetRootNode()->GetName();
}
// to get a string from the node name and attribute type
FbxString GetNodeNameAndAttributeTypeName(const FbxNode* pNode)
{
FbxString s = pNode->GetName();
FbxNodeAttribute::EType lAttributeType;
if(pNode->GetNodeAttribute() == NULL)
{
s += " (No node attribute type)";
}
else
{
lAttributeType = (pNode->GetNodeAttribute()->GetAttributeType());
switch (lAttributeType)
{
case FbxNodeAttribute::eMarker: s += " (Marker)"; break;
case FbxNodeAttribute::eSkeleton: s += " (Skeleton)"; break;
case FbxNodeAttribute::eMesh: s += " (Mesh)"; break;
case FbxNodeAttribute::eCamera: s += " (Camera)"; break;
case FbxNodeAttribute::eLight: s += " (Light)"; break;
case FbxNodeAttribute::eBoundary: s += " (Boundary)"; break;
case FbxNodeAttribute::eOpticalMarker: s += " (Optical marker)"; break;
case FbxNodeAttribute::eOpticalReference: s += " (Optical reference)"; break;
case FbxNodeAttribute::eCameraSwitcher: s += " (Camera switcher)"; break;
case FbxNodeAttribute::eNull: s += " (Null)"; break;
case FbxNodeAttribute::ePatch: s += " (Patch)"; break;
case FbxNodeAttribute::eNurbs: s += " (NURB)"; break;
case FbxNodeAttribute::eNurbsSurface: s += " (Nurbs surface)"; break;
case FbxNodeAttribute::eNurbsCurve: s += " (NURBS curve)"; break;
case FbxNodeAttribute::eTrimNurbsSurface: s += " (Trim nurbs surface)"; break;
case FbxNodeAttribute::eUnknown: s += " (Unidentified)"; break;
}
}
return s;
}
// to get a string from the node default translation values
FbxString GetDefaultTranslationInfo(
const FbxNode* pNode
)
{
FbxVector4 v4;
v4 = ((FbxNode*)pNode)->LclTranslation.Get();
return FbxString("Translation (X,Y,Z): ") + FbxString(v4[0]) + ", " + FbxString(v4[1]) + ", " + FbxString(v4[2]);
}
// to get a string with info about material, texture, animation
FbxString GetNodeInfo( const FbxNode* pNode )
{
FbxString s;
// check for texture
int lMaterialCount = pNode->GetMaterialCount();
FbxSurfacePhong* lMaterial = NULL;
bool lTextureExist = false;
if( lMaterialCount > 0)
{
for( int i = 0; i < lMaterialCount; ++i)
{
lMaterial = (FbxSurfacePhong*)pNode->GetMaterial( i);
if( lMaterial->Diffuse.GetSrcObjectCount<FbxFileTexture>() > 0)
{
lTextureExist = true;
break;
}
}
}
if( lTextureExist) s+= "[Texture: Yes] ";
else s+= "[Texture: No] ";
// check for animation
bool anim = false;
FbxAnimCurveNode* lCurveNode = NULL;
// check rotation FCurve node
lCurveNode =((FbxNode* )pNode)->LclRotation.GetCurveNode(gAnimLayer);
if(lCurveNode != NULL) anim = true;
// check Translation FCurve node
lCurveNode = ((FbxNode* )pNode)->LclTranslation.GetCurveNode(gAnimLayer);
if(lCurveNode != NULL) anim = true;
if(anim == true)
{
s+= "[Animation: Yes] ";
}
else
{
s+= "[Animation: No] ";
}
return s;
}
// Create a marker to use a point of interest for the camera.
FbxNode* CreateMarker(FbxScene* pScene, char* pName)
{
FbxMarker* lMarker = FbxMarker::Create(pScene,pName);
FbxNode* lNode = FbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lMarker);
return lNode;
}
// Create a camera.
FbxNode* CreateCamera(FbxScene* pScene, char* pName)
{
FbxCamera* lCamera = FbxCamera::Create(pScene,pName);
// Set camera property for a classic TV projection with aspect ratio 4:3
lCamera->SetFormat(FbxCamera::eNTSC);
FbxNode* lNode = FbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lCamera);
return lNode;
}
// Set target of the camera.
void SetCameraPointOfInterest(FbxNode* pCamera, FbxNode* pPointOfInterest)
{
// Set the camera to always point at this node.
pCamera->SetTarget(pPointOfInterest);
}
// Set marker default position.
void SetMarkerDefaultPosition(FbxNode* pMarker)
{
// The marker is positioned above the origin. There is no rotation and no scaling.
pMarker->LclTranslation.Set(FbxVector4(0.0, 40.0, 0.0));
pMarker->LclRotation.Set(FbxVector4(0.0, 0.0, 0.0));
pMarker->LclScaling.Set(FbxVector4(1.0, 1.0, 1.0));
}
// Compute the camera position.
void SetCameraDefaultPosition(FbxNode* pCamera)
{
// set the initial camera position
FbxVector4 lCameraLocation(0.0, 200.0, -100.0);
pCamera->LclTranslation.Set(lCameraLocation);
}
// The camera move on X and Y axis.
void AnimateCamera(FbxNode* pCamera, FbxAnimLayer* pAnimLayer)
{
FbxAnimCurve* lCurve = NULL;
FbxTime lTime;
int lKeyIndex = 0;
pCamera->LclTranslation.GetCurveNode(pAnimLayer, true);
// X translation.
lCurve = pCamera->LclTranslation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 0.0, FbxAnimCurveDef::eInterpolationLinear);
lTime.SetSecondDouble(20.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 500.0, FbxAnimCurveDef::eInterpolationLinear);
lCurve->KeyModifyEnd();
}
// Y translation.
lCurve = pCamera->LclTranslation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 0.0, FbxAnimCurveDef::eInterpolationLinear);
lTime.SetSecondDouble(20.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 800.0, FbxAnimCurveDef::eInterpolationLinear);
lCurve->KeyModifyEnd();
}
}
// The cube rotate on X or Y or Z.
void AnimateCube(FbxNode* pCube, FbxAnimLayer* pAnimLayer, int pRotAxe)
{
FbxAnimCurve* lCurve = NULL;
FbxTime lTime;
int lKeyIndex = 0;
pCube->LclRotation.GetCurveNode(pAnimLayer, true);
if(pRotAxe == 0) lCurve = pCube->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true);
else if(pRotAxe == 1) lCurve = pCube->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true);
else if(pRotAxe == 2) lCurve = pCube->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true);
if (lCurve)
{
lCurve->KeyModifyBegin();
lTime.SetSecondDouble(0.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, 0.0, FbxAnimCurveDef::eInterpolationLinear);
lTime.SetSecondDouble(20.0);
lKeyIndex = lCurve->KeyAdd(lTime);
lCurve->KeySet(lKeyIndex, lTime, -3500, FbxAnimCurveDef::eInterpolationLinear);
lCurve->KeyModifyEnd();
}
}
// Create a cube mesh.
FbxNode* CreateCubeMesh(FbxScene* pScene, char* pName)
{
int i, j;
FbxMesh* lMesh = FbxMesh::Create(pScene,pName);
FbxVector4 lControlPoint0(-50, 0, 50);
FbxVector4 lControlPoint1(50, 0, 50);
FbxVector4 lControlPoint2(50, 100, 50);
FbxVector4 lControlPoint3(-50, 100, 50);
FbxVector4 lControlPoint4(-50, 0, -50);
FbxVector4 lControlPoint5(50, 0, -50);
FbxVector4 lControlPoint6(50, 100, -50);
FbxVector4 lControlPoint7(-50, 100, -50);
FbxVector4 lNormalXPos(1, 0, 0);
FbxVector4 lNormalXNeg(-1, 0, 0);
FbxVector4 lNormalYPos(0, 1, 0);
FbxVector4 lNormalYNeg(0, -1, 0);
FbxVector4 lNormalZPos(0, 0, 1);
FbxVector4 lNormalZNeg(0, 0, -1);
// Create control points.
lMesh->InitControlPoints(24);
FbxVector4* 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;
// We want to have one normal for each vertex (or control point),
// so we set the mapping mode to eByControlPoint.
FbxGeometryElementNormal* lGeometryElementNormal= lMesh->CreateElementNormal();
lGeometryElementNormal->SetMappingMode(FbxGeometryElement::eByControlPoint);
// Set the normal values for every control point.
lGeometryElementNormal->SetReferenceMode(FbxGeometryElement::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);
// Array of polygon vertices.
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 };
// Create UV for Diffuse channel.
FbxGeometryElementUV* lUVDiffuseElement = lMesh->CreateElementUV( "DiffuseUV");
FBX_ASSERT( lUVDiffuseElement != NULL);
lUVDiffuseElement->SetMappingMode(FbxGeometryElement::eByPolygonVertex);
lUVDiffuseElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect);
FbxVector2 lVectors0(0, 0);
FbxVector2 lVectors1(1, 0);
FbxVector2 lVectors2(1, 1);
FbxVector2 lVectors3(0, 1);
lUVDiffuseElement->GetDirectArray().Add(lVectors0);
lUVDiffuseElement->GetDirectArray().Add(lVectors1);
lUVDiffuseElement->GetDirectArray().Add(lVectors2);
lUVDiffuseElement->GetDirectArray().Add(lVectors3);
//Now we have set the UVs as eIndexToDirect reference and in eByPolygonVertex mapping mode
//we must update the size of the index array.
lUVDiffuseElement->GetIndexArray().SetCount(24);
// Create polygons. Assign texture and texture UV indices.
for(i = 0; i < 6; i++)
{
// all faces of the cube have the same texture
lMesh->BeginPolygon(-1, -1, -1, false);
for(j = 0; j < 4; j++)
{
// Control point index
lMesh->AddPolygon(lPolygonVertices[i*4 + j]);
// update the index array of the UVs that map the texture to the face
lUVDiffuseElement->GetIndexArray().SetAt(i*4+j, j);
}
lMesh->EndPolygon ();
}
// create a FbxNode
FbxNode* lNode = FbxNode::Create(pScene,pName);
// set the node attribute
lNode->SetNodeAttribute(lMesh);
// set the shading mode to view texture
lNode->SetShadingMode(FbxNode::eTextureShading);
// rescale the cube
lNode->LclScaling.Set(FbxVector4(0.3, 0.3, 0.3));
// return the FbxNode
return lNode;
}
// Create a global texture for cube.
void CreateTexture(FbxScene* pScene)
{
gTexture = FbxFileTexture::Create(pScene,"Diffuse Texture");
// Resource file must be in the application's directory.
FbxString lTexPath = gAppPath ? *gAppPath + "\\Crate.jpg" : "";
// Set texture properties.
gTexture->SetFileName(lTexPath.Buffer());
gTexture->SetTextureUse(FbxTexture::eStandard);
gTexture->SetMappingType(FbxTexture::eUV);
gTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
gTexture->SetSwapUV(false);
gTexture->SetTranslation(0.0, 0.0);
gTexture->SetScale(1.0, 1.0);
gTexture->SetRotation(0.0, 0.0);
}
// Create global material for cube.
void CreateMaterial(FbxScene* pScene)
{
FbxString lMaterialName = "material";
FbxString 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 = FbxSurfacePhong::Create(pScene, lMaterialName.Buffer());
// Generate primary and secondary colors.
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);
// the texture need to be connected to the material on the corresponding property
if (gTexture)
gMaterial->Diffuse.ConnectSrcObject(gTexture);
}
void AddMaterials(FbxMesh* pMesh)
{
// Set material mapping.
FbxGeometryElementMaterial* lMaterialElement = pMesh->CreateElementMaterial();
lMaterialElement->SetMappingMode(FbxGeometryElement::eByPolygon);
lMaterialElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect);
//get the node of mesh, add material for it.
FbxNode* lNode = pMesh->GetNode();
if(lNode == NULL)
return;
lNode->AddMaterial(gMaterial);
// We are in eByPolygon, so there's only need for 6 index (a cube has 6 polygons).
lMaterialElement->GetIndexArray().SetCount(6);
// Set the Index 0 to 6 to the material in position 0 of the direct array.
for(int i=0; i<6; ++i)
lMaterialElement->GetIndexArray().SetAt(i,0);
}
// Reset camera values
void SetInitialCubeData()
{
gCubeNumber = 1; // Cube Number
gCubeRotationAxis = 1; // Cube Rotation Axis 0==X, 1==Y, 2==Z
gCubeXPos = 0.0; // initial CubXPos
gCubeYPos = 20.0; // initial CubeYPos
gCubeZPos = 0.0; // initial CubeZPos
}