603 lines
19 KiB
C++
603 lines
19 KiB
C++
/****************************************************************************************
|
|
|
|
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 "DisplayMesh.h"
|
|
|
|
#include "DisplayMaterial.h"
|
|
#include "DisplayTexture.h"
|
|
#include "DisplayLink.h"
|
|
#include "DisplayShape.h"
|
|
#include "DisplayCache.h"
|
|
|
|
#if defined (FBXSDK_ENV_MAC)
|
|
// disable the “format not a string literal and no format arguments” warning since
|
|
// the FBXSDK_printf calls made here are all valid calls and there is no secuity risk
|
|
#pragma GCC diagnostic ignored "-Wformat-security"
|
|
#endif
|
|
|
|
#define MAT_HEADER_LENGTH 200
|
|
|
|
void DisplayControlsPoints(FbxMesh* pMesh);
|
|
void DisplayPolygons(FbxMesh* pMesh);
|
|
void DisplayMaterialMapping(FbxMesh* pMesh);
|
|
void DisplayTextureMapping(FbxMesh* pMesh);
|
|
void DisplayTextureNames( FbxProperty &pProperty, FbxString& pConnectionString );
|
|
void DisplayMaterialConnections(FbxMesh* pMesh);
|
|
void DisplayMaterialTextureConnections( FbxSurfaceMaterial* pMaterial,
|
|
char * header, int pMatId, int l );
|
|
|
|
void DisplayMesh(FbxNode* pNode)
|
|
{
|
|
FbxMesh* lMesh = (FbxMesh*) pNode->GetNodeAttribute ();
|
|
|
|
DisplayString("Mesh Name: ", (char *) pNode->GetName());
|
|
DisplayMetaDataConnections(lMesh);
|
|
DisplayControlsPoints(lMesh);
|
|
DisplayPolygons(lMesh);
|
|
DisplayMaterialMapping(lMesh);
|
|
DisplayMaterial(lMesh);
|
|
DisplayTexture(lMesh);
|
|
DisplayMaterialConnections(lMesh);
|
|
DisplayLink(lMesh);
|
|
DisplayShape(lMesh);
|
|
|
|
DisplayCache(lMesh);
|
|
}
|
|
|
|
|
|
void DisplayControlsPoints(FbxMesh* pMesh)
|
|
{
|
|
int i, lControlPointsCount = pMesh->GetControlPointsCount();
|
|
FbxVector4* lControlPoints = pMesh->GetControlPoints();
|
|
|
|
DisplayString(" Control Points");
|
|
|
|
for (i = 0; i < lControlPointsCount; i++)
|
|
{
|
|
DisplayInt(" Control Point ", i);
|
|
Display3DVector(" Coordinates: ", lControlPoints[i]);
|
|
|
|
for (int j = 0; j < pMesh->GetElementNormalCount(); j++)
|
|
{
|
|
FbxGeometryElementNormal* leNormals = pMesh->GetElementNormal( j);
|
|
if (leNormals->GetMappingMode() == FbxGeometryElement::eByControlPoint)
|
|
{
|
|
char header[100];
|
|
FBXSDK_sprintf(header, 100, " Normal Vector: ");
|
|
if (leNormals->GetReferenceMode() == FbxGeometryElement::eDirect)
|
|
Display3DVector(header, leNormals->GetDirectArray().GetAt(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
DisplayString("");
|
|
}
|
|
|
|
|
|
void DisplayPolygons(FbxMesh* pMesh)
|
|
{
|
|
int i, j, lPolygonCount = pMesh->GetPolygonCount();
|
|
FbxVector4* lControlPoints = pMesh->GetControlPoints();
|
|
char header[100];
|
|
|
|
DisplayString(" Polygons");
|
|
|
|
int vertexId = 0;
|
|
for (i = 0; i < lPolygonCount; i++)
|
|
{
|
|
DisplayInt(" Polygon ", i);
|
|
int l;
|
|
|
|
for (l = 0; l < pMesh->GetElementPolygonGroupCount(); l++)
|
|
{
|
|
FbxGeometryElementPolygonGroup* lePolgrp = pMesh->GetElementPolygonGroup(l);
|
|
switch (lePolgrp->GetMappingMode())
|
|
{
|
|
case FbxGeometryElement::eByPolygon:
|
|
if (lePolgrp->GetReferenceMode() == FbxGeometryElement::eIndex)
|
|
{
|
|
FBXSDK_sprintf(header, 100, " Assigned to group: ");
|
|
int polyGroupId = lePolgrp->GetIndexArray().GetAt(i);
|
|
DisplayInt(header, polyGroupId);
|
|
break;
|
|
}
|
|
default:
|
|
// any other mapping modes don't make sense
|
|
DisplayString(" \"unsupported group assignment\"");
|
|
break;
|
|
}
|
|
}
|
|
|
|
int lPolygonSize = pMesh->GetPolygonSize(i);
|
|
|
|
for (j = 0; j < lPolygonSize; j++)
|
|
{
|
|
int lControlPointIndex = pMesh->GetPolygonVertex(i, j);
|
|
if (lControlPointIndex < 0)
|
|
{
|
|
DisplayString(" Coordinates: Invalid index found!");
|
|
continue;
|
|
}
|
|
else
|
|
Display3DVector(" Coordinates: ", lControlPoints[lControlPointIndex]);
|
|
|
|
for (l = 0; l < pMesh->GetElementVertexColorCount(); l++)
|
|
{
|
|
FbxGeometryElementVertexColor* leVtxc = pMesh->GetElementVertexColor( l);
|
|
FBXSDK_sprintf(header, 100, " Color vertex: ");
|
|
|
|
switch (leVtxc->GetMappingMode())
|
|
{
|
|
default:
|
|
break;
|
|
case FbxGeometryElement::eByControlPoint:
|
|
switch (leVtxc->GetReferenceMode())
|
|
{
|
|
case FbxGeometryElement::eDirect:
|
|
DisplayColor(header, leVtxc->GetDirectArray().GetAt(lControlPointIndex));
|
|
break;
|
|
case FbxGeometryElement::eIndexToDirect:
|
|
{
|
|
int id = leVtxc->GetIndexArray().GetAt(lControlPointIndex);
|
|
DisplayColor(header, leVtxc->GetDirectArray().GetAt(id));
|
|
}
|
|
break;
|
|
default:
|
|
break; // other reference modes not shown here!
|
|
}
|
|
break;
|
|
|
|
case FbxGeometryElement::eByPolygonVertex:
|
|
{
|
|
switch (leVtxc->GetReferenceMode())
|
|
{
|
|
case FbxGeometryElement::eDirect:
|
|
DisplayColor(header, leVtxc->GetDirectArray().GetAt(vertexId));
|
|
break;
|
|
case FbxGeometryElement::eIndexToDirect:
|
|
{
|
|
int id = leVtxc->GetIndexArray().GetAt(vertexId);
|
|
DisplayColor(header, leVtxc->GetDirectArray().GetAt(id));
|
|
}
|
|
break;
|
|
default:
|
|
break; // other reference modes not shown here!
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FbxGeometryElement::eByPolygon: // doesn't make much sense for UVs
|
|
case FbxGeometryElement::eAllSame: // doesn't make much sense for UVs
|
|
case FbxGeometryElement::eNone: // doesn't make much sense for UVs
|
|
break;
|
|
}
|
|
}
|
|
for (l = 0; l < pMesh->GetElementUVCount(); ++l)
|
|
{
|
|
FbxGeometryElementUV* leUV = pMesh->GetElementUV( l);
|
|
FBXSDK_sprintf(header, 100, " Texture UV: ");
|
|
|
|
switch (leUV->GetMappingMode())
|
|
{
|
|
default:
|
|
break;
|
|
case FbxGeometryElement::eByControlPoint:
|
|
switch (leUV->GetReferenceMode())
|
|
{
|
|
case FbxGeometryElement::eDirect:
|
|
Display2DVector(header, leUV->GetDirectArray().GetAt(lControlPointIndex));
|
|
break;
|
|
case FbxGeometryElement::eIndexToDirect:
|
|
{
|
|
int id = leUV->GetIndexArray().GetAt(lControlPointIndex);
|
|
Display2DVector(header, leUV->GetDirectArray().GetAt(id));
|
|
}
|
|
break;
|
|
default:
|
|
break; // other reference modes not shown here!
|
|
}
|
|
break;
|
|
|
|
case FbxGeometryElement::eByPolygonVertex:
|
|
{
|
|
int lTextureUVIndex = pMesh->GetTextureUVIndex(i, j);
|
|
switch (leUV->GetReferenceMode())
|
|
{
|
|
case FbxGeometryElement::eDirect:
|
|
case FbxGeometryElement::eIndexToDirect:
|
|
{
|
|
Display2DVector(header, leUV->GetDirectArray().GetAt(lTextureUVIndex));
|
|
}
|
|
break;
|
|
default:
|
|
break; // other reference modes not shown here!
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FbxGeometryElement::eByPolygon: // doesn't make much sense for UVs
|
|
case FbxGeometryElement::eAllSame: // doesn't make much sense for UVs
|
|
case FbxGeometryElement::eNone: // doesn't make much sense for UVs
|
|
break;
|
|
}
|
|
}
|
|
for( l = 0; l < pMesh->GetElementNormalCount(); ++l)
|
|
{
|
|
FbxGeometryElementNormal* leNormal = pMesh->GetElementNormal( l);
|
|
FBXSDK_sprintf(header, 100, " Normal: ");
|
|
|
|
if(leNormal->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
|
|
{
|
|
switch (leNormal->GetReferenceMode())
|
|
{
|
|
case FbxGeometryElement::eDirect:
|
|
Display3DVector(header, leNormal->GetDirectArray().GetAt(vertexId));
|
|
break;
|
|
case FbxGeometryElement::eIndexToDirect:
|
|
{
|
|
int id = leNormal->GetIndexArray().GetAt(vertexId);
|
|
Display3DVector(header, leNormal->GetDirectArray().GetAt(id));
|
|
}
|
|
break;
|
|
default:
|
|
break; // other reference modes not shown here!
|
|
}
|
|
}
|
|
|
|
}
|
|
for( l = 0; l < pMesh->GetElementTangentCount(); ++l)
|
|
{
|
|
FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent( l);
|
|
FBXSDK_sprintf(header, 100, " Tangent: ");
|
|
|
|
if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
|
|
{
|
|
switch (leTangent->GetReferenceMode())
|
|
{
|
|
case FbxGeometryElement::eDirect:
|
|
Display3DVector(header, leTangent->GetDirectArray().GetAt(vertexId));
|
|
break;
|
|
case FbxGeometryElement::eIndexToDirect:
|
|
{
|
|
int id = leTangent->GetIndexArray().GetAt(vertexId);
|
|
Display3DVector(header, leTangent->GetDirectArray().GetAt(id));
|
|
}
|
|
break;
|
|
default:
|
|
break; // other reference modes not shown here!
|
|
}
|
|
}
|
|
|
|
}
|
|
for( l = 0; l < pMesh->GetElementBinormalCount(); ++l)
|
|
{
|
|
|
|
FbxGeometryElementBinormal* leBinormal = pMesh->GetElementBinormal( l);
|
|
|
|
FBXSDK_sprintf(header, 100, " Binormal: ");
|
|
if(leBinormal->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
|
|
{
|
|
switch (leBinormal->GetReferenceMode())
|
|
{
|
|
case FbxGeometryElement::eDirect:
|
|
Display3DVector(header, leBinormal->GetDirectArray().GetAt(vertexId));
|
|
break;
|
|
case FbxGeometryElement::eIndexToDirect:
|
|
{
|
|
int id = leBinormal->GetIndexArray().GetAt(vertexId);
|
|
Display3DVector(header, leBinormal->GetDirectArray().GetAt(id));
|
|
}
|
|
break;
|
|
default:
|
|
break; // other reference modes not shown here!
|
|
}
|
|
}
|
|
}
|
|
vertexId++;
|
|
} // for polygonSize
|
|
} // for polygonCount
|
|
|
|
|
|
//check visibility for the edges of the mesh
|
|
for(int l = 0; l < pMesh->GetElementVisibilityCount(); ++l)
|
|
{
|
|
FbxGeometryElementVisibility* leVisibility=pMesh->GetElementVisibility(l);
|
|
FBXSDK_sprintf(header, 100, " Edge Visibility : ");
|
|
DisplayString(header);
|
|
switch(leVisibility->GetMappingMode())
|
|
{
|
|
default:
|
|
break;
|
|
//should be eByEdge
|
|
case FbxGeometryElement::eByEdge:
|
|
//should be eDirect
|
|
for(j=0; j!=pMesh->GetMeshEdgeCount();++j)
|
|
{
|
|
DisplayInt(" Edge ", j);
|
|
DisplayBool(" Edge visibility: ", leVisibility->GetDirectArray().GetAt(j));
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
DisplayString("");
|
|
}
|
|
|
|
void DisplayTextureNames( FbxProperty &pProperty, FbxString& pConnectionString )
|
|
{
|
|
int lLayeredTextureCount = pProperty.GetSrcObjectCount<FbxLayeredTexture>();
|
|
if(lLayeredTextureCount > 0)
|
|
{
|
|
for(int j=0; j<lLayeredTextureCount; ++j)
|
|
{
|
|
FbxLayeredTexture *lLayeredTexture = pProperty.GetSrcObject<FbxLayeredTexture>(j);
|
|
int lNbTextures = lLayeredTexture->GetSrcObjectCount<FbxTexture>();
|
|
pConnectionString += " Texture ";
|
|
|
|
for(int k =0; k<lNbTextures; ++k)
|
|
{
|
|
//lConnectionString += k;
|
|
pConnectionString += "\"";
|
|
pConnectionString += (char*)lLayeredTexture->GetName();
|
|
pConnectionString += "\"";
|
|
pConnectionString += " ";
|
|
}
|
|
pConnectionString += "of ";
|
|
pConnectionString += pProperty.GetName();
|
|
pConnectionString += " on layer ";
|
|
pConnectionString += j;
|
|
}
|
|
pConnectionString += " |";
|
|
}
|
|
else
|
|
{
|
|
//no layered texture simply get on the property
|
|
int lNbTextures = pProperty.GetSrcObjectCount<FbxTexture>();
|
|
|
|
if(lNbTextures > 0)
|
|
{
|
|
pConnectionString += " Texture ";
|
|
pConnectionString += " ";
|
|
|
|
for(int j =0; j<lNbTextures; ++j)
|
|
{
|
|
FbxTexture* lTexture = pProperty.GetSrcObject<FbxTexture>(j);
|
|
if(lTexture)
|
|
{
|
|
pConnectionString += "\"";
|
|
pConnectionString += (char*)lTexture->GetName();
|
|
pConnectionString += "\"";
|
|
pConnectionString += " ";
|
|
}
|
|
}
|
|
pConnectionString += "of ";
|
|
pConnectionString += pProperty.GetName();
|
|
pConnectionString += " |";
|
|
}
|
|
}
|
|
}
|
|
|
|
void DisplayMaterialTextureConnections( FbxSurfaceMaterial* pMaterial, char * header, int pMatId, int l )
|
|
{
|
|
if(!pMaterial)
|
|
return;
|
|
|
|
FbxString lConnectionString = " Material %d -- ";
|
|
//Show all the textures
|
|
|
|
FbxProperty lProperty;
|
|
//Diffuse Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//DiffuseFactor Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuseFactor);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//Emissive Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sEmissive);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//EmissiveFactor Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sEmissiveFactor);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
|
|
//Ambient Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sAmbient);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//AmbientFactor Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sAmbientFactor);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//Specular Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecular);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//SpecularFactor Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecularFactor);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//Shininess Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sShininess);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//Bump Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sBump);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//Normal Map Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sNormalMap);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//Transparent Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sTransparentColor);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//TransparencyFactor Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//Reflection Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sReflection);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//ReflectionFactor Textures
|
|
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sReflectionFactor);
|
|
DisplayTextureNames(lProperty, lConnectionString);
|
|
|
|
//Update header with material info
|
|
bool lStringOverflow = (lConnectionString.GetLen() + 10 >= MAT_HEADER_LENGTH); // allow for string length and some padding for "%d"
|
|
if (lStringOverflow)
|
|
{
|
|
// Truncate string!
|
|
lConnectionString = lConnectionString.Left(MAT_HEADER_LENGTH - 10);
|
|
lConnectionString = lConnectionString + "...";
|
|
}
|
|
FBXSDK_sprintf(header, MAT_HEADER_LENGTH, lConnectionString.Buffer(), pMatId, l);
|
|
DisplayString(header);
|
|
}
|
|
|
|
void DisplayMaterialConnections(FbxMesh* pMesh)
|
|
{
|
|
int i, l, lPolygonCount = pMesh->GetPolygonCount();
|
|
|
|
char header[MAT_HEADER_LENGTH];
|
|
|
|
DisplayString(" Polygons Material Connections");
|
|
|
|
//check whether the material maps with only one mesh
|
|
bool lIsAllSame = true;
|
|
for (l = 0; l < pMesh->GetElementMaterialCount(); l++)
|
|
{
|
|
|
|
FbxGeometryElementMaterial* lMaterialElement = pMesh->GetElementMaterial(l);
|
|
if( lMaterialElement->GetMappingMode() == FbxGeometryElement::eByPolygon)
|
|
{
|
|
lIsAllSame = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//For eAllSame mapping type, just out the material and texture mapping info once
|
|
if(lIsAllSame)
|
|
{
|
|
for (l = 0; l < pMesh->GetElementMaterialCount(); l++)
|
|
{
|
|
|
|
FbxGeometryElementMaterial* lMaterialElement = pMesh->GetElementMaterial( l);
|
|
if( lMaterialElement->GetMappingMode() == FbxGeometryElement::eAllSame)
|
|
{
|
|
FbxSurfaceMaterial* lMaterial = pMesh->GetNode()->GetMaterial(lMaterialElement->GetIndexArray().GetAt(0));
|
|
int lMatId = lMaterialElement->GetIndexArray().GetAt(0);
|
|
if(lMatId >= 0)
|
|
{
|
|
DisplayInt(" All polygons share the same material in mesh ", l);
|
|
DisplayMaterialTextureConnections(lMaterial, header, lMatId, l);
|
|
}
|
|
}
|
|
}
|
|
|
|
//no material
|
|
if(l == 0)
|
|
DisplayString(" no material applied");
|
|
}
|
|
|
|
//For eByPolygon mapping type, just out the material and texture mapping info once
|
|
else
|
|
{
|
|
for (i = 0; i < lPolygonCount; i++)
|
|
{
|
|
DisplayInt(" Polygon ", i);
|
|
|
|
for (l = 0; l < pMesh->GetElementMaterialCount(); l++)
|
|
{
|
|
|
|
FbxGeometryElementMaterial* lMaterialElement = pMesh->GetElementMaterial( l);
|
|
FbxSurfaceMaterial* lMaterial = NULL;
|
|
int lMatId = -1;
|
|
lMaterial = pMesh->GetNode()->GetMaterial(lMaterialElement->GetIndexArray().GetAt(i));
|
|
lMatId = lMaterialElement->GetIndexArray().GetAt(i);
|
|
|
|
if(lMatId >= 0)
|
|
{
|
|
DisplayMaterialTextureConnections(lMaterial, header, lMatId, l);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void DisplayMaterialMapping(FbxMesh* pMesh)
|
|
{
|
|
const char* lMappingTypes[] = { "None", "By Control Point", "By Polygon Vertex", "By Polygon", "By Edge", "All Same" };
|
|
const char* lReferenceMode[] = { "Direct", "Index", "Index to Direct"};
|
|
|
|
int lMtrlCount = 0;
|
|
FbxNode* lNode = NULL;
|
|
if(pMesh){
|
|
lNode = pMesh->GetNode();
|
|
if(lNode)
|
|
lMtrlCount = lNode->GetMaterialCount();
|
|
}
|
|
|
|
for (int l = 0; l < pMesh->GetElementMaterialCount(); l++)
|
|
{
|
|
FbxGeometryElementMaterial* leMat = pMesh->GetElementMaterial( l);
|
|
if (leMat)
|
|
{
|
|
char header[100];
|
|
FBXSDK_sprintf(header, 100, " Material Element %d: ", l);
|
|
DisplayString(header);
|
|
|
|
|
|
DisplayString(" Mapping: ", lMappingTypes[leMat->GetMappingMode()]);
|
|
DisplayString(" ReferenceMode: ", lReferenceMode[leMat->GetReferenceMode()]);
|
|
|
|
int lMaterialCount = 0;
|
|
FbxString lString;
|
|
|
|
if (leMat->GetReferenceMode() == FbxGeometryElement::eDirect ||
|
|
leMat->GetReferenceMode() == FbxGeometryElement::eIndexToDirect)
|
|
{
|
|
lMaterialCount = lMtrlCount;
|
|
}
|
|
|
|
if (leMat->GetReferenceMode() == FbxGeometryElement::eIndex ||
|
|
leMat->GetReferenceMode() == FbxGeometryElement::eIndexToDirect)
|
|
{
|
|
int i;
|
|
|
|
lString = " Indices: ";
|
|
|
|
int lIndexArrayCount = leMat->GetIndexArray().GetCount();
|
|
for (i = 0; i < lIndexArrayCount; i++)
|
|
{
|
|
lString += leMat->GetIndexArray().GetAt(i);
|
|
|
|
if (i < lIndexArrayCount - 1)
|
|
{
|
|
lString += ", ";
|
|
}
|
|
}
|
|
|
|
lString += "\n";
|
|
|
|
FBXSDK_printf(lString);
|
|
}
|
|
}
|
|
}
|
|
|
|
DisplayString("");
|
|
}
|