00001 #ifndef IMPORT_FBX
00002 #define IMPORT_FBX
00003
00004 #include<vcg/complex/allocate.h>
00005 #include <wrap/callback.h>
00006 #include <wrap/io_trimesh/io_mask.h>
00007 #include <wrap/io_trimesh/io_material.h>
00008 #include <vcg/space/color4.h>
00009 #include <fbxsdk.h>
00010 #include <vcg/complex/algorithms/update/bounding.h>
00011 #include <fstream>
00012 #include <string>
00013 #include <vector>
00014 #include <cmath>
00015 #include <map>
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 template <class OpenMeshType>
00026 class ImporterFBX
00027 {
00028 public:
00029
00030 class Info
00031 {
00032 public:
00033
00034 Info()
00035 {
00036 mask = 0;
00037 cb = 0;
00038 numVertices = 0;
00039 numFaces = 0;
00040 numMeshPatches = 0;
00041 }
00042
00044 int mask;
00045
00047
00048 vcg::CallBackPos *cb;
00049
00051 int numVertices;
00054 int numFaces;
00056 int numMeshPatches;
00057
00058 };
00059
00060 typedef typename OpenMeshType::VertexPointer VertexPointer;
00061 typedef typename OpenMeshType::ScalarType ScalarType;
00062 typedef typename OpenMeshType::VertexType VertexType;
00063 typedef typename OpenMeshType::FaceType FaceType;
00064 typedef typename OpenMeshType::VertexIterator VertexIterator;
00065 typedef typename OpenMeshType::FaceIterator FaceIterator;
00066 typedef typename OpenMeshType::CoordType CoordType;
00067 typedef typename OpenMeshType::VertexType::ColorType ColorType;
00068 typedef typename OpenMeshType::VertexType::ColorType::ScalarType CSType;
00069 private:
00070 class VCGMaterialBridge
00071 {
00072 private:
00073
00074 void insertMaterialInfoAndTextureName(KFbxSurfaceMaterial& mat,const char* colorAttributeName,OpenMeshType& m)
00075 {
00076 MaterialInfo matinfo;
00077 matinfo.setSurfaceMaterial(&mat);
00078
00079
00080 KFbxFileTexture* tex = matinfo.getTextureFileObject(colorAttributeName);
00081 if(tex)
00082 {
00083 const char* texfile = tex->GetFileName();
00084 std::vector<std::string>::iterator it = std::find(m.textures.begin(),m.textures.end(),texfile);
00085 if (it == m.textures.end())
00086 {
00087 m.textures.push_back(texfile);
00088 matinfo.setTextureIndex(m.textures.size() - 1);
00089 }
00090 else
00091 {
00092 int dist = int(std::distance(m.textures.begin(),it));
00093 matinfo.setTextureIndex(dist);
00094 }
00095 }
00096 else
00097 {
00098 if (mat.GetClassId().Is(KFbxSurfaceLambert::ClassId))
00099 {
00100 KFbxPropertyDouble3 diffProp = ((KFbxSurfaceLambert* ) (&mat))->Diffuse;
00101 fbxDouble3 diffCol = diffProp.Get();
00102 vcg::Color4b tmpc = vcg::Color4b(diffCol[0] * 255,diffCol[1] * 255,diffCol[2] * 255,255);
00103 matinfo.setColor(tmpc);
00104 }
00105 }
00106 material[colorAttributeName] = matinfo;
00107 }
00108 public:
00109
00110
00111 VCGMaterialBridge(OpenMeshType& m,KFbxSurfaceMaterial& mat)
00112 :material()
00113 {
00114 insertMaterialInfoAndTextureName(mat,KFbxSurfaceMaterial::sDiffuse,m);
00115 }
00116
00117 class MaterialInfo
00118 {
00119 private:
00120 int textindex;
00121 ColorType color;
00122 bool hascolor;
00123 KFbxSurfaceMaterial* surfMat;
00124 public:
00125 MaterialInfo():hascolor(false),textindex(-1),surfMat(NULL){}
00126 void setColor(const ColorType& col) {color = col;hascolor= true;}
00127 void setTextureIndex(const int i) {textindex = i;}
00128 bool hasColor() const {return hascolor;}
00129 bool hasTexture() const {return (textindex != -1);}
00130 int getTextureIndex() const {return textindex;}
00131 KFbxSurfaceMaterial* getSurfaceMaterial() const {return surfMat;}
00132 void setSurfaceMaterial(KFbxSurfaceMaterial* mat) {surfMat = mat;}
00133 KFbxFileTexture* getTextureFileObject (const char* attributeName)
00134 {
00135 if (surfMat)
00136 {
00137 KFbxProperty prop = surfMat->FindProperty(attributeName);
00138 if(prop.IsValid())
00139 {
00140 int texnum = prop.GetSrcObjectCount(KFbxTexture::ClassId);
00141
00142 if (texnum > 0)
00143 return KFbxCast <KFbxFileTexture> (prop.GetSrcObject(KFbxTexture::ClassId,0));
00144 else
00145 return NULL;
00146 }
00147 }
00148 return NULL;
00149 }
00150
00151 ColorType getColor() const {return color;}
00152 };
00153
00154 MaterialInfo* getMaterial(const char* attr)
00155 {
00156 typename std::map<const char*,MaterialInfo>::iterator it = material.find(attr);
00157 if (it != material.end())
00158 return &(it->second);
00159 return NULL;
00160 }
00161
00162 private:
00163 std::map<const char*,MaterialInfo> material;
00164 };
00165
00166 static int ImportNode(OpenMeshType& m,KFbxNode* node,KFbxPose* pose,KFbxXMatrix* globPosMat,Info &oi)
00167 {
00168 int result = E_NOERROR;
00169 if (node)
00170 {
00171 KFbxXMatrix mat = getGlobalMatrix(node, KTime(), pose, globPosMat);
00172
00173
00174 KFbxNodeAttribute* attr = node->GetNodeAttribute();
00175 if (attr != NULL)
00176 {
00177 KFbxNodeAttribute::EAttributeType att = attr->GetAttributeType();
00178 if (attr->GetAttributeType() == KFbxNodeAttribute::eMESH)
00179 {
00180 KFbxXMatrix geoOff = GetGeometry(node);
00181 KFbxXMatrix final = mat * geoOff;
00182
00183 result = ImportMesh(m,node,final,oi);
00184 }
00185
00186 }
00187 for(int ii = 0;ii < node->GetChildCount();++ii)
00188 ImportNode(m,node->GetChild(ii),pose,&mat,oi);
00189 }
00190 return result;
00191 }
00192
00193 static int ImportScene(OpenMeshType& m,KFbxScene* scene,Info &oi)
00194 {
00195 scene->ConnectTextures();
00196 KFbxPose* pose = NULL;
00197 int ii = scene->GetPoseCount();
00198 if (ii > 0)
00199 pose = scene->GetPose(ii-1);
00200
00201 KFbxNode* node = scene->GetRootNode();
00202 int result = E_NOERROR;
00203 KFbxXMatrix globPosMat;
00204 for (int ii = 0; ii < scene->GetRootNode()->GetChildCount(); ++ii)
00205 result = ImportNode(m,scene->GetRootNode()->GetChild(ii),pose,&globPosMat,oi);
00206 return result;
00207 }
00208
00209 static int ImportMesh(OpenMeshType& m,KFbxNode* node,const KFbxXMatrix& mat,Info& oi)
00210 {
00211 KFbxMesh* newMesh = node->GetMesh();
00212 if (!newMesh->IsTriangleMesh())
00213 {
00214 KFbxGeometryConverter* conv = new KFbxGeometryConverter(newMesh->GetFbxSdkManager());
00215 newMesh = conv->TriangulateMesh(newMesh);
00216 }
00217
00218 vcg::Matrix44<ScalarType> mat2;
00219 for(int ll = 0;ll < 4;++ll)
00220 for(int vv = 0;vv < 4;++vv)
00221 mat2[ll][vv] = mat[vv][ll];
00222
00223
00224 vcg::Matrix33<ScalarType> matnorm;
00225 for(int ll = 0;ll < 3;++ll)
00226 for(int vv = 0;vv < 3;++vv)
00227 matnorm[ll][vv] = mat[vv][ll];
00228
00229 int matnum = node->GetSrcObjectCount(KFbxSurfaceMaterial::ClassId);
00230 KFbxLayerElementArrayTemplate< int >* matarr = NULL;
00231 bool found = newMesh->GetMaterialIndices(&matarr);
00232
00233 std::vector<VCGMaterialBridge> matAtlas;
00234 for (int matind = 0; matind < matnum; ++matind)
00235 {
00236 KFbxSurfaceMaterial *mater = KFbxCast <KFbxSurfaceMaterial>(node->GetSrcObject(KFbxSurfaceMaterial::ClassId, matind));
00237 matAtlas.push_back(VCGMaterialBridge(m,*mater));
00238 }
00239 size_t vertDispl = m.vert.size();
00240 int currmeshvert = newMesh->GetControlPointsCount();
00241 vcg::tri::Allocator<OpenMeshType>::AddVertices(m,currmeshvert);
00242 int currmeshface = newMesh->GetPolygonCount();
00243 size_t faceDispl = m.face.size();
00244 vcg::tri::Allocator<OpenMeshType>::AddFaces(m,currmeshface);
00245 KFbxVector4* posVert = newMesh->GetControlPoints();
00246 KFbxLayerElementArrayTemplate<KFbxVector2>* UVArr = NULL;
00247 int uvparcount = newMesh->GetElementUVCount();
00248
00249 KFbxLayer* lnorm = newMesh->GetLayer(0,KFbxLayerElement::eNORMAL);
00250 KFbxLayerElementNormal* normalLayer = NULL;
00251 if (lnorm)
00252 normalLayer = lnorm->GetNormals();
00253 KFbxLayerElement::EMappingMode normalMapMode = KFbxLayerElement::eNONE;
00254 if (normalLayer)
00255 normalMapMode = normalLayer->GetMappingMode();
00256 KFbxLayer* lcol = newMesh->GetLayer(0,KFbxLayerElement::eVERTEX_COLOR);
00257 KFbxLayerElementVertexColor* colorLayer = NULL;
00258 if (lcol)
00259 colorLayer = lcol->GetVertexColors();
00260 KFbxLayerElement::EMappingMode colorMapMode = KFbxLayerElement::eNONE;
00261 if (colorLayer)
00262 colorMapMode = colorLayer->GetMappingMode();
00263
00264 newMesh->GetTextureUV(&UVArr, KFbxLayerElement::eDIFFUSE_TEXTURES);
00265
00266 int numFacPlusVert = oi.numFaces + oi.numVertices;
00267 float det = mat2.Determinant();
00268 bool invert = (det< 0.0);
00269 for(int ii = 0;ii < currmeshvert;++ii)
00270 {
00271
00272 ScalarType a = ScalarType(posVert[ii][0]);
00273 ScalarType b = ScalarType(posVert[ii][1]);
00274 ScalarType c = ScalarType(posVert[ii][2]);
00275 vcg::Point4<ScalarType> fbxpos(a,b,c,ScalarType(1.0));
00276 fbxpos = mat2 * fbxpos;
00277 CoordType t(fbxpos[0],fbxpos[1],fbxpos[2]);
00278 m.vert[ii + vertDispl].P() = t;
00279
00280 if (vcg::tri::HasPerVertexNormal(m) && (normalLayer) && (normalMapMode == KFbxLayerElement::eBY_CONTROL_POINT))
00281 {
00282 KFbxVector4 n;
00283 int normInd = -1;
00284 switch(normalLayer->GetReferenceMode())
00285 {
00286 case (KFbxLayerElement::eDIRECT):
00287 {
00288 normInd = ii;
00289 break;
00290 }
00291 case (KFbxLayerElement::eINDEX_TO_DIRECT):
00292 {
00293 normInd = normalLayer->GetIndexArray()[ii];
00294 break;
00295 }
00296 }
00297 n = normalLayer->GetDirectArray()[normInd];
00298 CoordType nn(n[0],n[1],n[2]);
00299 nn = (matnorm * nn);
00300
00301 nn.Normalize();
00302
00303
00304 m.vert[ii + vertDispl].N() = nn;
00305 }
00306 if (vcg::tri::HasPerVertexColor(m) && (colorLayer) && (colorMapMode == KFbxLayerElement::eBY_CONTROL_POINT))
00307 {
00308 KFbxColor c;
00309 int colorInd = -1;
00310 switch(colorLayer->GetReferenceMode())
00311 {
00312 case (KFbxLayerElement::eDIRECT):
00313 {
00314 colorInd = ii;
00315 break;
00316 }
00317 case (KFbxLayerElement::eINDEX_TO_DIRECT):
00318 {
00319 colorInd = colorLayer->GetIndexArray()[ii];
00320 break;
00321 }
00322 }
00323 c = colorLayer->GetDirectArray()[colorInd];
00324 vcg::Color4b vcgcol(c[0] * 255,c[1] * 255,c[2] * 255,c[3] * 255);
00325 m.vert[ii + vertDispl].C() = vcgcol;
00326 }
00327 }
00328
00329 int* index = newMesh->GetPolygonVertices();
00330 bool allsame = false;
00331 int matarrsize = -1;
00332 if (matarr)
00333 matarrsize = matarr->GetCount();
00334 if (matarrsize == 1)
00335 allsame = true;
00336
00337 for(int ii = 0;ii < currmeshface;++ii)
00338 {
00339 int diffusematind = -1;
00340 int matptr = -1;
00341 typename VCGMaterialBridge::MaterialInfo* mymat = NULL;
00342 if (matAtlas.size() > 0)
00343 {
00344 if ((!allsame) && (matarrsize == currmeshface))
00345 matptr = (*matarr)[ii];
00346 else
00347 {
00348 if (allsame)
00349 {
00350 matptr = (*matarr)[0];
00351 }
00352 }
00353 if ((matptr >= 0) && (matptr < matAtlas.size()))
00354 {
00355 mymat = matAtlas[matptr].getMaterial(KFbxSurfaceMaterial::sDiffuse);
00356 if (mymat && mymat->hasTexture())
00357 diffusematind = mymat->getTextureIndex();
00358 }
00359 else
00360 if (matptr == node->GetMaterialCount())
00361 {
00362 mymat = matAtlas[matptr-1].getMaterial(KFbxSurfaceMaterial::sDiffuse);
00363 if (mymat && mymat->hasTexture())
00364 diffusematind = mymat->getTextureIndex();
00365 }
00366 }
00367 for (int jj = 0;jj < 3;++jj)
00368 {
00369 VertexIterator mov = m.vert.begin();
00370 std::advance(mov,index[ii * 3 + jj] + vertDispl);
00371 int invind = (3 - jj) % 3;
00372 if (!invert)
00373 m.face[ii + faceDispl].V(jj) = &(*mov);
00374 else
00375 m.face[ii + faceDispl].V(invind) = &(*mov);
00376 if (vcg::tri::HasPerWedgeTexCoord(m) && (uvparcount > 0) && mymat && mymat->hasTexture())
00377 {
00378 int texind = -1;
00379 KFbxLayerElement::EReferenceMode mapmode = newMesh->GetElementUV(0)->GetReferenceMode();
00380 if (mapmode == KFbxLayerElement::eINDEX_TO_DIRECT)
00381 texind = newMesh->GetTextureUVIndex(ii,jj);
00382 else
00383 if (mapmode == KFbxLayerElement::eDIRECT)
00384 texind = ii * 3 + jj;
00385 if (UVArr)
00386 {
00387
00388 KFbxVector2 texcoord = UVArr->GetAt(texind);
00389 if (!invert)
00390 {
00391 m.face[ii + faceDispl].WT(jj).U() = ScalarType(texcoord[0]);
00392 m.face[ii + faceDispl].WT(jj).V() = ScalarType(texcoord[1]);
00393 m.face[ii + faceDispl].WT(jj).N() = diffusematind;
00394 }
00395 else
00396 {
00397 m.face[ii + faceDispl].WT(invind).U() = ScalarType(texcoord[0]);
00398 m.face[ii + faceDispl].WT(invind).V() = ScalarType(texcoord[1]);
00399 m.face[ii + faceDispl].WT(invind).N() = diffusematind;
00400 }
00401 }
00402 }
00403
00404 else
00405 if (vcg::tri::HasPerVertexColor(m) && mymat && mymat->hasColor())
00406 {
00407 if (!invert)
00408 m.face[ii + faceDispl].V(jj)->C() = mymat->getColor();
00409 else
00410 m.face[ii + faceDispl].V(invind)->C() = mymat->getColor();
00411 }
00412 }
00413 if (oi.cb)
00414 {
00415 char numstr[33];
00416 sprintf(numstr,"%d",oi.numMeshPatches);
00417 std::string st("Loading Vertices and Faces from ");
00418 st = st + numstr + " submeshes";
00419 oi.cb( (100*(m.vert.size() +m.face.size()))/ numFacPlusVert, st.c_str());
00420 }
00421 }
00422
00423
00424 return E_NOERROR;
00425 }
00426
00427 static void LoadMaskNode(KFbxNode* node, Info &oi)
00428 {
00429 if (node)
00430 {
00431 KFbxNodeAttribute* attr = node->GetNodeAttribute();
00432 if (attr != NULL)
00433 {
00434 KFbxNodeAttribute::EAttributeType att = attr->GetAttributeType();
00435 if (attr->GetAttributeType() == KFbxNodeAttribute::eMESH)
00436 {
00437 int matnum = node->GetSrcObjectCount(KFbxSurfaceMaterial::ClassId);
00438 KFbxMesh* newMesh = node->GetMesh();
00439 int uvparcount = newMesh->GetElementUVCount();
00440 if (uvparcount > 0)
00441 oi.mask |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
00442
00443 KFbxLayer* lcolo = newMesh->GetLayer(0,KFbxLayerElement::eVERTEX_COLOR);
00444 if (matnum || lcolo)
00445 oi.mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
00446 KFbxLayer* lnorm = newMesh->GetLayer(0,KFbxLayerElement::eNORMAL);
00447 KFbxLayerElementNormal* nnom = lnorm->GetNormals();
00448 if (lnorm)
00449 oi.mask |= vcg::tri::io::Mask::IOM_VERTNORMAL;
00450 oi.numVertices = oi.numVertices + newMesh->GetControlPointsCount();
00451 if (!newMesh->IsTriangleMesh())
00452 {
00453 KFbxGeometryConverter* conv = new KFbxGeometryConverter(newMesh->GetFbxSdkManager());
00454 newMesh = conv->TriangulateMesh(newMesh);
00455 }
00456 oi.numFaces = oi.numFaces + newMesh->GetPolygonCount();
00457 oi.numMeshPatches += 1;
00458 }
00459 }
00460 for(int ii = 0;ii < node->GetChildCount();++ii)
00461 LoadMaskNode(node->GetChild(ii),oi);
00462 }
00463 }
00464
00465 static KFbxXMatrix getGlobalMatrix(KFbxNode* pNode, const KTime& pTime, KFbxPose* pPose, KFbxXMatrix* pParentGlobalPosition = NULL)
00466 {
00467 KFbxXMatrix lGlobalPosition;
00468 bool lPositionFound = false;
00469
00470 if (pPose)
00471 {
00472 int lNodeIndex = pPose->Find(pNode);
00473
00474 if (lNodeIndex > -1)
00475 {
00476 if (pPose->IsBindPose() || !pPose->IsLocalMatrix(lNodeIndex))
00477 {
00478 lGlobalPosition = GetPoseMatrix(pPose, lNodeIndex);
00479 }
00480 else
00481 {
00482 KFbxXMatrix lParentGlobalPosition;
00483
00484 if (pParentGlobalPosition)
00485 {
00486 lParentGlobalPosition = *pParentGlobalPosition;
00487 }
00488 else
00489 {
00490 if (pNode->GetParent())
00491 {
00492 lParentGlobalPosition = getGlobalMatrix(pNode->GetParent(), pTime, pPose);
00493 }
00494 }
00495
00496 KFbxXMatrix lLocalPosition = GetPoseMatrix(pPose, lNodeIndex);
00497 lGlobalPosition = lParentGlobalPosition * lLocalPosition;
00498 }
00499
00500 lPositionFound = true;
00501 }
00502 }
00503
00504 if (!lPositionFound)
00505 {
00506 lGlobalPosition = pNode->EvaluateGlobalTransform(pTime);
00507 }
00508
00509 return lGlobalPosition;
00510 }
00511
00512 static KFbxXMatrix GetPoseMatrix(KFbxPose* pPose, int pNodeIndex)
00513 {
00514 KFbxXMatrix lPoseMatrix;
00515 KFbxMatrix lMatrix = pPose->GetMatrix(pNodeIndex);
00516
00517 memcpy((double*)lPoseMatrix, (double*)lMatrix, sizeof(lMatrix.mData));
00518
00519 return lPoseMatrix;
00520 }
00521
00522 static KFbxXMatrix GetGeometry(KFbxNode* pNode)
00523 {
00524 const KFbxVector4 lT = pNode->GetGeometricTranslation(KFbxNode::eSOURCE_SET);
00525 const KFbxVector4 lR = pNode->GetGeometricRotation(KFbxNode::eSOURCE_SET);
00526 const KFbxVector4 lS = pNode->GetGeometricScaling(KFbxNode::eSOURCE_SET);
00527
00528 return KFbxXMatrix(lT, lR, lS);
00529 }
00530
00531 public:
00532
00533
00534
00535 enum FBXError
00536 {
00537
00538 E_NOERROR = 0,
00539
00540
00541 E_CANTCREATEFBXMANAGER = 1,
00542 E_CANTCREATEFBXSCENE = 2,
00543 E_CANTCREATEFBXIMPORTER = 3,
00544 E_CANTFINDFILE = 4,
00545 E_CANTFINDFBXFILE = 5,
00546 E_CANTIMPORTFBXFILE = 6
00547 };
00548
00549
00550
00551
00552 static bool ErrorCritical(int err)
00553 {
00554 if(err == E_NOERROR)
00555 return false;
00556 return true;
00557 }
00558
00559
00560
00561
00562 static const char* ErrorMsg(int error)
00563 {
00564 static const char* fbx_error_msg[] =
00565 {
00566 "No errors",
00567
00568 "Failed to create a KFbxSdkManager",
00569 "Failed to create a KFbxScene",
00570 "Failed to create a KFbxImporter",
00571 "Failed to locate requested file",
00572 "Failed to import requested file",
00573 };
00574
00575 if(error>6 || error<0)
00576 return "Unknown error";
00577 else
00578 return fbx_error_msg[error];
00579 };
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 static int Open( OpenMeshType &m, const char * filename, Info &oi)
00603 {
00604 int result = E_NOERROR;
00605 m.Clear();
00606 vcg::CallBackPos *cb = oi.cb;
00607
00608 KFbxSdkManager* FBXmanager = KFbxSdkManager::Create();
00609 if (FBXmanager==NULL)
00610 return E_CANTCREATEFBXMANAGER;
00611 KFbxScene* FBXscene = KFbxScene::Create(FBXmanager,"");
00612 if (FBXscene==NULL)
00613 return E_CANTCREATEFBXSCENE;
00614 KFbxImporter* importer = KFbxImporter::Create(FBXmanager,"");
00615 if (importer==NULL)
00616 return E_CANTCREATEFBXIMPORTER;
00617
00618 bool initfile = importer->Initialize(filename);
00619 if (!initfile)
00620 {
00621 printf("Fbx error: %s",importer->GetLastErrorString());
00622 return E_CANTFINDFBXFILE;
00623 }
00624 bool importfile = importer->Import(FBXscene);
00625 if (!importfile)
00626 {
00627 printf("Fbx error: %s",importer->GetLastErrorString());
00628 return E_CANTIMPORTFBXFILE;
00629 }
00630 result = ImportScene(m,FBXscene,oi);
00631
00632
00633
00634 if (FBXmanager)
00635 FBXmanager->Destroy();
00636 return result;
00637 }
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 static int LoadMask(const char * filename, Info &oi)
00651 {
00652 KFbxSdkManager* FBXmanager = KFbxSdkManager::Create();
00653 if (FBXmanager==NULL)
00654 return E_CANTCREATEFBXMANAGER;
00655 KFbxScene* FBXscene = KFbxScene::Create(FBXmanager,"");
00656 if (FBXscene==NULL)
00657 return E_CANTCREATEFBXSCENE;
00658 KFbxImporter* importer = KFbxImporter::Create(FBXmanager,"");
00659 if (importer==NULL)
00660 return E_CANTCREATEFBXIMPORTER;
00661
00662 bool initfile = importer->Initialize(filename);
00663 if (!initfile)
00664 {
00665 printf("Fbx error: %s",importer->GetLastErrorString());
00666 return E_CANTFINDFBXFILE;
00667 }
00668 bool importfile = importer->Import(FBXscene);
00669 if (!importfile)
00670 {
00671 printf("Fbx error: %s",importer->GetLastErrorString());
00672 return E_CANTIMPORTFBXFILE;
00673 }
00674 LoadMaskNode(FBXscene->GetRootNode(),oi);
00675
00676
00677
00678 if (FBXmanager)
00679 FBXmanager->Destroy();
00680 return E_NOERROR;
00681 }
00682
00683 };
00684
00685
00686 #endif