CC_FILE_ERROR FBXFilter::saveToFile(ccHObject* entity, QString filename, SaveParameters& parameters) { if (!entity) return CC_FERR_BAD_ARGUMENT; std::vector<ccGenericMesh*> meshes; if (entity->isKindOf(CC_TYPES::MESH)) { meshes.push_back(static_cast<ccGenericMesh*>(entity)); } else if (entity->isA(CC_TYPES::HIERARCHY_OBJECT)) { for (unsigned i=0; i<entity->getChildrenNumber(); ++i) { ccHObject* child = entity->getChild(i); if (child->isKindOf(CC_TYPES::MESH)) meshes.push_back(static_cast<ccGenericMesh*>(child)); } } if (meshes.empty()) { return CC_FERR_NO_SAVE; } //The first thing to do is to create the FBX Manager which is the object allocator for almost all the classes in the SDK FbxManager* lSdkManager = FbxManager::Create(); if( !lSdkManager ) { ccLog::Warning("[FBX] Error: Unable to create FBX Manager!"); return CC_FERR_CONSOLE_ERROR; } else { ccLog::Print("[FBX] Autodesk FBX SDK version %s", lSdkManager->GetVersion()); } try { //Create an IOSettings object. This object holds all import/export settings. FbxIOSettings* ios = FbxIOSettings::Create(lSdkManager, IOSROOT); lSdkManager->SetIOSettings(ios); //Load plugins from the executable directory (optional) //FbxString lPath = FbxGetApplicationDirectory(); //lSdkManager->LoadPluginsDirectory(lPath.Buffer()); //Create an FBX scene. This object holds most objects imported/exported from/to files. FbxScene* lScene = FbxScene::Create(lSdkManager, "My Scene"); if( !lScene ) { ccLog::Warning("[FBX] Error: Unable to create FBX scene!"); return CC_FERR_CONSOLE_ERROR; } // create scene info { FbxDocumentInfo* sceneInfo = FbxDocumentInfo::Create(lSdkManager,"SceneInfo"); sceneInfo->mTitle = qPrintable(QString("Mesh: ") + (meshes.size() == 1 ? meshes[0]->getName() : QString("Multiple meshes"))); sceneInfo->mAuthor = "CloudCompare"; sceneInfo->mRevision = "rev. 1.0"; sceneInfo->mKeywords = "cloudcompare mesh"; // we need to add the sceneInfo before calling AddThumbNailToScene because // that function is asking the scene for the sceneInfo. lScene->SetSceneInfo(sceneInfo); } //create thumbnail //{ // FbxThumbnail* lThumbnail = FbxThumbnail::Create(lScene,""); // lThumbnail->SetDataFormat(FbxThumbnail::eRGB_24); // lThumbnail->SetSize(FbxThumbnail::e64x64); // lThumbnail->SetThumbnailImage(cSceneThumbnail); // if (lScene->GetSceneInfo()) // { // lScene->GetSceneInfo()->SetSceneThumbnail(lThumbnail); // } //} // Build the node tree. FbxNode* lRootNode = lScene->GetRootNode(); { for (size_t i=0; i<meshes.size(); ++i) { FbxNode* meshNode = ToFbxMesh(meshes[i],lScene,filename,i); if (meshNode) lRootNode->AddChild(meshNode); else ccLog::Warning(QString("[FBX] Failed to convert mesh '%1' to FBX mesh/node!").arg(meshes[i]->getName())); } } int fileFormat = -1; //Display a combox box to let the user choose the export file format { FbxManager* pSdkManager = FbxManager::GetDefaultManager(); int lFormatCount = pSdkManager ? pSdkManager->GetIOPluginRegistry()->GetWriterFormatCount() : 0; if (lFormatCount > 0) { if (s_defaultOutputFormat.isEmpty()) { try { QMessageBox msgBox(QMessageBox::Question,"FBX format","Choose output format:"); QMap<QAbstractButton*,int> buttons; for (int lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++) { if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex)) { FbxString lDesc = pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex); QPushButton *button = msgBox.addButton(lDesc.Buffer(), QMessageBox::AcceptRole); buttons[button] = lFormatIndex; } } msgBox.exec(); //get the right format fileFormat = buttons[msgBox.clickedButton()]; } catch(...) { } } else { //try to find the default output format as set by the user for (int lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++) { if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex)) { FbxString lDesc = pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex); QString sanitizedDesc = SanitizeFBXFormatString(lDesc.Buffer()); if (s_defaultOutputFormat == sanitizedDesc) { ccLog::Print(QString("[FBX] Default output file format: %1").arg(sanitizedDesc)); fileFormat = lFormatIndex; break; } } } //if we failed to find the specified file format, warn the user and display the list of supported formats if (fileFormat < 0) { ccLog::Warning(QString("[FBX] File format '%1' not supported").arg(s_defaultOutputFormat)); ccLog::Print("[FBX] Supported output formats:"); for (int lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++) { if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex)) { FbxString lDesc = pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex); ccLog::Print(QString("\t- %1").arg(SanitizeFBXFormatString(lDesc.Buffer()))); } } } } } } // Save the scene. bool lResult = SaveScene(lSdkManager, lScene, qPrintable(filename),fileFormat); // Destroy all objects created by the FBX SDK. if( lSdkManager ) lSdkManager->Destroy(); return lResult ? CC_FERR_NO_ERROR : CC_FERR_CONSOLE_ERROR; } catch(...) { ccLog::Warning("[FBX] FBX SDK has thrown an unknown exception!"); return CC_FERR_THIRD_PARTY_LIB_EXCEPTION; } }
HRESULT CStaticMesh::Initalize(const char * szFilePath, const char * szFileName) { m_eDrawType = DRAW_VERTEX; FbxManager* pFBXManager = FbxManager::Create(); FbxIOSettings* pIOsettings = FbxIOSettings::Create(pFBXManager, IOSROOT); pFBXManager->SetIOSettings(pIOsettings); FbxScene* pFBXScene = FbxScene::Create(pFBXManager, ""); FbxImporter* pImporter = FbxImporter::Create(pFBXManager, ""); if (FAILED(Load_StaticMesh(szFilePath, szFileName, pFBXManager, pIOsettings, pFBXScene, pImporter))) return E_FAIL; CMesh::CreateRasterizerState(); //Init_Shader(); pFBXScene->Destroy(); pImporter->Destroy(); pIOsettings->Destroy(); pFBXManager->Destroy(); return S_OK; }
void FbxUtil::LoadScene(const std::string &filePath, const std::shared_ptr<SceneNode> &rootNode, float scaleFactor, unsigned int options) { FbxManager* sdkManager = FbxManager::Create(); FbxIOSettings* ios = FbxIOSettings::Create(sdkManager, IOSROOT); sdkManager->SetIOSettings(ios); FbxImporter* importer = FbxImporter::Create(sdkManager, ""); m_ScaleFactor = scaleFactor; m_Options = options; if (importer->Initialize(filePath.c_str(), -1, sdkManager->GetIOSettings())) { FbxScene* lScene = FbxScene::Create(sdkManager, ""); importer->Import(lScene); importer->Destroy(); FbxNode* lRootNode = lScene->GetRootNode(); if (lRootNode) { for (int i = 0; i < lRootNode->GetChildCount(); i++) LoadNode(rootNode, lRootNode->GetChild(i)); rootNode->Recompose(); } } else ASSERT_MSG(false, "Error: " << importer->GetStatus().GetErrorString()); // Destroy the SDK manager and all the other objects it was handling. sdkManager->Destroy(); }
int main(int argc, char** argv) { #if _WIN32 char current_path[MAX_PATH + 1]; GetDirectoryName(current_path, argv[0]); SetCurrentDirectoryA(current_path); #endif FBX2MDL::FBXImporter importer; FBX2MDL::FBXExporter exporter; FbxManager* sdkManager = FbxManager::Create(); FbxIOSettings* ios = FbxIOSettings::Create(sdkManager, IOSROOT); sdkManager->SetIOSettings(ios); fbxsdk_2015_1::FbxImporter* fbxImporter = fbxsdk_2015_1::FbxImporter::Create(sdkManager, ""); if (!fbxImporter->Initialize("box3.fbx", -1, sdkManager->GetIOSettings())) { printf("Call to FbxImporter::Initialize() failed.\n"); printf("Error returned: %s\n\n", fbxImporter->GetStatus().GetErrorString()); system("PAUSE"); exit(-1); } FbxScene* fbxScene = FbxScene::Create(sdkManager, "myScene"); fbxImporter->Import(fbxScene); auto scene = importer.LoadScene(fbxScene, sdkManager); auto writer = exporter.Export(scene); fbxScene->Destroy(); fbxImporter->Destroy(); sdkManager->Destroy(); writer->WriteOut("box2.mdl"); auto buf = writer->Get(); auto buf_ = std::vector<uint8_t>(); for (size_t i = 0; i < buf.size(); i++) { auto b = ((uint8_t*) buf.data())[i]; buf_.push_back(b); } ace::Model_IO model_io; model_io.Load(buf_, ace::ToAString("./").c_str()); /* MDLExporter *exporter = new MDLExporter("Data/Model/AnimationTest.fbx", "Data/Model/AnimationTest.mdl"); exporter->Convert(); delete exporter; */ return 0; }
// FBXデータから頂点データにコンバート // ※パスは「/」でしか通らない //const char* filename = "../datas/box.fbx"; bool LoadFBXConvertToVertexData(const char* filename, VertexDataArray& outVertexData) { //============================================================================== // FBXオブジェクト初期化 //============================================================================== // FBXマネージャー作成 FbxManager* pFBXManager = FbxManager::Create(); // シーン作成 FbxScene* pScene = FbxScene::Create(pFBXManager, ""); // FBXのIO設定オブジェクト作成 FbxIOSettings *pIO = FbxIOSettings::Create(pFBXManager, IOSROOT); pFBXManager->SetIOSettings(pIO); // インポートオブジェクト作成 FbxImporter* pImporter = FbxImporter::Create(pFBXManager, ""); // ファイルインポート if(pImporter->Initialize(filename, -1, pFBXManager->GetIOSettings()) == false) { return false; } // シーンへインポート if(pImporter->Import(pScene) == false) { return false; } // ※この時点でインポートオブジェクトはいらない pImporter->Destroy(); //============================================================================== // FBXオブジェクトの処理 //============================================================================== // シーンのものすべてを三角化 FbxGeometryConverter geometryConverte(pFBXManager); geometryConverte.Triangulate(pScene, true); // メッシュ情報処理 GetMeshData(pScene->GetRootNode(), outVertexData); //============================================================================== // FBXオブジェクト色々破棄 //============================================================================== pIO->Destroy(); pScene->Destroy(); pFBXManager->Destroy(); getchar(); return true; }
//-------------------------------------------------------------------------- void ConvertorFBX(const char* lFilename, const VeDirectoryPtr& spDest) noexcept { FbxManager* lSdkManager = FbxManager::Create(); VE_ASSERT_ALWAYS(lSdkManager); VeUserLogI("Autodesk FBX SDK version ", lSdkManager->GetVersion()); FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT); VE_ASSERT_ALWAYS(ios); lSdkManager->SetIOSettings(ios); FbxImporter* lImporter = FbxImporter::Create(lSdkManager, "Import for Venus3D"); VE_ASSERT_ALWAYS(lImporter->Initialize(lFilename, -1, lSdkManager->GetIOSettings())); FbxScene* lScene = FbxScene::Create(lSdkManager, "ImportedScnee"); VE_ASSERT_ALWAYS(lImporter->Import(lScene)); SaveContent(lScene, spDest); lSdkManager->Destroy(); }
// Load Fbx File void GenerateLOD::LoadFbx() { FbxManager *fbxManager = FbxManager::Create(); //Create an IOSetting FbxIOSettings *ios = FbxIOSettings::Create(fbxManager, IOSROOT); fbxManager->SetIOSettings(ios); //Create an impoter FbxImporter *lImporter = FbxImporter::Create(fbxManager, "myImporter"); std::string tmp = std::string(".\\LODs\\") + srcFbxName; bool lImporterStatus = lImporter->Initialize(tmp.c_str(), -1, fbxManager->GetIOSettings()); if (!lImporterStatus) { MessageBox(NULL, "No Scuh File in .\\LODs\\ directory !", "Warning", 0); return; } FbxScene *fbxScene = FbxScene::Create(fbxManager, "myScene"); lImporter->Import(fbxScene); FbxNode *rootNode = fbxScene->GetRootNode(); if (rootNode != NULL) { for (int i = 0; i < rootNode->GetChildCount(); ++i) { FbxNode *node = rootNode->GetChild(i); FbxNodeAttribute *Att = node->GetNodeAttribute(); if (Att != NULL && Att->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh *lMesh = (FbxMesh *)(Att); //FbxMesh *lMesh = dynamic_cast<FbxMesh *>(Att); if (!lMesh->IsTriangleMesh()) { FbxGeometryConverter converter = FbxGeometryConverter(fbxManager); FbxNodeAttribute *Attr = converter.Triangulate(lMesh, true); lMesh = (FbxMesh *)(Attr); } //Following is the SImplification Reduction_EdgesCollapse_UV(node, lMesh, fbxManager, fbxScene); } } } //MessageBox(NULL, "Export Succeed!", "Export", 0); fbxManager->Destroy(); }
int main(int argc, char** argv) { if(argc!=3) { printf("引数が足りません。\n"); return -1; } const char* importPath = argv[1]; const char* exportPath = argv[2]; FBX2MDL::FBXImporter importer; FBX2MDL::FBXExporter exporter; FbxManager* sdkManager = FbxManager::Create(); FbxIOSettings* ios = FbxIOSettings::Create(sdkManager, IOSROOT); sdkManager->SetIOSettings(ios); fbxsdk_2015_1::FbxImporter* fbxImporter = fbxsdk_2015_1::FbxImporter::Create(sdkManager, ""); if (!fbxImporter->Initialize(importPath, -1, sdkManager->GetIOSettings())) { printf("Call to FbxImporter::Initialize() failed.\n"); printf("Error returned: %s\n\n", fbxImporter->GetStatus().GetErrorString()); system("PAUSE"); exit(-1); } FbxScene* fbxScene = FbxScene::Create(sdkManager, "myScene"); fbxImporter->Import(fbxScene); auto scene = importer.LoadScene(fbxScene, sdkManager); auto writer = exporter.Export(scene); fbxScene->Destroy(); fbxImporter->Destroy(); sdkManager->Destroy(); writer->WriteOut(exportPath); return 0; }
int main(int argc, char **argv) { #ifndef _DEBUG if (argc != 2) { printf("invalid arg"); return 0; } const char* filename = argv[1]; #else const char* filename = "*****@*****.**"; #endif output.open("output.txt", ios::out | ios::trunc); output2.open("output2.txt", ios::out | ios::trunc); output3.open("output3.txt", ios::out | ios::trunc); if (!output.is_open()) { exit(1); } FbxManager* fm = FbxManager::Create(); FbxIOSettings *ios = FbxIOSettings::Create(fm, IOSROOT); //ios->SetBoolProp(EXP_FBX_ANIMATION, false); ios->SetIntProp(EXP_FBX_COMPRESS_LEVEL, 9); ios->SetAllObjectFlags(true); fm->SetIOSettings(ios); FbxImporter* importer = FbxImporter::Create(fm, ""); if (!importer->Initialize(filename, -1, fm->GetIOSettings())) { printf("error returned : %s\n", importer->GetStatus().GetErrorString()); exit(-1); } FbxScene* scene = FbxScene::Create(fm, "myscene"); importer->Import(scene); importer->Destroy(); output << "some\n"; output << "charcnt : " << scene->GetCharacterCount() << endl << "node cnt : " << scene->GetNodeCount() << endl; int animstackcnt = scene->GetSrcObjectCount<FbxAnimStack>(); output << "animstackcnt : " << animstackcnt << endl; output << "------------" << endl; vector<FbxNode*> removableNodes; for (int i = 0; i < scene->GetNodeCount(); i++) { FbxNode* node = scene->GetNode(i); output << "scene's node " << i << " : " << node->GetName() << ", childcnt : " << node->GetChildCount(); if (node->GetNodeAttribute()) { output <<", att type : " << node->GetNodeAttribute()->GetAttributeType(); if (node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::EType::eMesh) { FbxMesh* mesh = node->GetMesh(); output << ", mem usage : " << mesh->MemoryUsage() << ", deformer cnt : " << mesh->GetDeformerCount(FbxDeformer::EDeformerType::eSkin) << endl; collapseMesh(mesh); FbxSkin* skin = (FbxSkin*) (mesh->GetDeformer(0, FbxDeformer::EDeformerType::eSkin)); if (skin) { for (int cli = 0; cli < skin->GetClusterCount(); cli++) { FbxCluster* cluster = skin->GetCluster(cli); output << "\tcluster no." << cli << " has " << cluster->GetControlPointIndicesCount() << " connected verts" << endl; if (cluster->GetControlPointIndicesCount() == 0) removableNodes.push_back( cluster->GetLink() ); //cluster-> //skin->RemoveCluster(cluster);효과없음 } } if (mesh->IsTriangleMesh()) { output << "\tit's triangle mesh" << endl; } //mesh->RemoveDeformer(0);효과없음 } else output << endl; } else { output << ", att type : none" << endl; } } for (int rni = 0; rni < removableNodes.size(); rni++) { FbxNode* rnd = removableNodes[rni]; if (rnd && rnd->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::EType::eSkeleton) { output3 << rnd->GetName() << " node with no vert attached's curve : " << rnd->GetSrcObjectCount<FbxAnimCurve>() << "," << rnd->GetSrcObjectCount<FbxAnimCurveNode>() << endl; } } output << "-----------animinfo" << endl; int cubic = 0, linear = 0, cons = 0; for (int si = 0; si < animstackcnt; si++) { FbxAnimStack* stack = scene->GetSrcObject<FbxAnimStack>(si); for (int i = 0; i < stack->GetMemberCount<FbxAnimLayer>(); i++) { FbxAnimLayer* layer = stack->GetMember<FbxAnimLayer>(i); int curvenodecnt = layer->GetMemberCount<FbxAnimCurveNode>(); int compositcnt = 0; for (int j = 0; j < curvenodecnt; j++) { FbxAnimCurveNode* cnode = layer->GetMember<FbxAnimCurveNode>(j); compositcnt += (cnode->IsComposite() ? 1 : 0); } output << "\tanimstack's layer " << i << " : " << layer->GetName() << ", curve node cnt : " << curvenodecnt << ", composit node cnt : " << compositcnt << endl; vector<FbxAnimCurveNode*> nodes2del; for (int j = 0; j < curvenodecnt; j++) { FbxAnimCurveNode* cnode = layer->GetMember<FbxAnimCurveNode>(j); output << "\t\tcurvenode " << j << " channel cnt : " << cnode->GetChannelsCount() << ", dst obj cnt " << cnode->GetDstObjectCount() << "("; for (int dsti = 0; dsti < cnode->GetDstObjectCount(); dsti++) { output << "," << cnode->GetDstObject(dsti)->GetName(); if (cnode->GetDstObject(dsti)->GetSrcObjectCount() > 0) output << "<" << cnode->GetDstObject(dsti)->GetSrcObjectCount<FbxSkeleton>() << ">"; } output << ")"; FbxTimeSpan interval; if (cnode->GetAnimationInterval(interval)) { output << ", start : " << interval.GetStart().GetTimeString() << ", end : " << interval.GetStop().GetTimeString() << endl; } else { nodes2del.push_back(cnode); output << ", no interval" << endl; } for (int chi = 0; chi < cnode->GetChannelsCount(); chi++) { int curvecnt = cnode->GetCurveCount(chi); output << "\t\t\tchannel." << chi << " curvecnt : " << curvecnt << endl; for (int ci = 0; ci < curvecnt; ci++) { FbxAnimCurve* curve = cnode->GetCurve(chi, ci); int keycnt = curve->KeyGetCount(); output << "\t\t\t\tcurve no." << ci << " : key count : " << keycnt; output2 << "curve " << ci << endl; vector<int> keys2Remove; for (int cki = 0; cki < keycnt; cki++) { FbxAnimCurveKey prevkey, currkey, nextkey; if (cki == 0 || cki == keycnt - 1) continue; currkey = curve->KeyGet(cki); prevkey = curve->KeyGet(cki-1); nextkey = curve->KeyGet(cki + 1); bool keepit = true; output2 << ci << "-" << cki; // keepit = keepTestHorizon(curve, prevkey, currkey, nextkey); // if (keepit) // keepit = slopkeepTest(curve, prevkey, currkey, nextkey); if (!keepit) { if (!(currkey.GetInterpolation() == FbxAnimCurveDef::EInterpolationType::eInterpolationConstant && nextkey.GetInterpolation() != FbxAnimCurveDef::EInterpolationType::eInterpolationConstant)) keys2Remove.push_back(cki); } } for (int kri = keys2Remove.size() - 1; kri >= 0; kri--) { //curve->KeyRemove(keys2Remove[kri]); } output2 << endl; //output << ", cubic:linear:const : " << cubic << ":" << linear << ":" << cons << endl; if (keys2Remove.size() > 0) output << ", " << keys2Remove.size() << " keys removed"; keycnt = curve->KeyGetCount(); } } } //이부분은 별로 효과없음 /* for (int di = 0; di < nodes2del.size(); di++) { layer->RemoveMember(nodes2del[di]); } */ } } output << "cubic:linear:const " << cubic << ":" << linear << ":" << cons << endl; FbxExporter* exporter = FbxExporter::Create(fm, ""); const char* outFBXName = "after.fbx"; bool exportstatus = exporter->Initialize(outFBXName, -1, fm->GetIOSettings()); if (exportstatus == false) { puts("err export fail"); } exporter->Export(scene); exporter->Destroy(); scene->Destroy(); ios->Destroy(); fm->Destroy(); output.close(); output2.close(); output3.close(); return 0; }
CC_FILE_ERROR FBXFilter::loadFile(const char* filename, ccHObject& container, bool alwaysDisplayLoadDialog/*=true*/, bool* coordinatesShiftEnabled/*=0*/, CCVector3d* coordinatesShift/*=0*/) { // Initialize the SDK manager. This object handles memory management. FbxManager* lSdkManager = FbxManager::Create(); // Create the IO settings object. FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT); lSdkManager->SetIOSettings(ios); // Import options determine what kind of data is to be imported. // True is the default, but here we’ll set some to true explicitly, and others to false. //(*(lSdkManager->GetIOSettings())).SetBoolProp(IMP_FBX_MATERIAL, true); //(*(lSdkManager->GetIOSettings())).SetBoolProp(IMP_FBX_TEXTURE, true); // Create an importer using the SDK manager. FbxImporter* lImporter = FbxImporter::Create(lSdkManager,""); CC_FILE_ERROR result = CC_FERR_NO_ERROR; // Use the first argument as the filename for the importer. if (!lImporter->Initialize(filename, -1, lSdkManager->GetIOSettings())) { ccLog::Warning(QString("[FBX] Error: %1").arg(lImporter->GetStatus().GetErrorString())); result = CC_FERR_READING; } else { // Create a new scene so that it can be populated by the imported file. FbxScene* lScene = FbxScene::Create(lSdkManager,"myScene"); // Import the contents of the file into the scene. if (lImporter->Import(lScene)) { // Print the nodes of the scene and their attributes recursively. // Note that we are not printing the root node because it should // not contain any attributes. FbxNode* lRootNode = lScene->GetRootNode(); std::vector<FbxNode*> nodes; nodes.push_back(lRootNode); while (!nodes.empty()) { FbxNode* lNode = nodes.back(); nodes.pop_back(); const char* nodeName = lNode->GetName(); #ifdef _DEBUG ccLog::Print(QString("Node: %1 - %2 properties").arg(nodeName).arg(lNode->GetNodeAttributeCount())); #endif // scan the node's attributes. for(int i=0; i<lNode->GetNodeAttributeCount(); i++) { FbxNodeAttribute* pAttribute = lNode->GetNodeAttributeByIndex(i); FbxNodeAttribute::EType type = pAttribute->GetAttributeType(); #ifdef _DEBUG ccLog::Print(QString("\tProp. #%1").arg(GetAttributeTypeName(type))); #endif switch(type) { case FbxNodeAttribute::eMesh: { ccMesh* mesh = FromFbxMesh(static_cast<FbxMesh*>(pAttribute),alwaysDisplayLoadDialog,coordinatesShiftEnabled,coordinatesShift); if (mesh) { //apply transformation FbxAMatrix& transform = lNode->EvaluateGlobalTransform(); ccGLMatrix mat; float* data = mat.data(); for (int c=0; c<4; ++c) { FbxVector4 C = transform.GetColumn(c); *data++ = static_cast<float>(C[0]); *data++ = static_cast<float>(C[1]); *data++ = static_cast<float>(C[2]); *data++ = static_cast<float>(C[3]); } mesh->applyGLTransformation_recursive(&mat); if (mesh->getName().isEmpty()) mesh->setName(nodeName); container.addChild(mesh); } } break; case FbxNodeAttribute::eUnknown: case FbxNodeAttribute::eNull: case FbxNodeAttribute::eMarker: case FbxNodeAttribute::eSkeleton: case FbxNodeAttribute::eNurbs: case FbxNodeAttribute::ePatch: case FbxNodeAttribute::eCamera: case FbxNodeAttribute::eCameraStereo: case FbxNodeAttribute::eCameraSwitcher: case FbxNodeAttribute::eLight: case FbxNodeAttribute::eOpticalReference: case FbxNodeAttribute::eOpticalMarker: case FbxNodeAttribute::eNurbsCurve: case FbxNodeAttribute::eTrimNurbsSurface: case FbxNodeAttribute::eBoundary: case FbxNodeAttribute::eNurbsSurface: case FbxNodeAttribute::eShape: case FbxNodeAttribute::eLODGroup: case FbxNodeAttribute::eSubDiv: default: //not handled yet break; } } // Recursively add the children. for(int j=0; j<lNode->GetChildCount(); j++) { nodes.push_back(lNode->GetChild(j)); } } } } // The file is imported, so get rid of the importer. lImporter->Destroy(); // Destroy the SDK manager and all the other objects it was handling. lSdkManager->Destroy(); return container.getChildrenNumber() == 0 ? CC_FERR_NO_LOAD : CC_FERR_NO_ERROR; }
CC_FILE_ERROR FBXFilter::saveToFile(ccHObject* entity, const char* filename) { if (!entity) return CC_FERR_BAD_ARGUMENT; std::vector<ccGenericMesh*> meshes; if (entity->isKindOf(CC_MESH)) { meshes.push_back(static_cast<ccGenericMesh*>(entity)); } else if (entity->isA(CC_HIERARCHY_OBJECT)) { for (unsigned i=0; i<entity->getChildrenNumber(); ++i) { ccHObject* child = entity->getChild(i); if (child->isKindOf(CC_MESH)) meshes.push_back(static_cast<ccGenericMesh*>(child)); } } if (meshes.empty()) { return CC_FERR_NO_SAVE; } //The first thing to do is to create the FBX Manager which is the object allocator for almost all the classes in the SDK FbxManager* lSdkManager = FbxManager::Create(); if( !lSdkManager ) { ccLog::Warning("[FBX] Error: Unable to create FBX Manager!"); return CC_FERR_CONSOLE_ERROR; } else { ccLog::Print("[FBX] Autodesk FBX SDK version %s", lSdkManager->GetVersion()); } //Create an IOSettings object. This object holds all import/export settings. FbxIOSettings* ios = FbxIOSettings::Create(lSdkManager, IOSROOT); lSdkManager->SetIOSettings(ios); //Load plugins from the executable directory (optional) //FbxString lPath = FbxGetApplicationDirectory(); //lSdkManager->LoadPluginsDirectory(lPath.Buffer()); //Create an FBX scene. This object holds most objects imported/exported from/to files. FbxScene* lScene = FbxScene::Create(lSdkManager, "My Scene"); if( !lScene ) { ccLog::Warning("[FBX] Error: Unable to create FBX scene!"); return CC_FERR_CONSOLE_ERROR; } // create scene info { FbxDocumentInfo* sceneInfo = FbxDocumentInfo::Create(lSdkManager,"SceneInfo"); sceneInfo->mTitle = qPrintable(QString("Mesh: ") + (meshes.size() == 1 ? meshes[0]->getName() : QString("Multiple meshes"))); sceneInfo->mAuthor = "CloudCompare"; sceneInfo->mRevision = "rev. 1.0"; sceneInfo->mKeywords = "cloudcompare mesh"; // we need to add the sceneInfo before calling AddThumbNailToScene because // that function is asking the scene for the sceneInfo. lScene->SetSceneInfo(sceneInfo); } //create thumbnail //{ // FbxThumbnail* lThumbnail = FbxThumbnail::Create(lScene,""); // lThumbnail->SetDataFormat(FbxThumbnail::eRGB_24); // lThumbnail->SetSize(FbxThumbnail::e64x64); // lThumbnail->SetThumbnailImage(cSceneThumbnail); // if (lScene->GetSceneInfo()) // { // lScene->GetSceneInfo()->SetSceneThumbnail(lThumbnail); // } //} // Build the node tree. FbxNode* lRootNode = lScene->GetRootNode(); { for (size_t i=0; i<meshes.size(); ++i) { FbxNode* meshNode = ToFbxMesh(meshes[i],lScene); if (meshNode) lRootNode->AddChild(meshNode); else ccLog::Warning(QString("[FBX] Failed to convert mesh '%1' to FBX mesh/node!").arg(meshes[i]->getName())); } } // Save the scene. bool lResult = SaveScene(lSdkManager, lScene, filename); // Destroy all objects created by the FBX SDK. if( lSdkManager ) lSdkManager->Destroy(); return lResult ? CC_FERR_NO_ERROR : CC_FERR_CONSOLE_ERROR; }
int main ( int argc, char *argv[] ) { std::vector<std::string> args (argv, argv + argc); if ( args.size() == 1 ) { PrintUsage (args[0]); return EXIT_FAILURE; } std::string animationFile; std::string outputPath ("model.glm"); unsigned i; for ( i = 1; i < args.size(); i++ ) { if ( args[i].compare ("-o") == 0 ) { i++; if ( args.size() > i ) { outputPath = args[i]; continue; } else { PrintUsage (args[0]); return EXIT_FAILURE; } } else if ( args[i].compare ("-anim") == 0 ) { i++; if ( args.size() > i ) { animationFile = args[i]; continue; } else { PrintUsage (args[0]); return EXIT_FAILURE; } } } std::unique_ptr<Skeleton> skeleton; std::string modelPath (args.back()); std::cout << "Converting " << modelPath << " to GLM.\n"; if ( !animationFile.empty() ) { skeleton = LoadGLA (animationFile); if ( !skeleton ) { return EXIT_FAILURE; } std::cout << "Using " << animationFile << " for skeleton.\n"; } FbxManager *fbxManager = FbxManager::Create(); FbxIOSettings *ios = FbxIOSettings::Create (fbxManager, IOSROOT); fbxManager->SetIOSettings (ios); FbxImporter *importer = FbxImporter::Create (fbxManager, ""); if ( !importer->Initialize (modelPath.c_str(), -1, fbxManager->GetIOSettings()) ) { std::cerr << "ERROR: Failed to import '" << modelPath << "': " << importer->GetStatus().GetErrorString() << ".\n"; importer->Destroy(); fbxManager->Destroy(); return EXIT_FAILURE; } FbxScene *scene = FbxScene::Create (fbxManager, "model"); importer->Import (scene); importer->Destroy(); FbxNode *root = scene->GetRootNode(); if ( root == nullptr ) { std::cerr << "ERROR: The scene's root node could not be found.\n"; fbxManager->Destroy(); return EXIT_FAILURE; } std::vector<FbxNode *> modelRoots (GetLodRootModels (*root)); if ( modelRoots.empty() ) { std::cerr << "ERROR: No model LODs found.\n"; fbxManager->Destroy(); return EXIT_FAILURE; } std::sort (modelRoots.begin(), modelRoots.end(), []( const FbxNode *a, const FbxNode *b ) { return std::strcmp (a->GetName(), b->GetName()) < 0; }); if ( !MakeGLMFile (*scene, modelRoots, skeleton.get(), outputPath) ) { std::cerr << "ERROR: Failed to create GLM file " << outputPath << ".\n"; fbxManager->Destroy(); return EXIT_FAILURE; } std::cout << "GLM file has been written to '" << outputPath << "'.\n"; fbxManager->Destroy(); return 0; }
void FBXSceneEncoder::write(const string& filepath, const EncoderArguments& arguments) { FbxManager* sdkManager = FbxManager::Create(); FbxIOSettings *ios = FbxIOSettings::Create(sdkManager, IOSROOT); sdkManager->SetIOSettings(ios); FbxImporter* importer = FbxImporter::Create(sdkManager,""); if (!importer->Initialize(filepath.c_str(), -1, sdkManager->GetIOSettings())) { LOG(1, "Call to FbxImporter::Initialize() failed.\n"); LOG(1, "Error returned: %s\n\n", importer->GetLastErrorString()); exit(-1); } FbxScene* fbxScene = FbxScene::Create(sdkManager,"__FBX_SCENE__"); print("Loading FBX file."); importer->Import(fbxScene); importer->Destroy(); // Determine if animations should be grouped. if (arguments.getGroupAnimationAnimationId().empty() && isGroupAnimationPossible(fbxScene)) { if ( arguments.getAnimationGrouping()==EncoderArguments::ANIMATIONGROUP_AUTO || (arguments.getAnimationGrouping()==EncoderArguments::ANIMATIONGROUP_PROMPT && promptUserGroupAnimations())) { _autoGroupAnimations = true; } } if (arguments.tangentBinormalIdCount() > 0) { generateTangentsAndBinormals(fbxScene->GetRootNode(), arguments); } print("Loading Scene."); loadScene(fbxScene); print("Load materials"); loadMaterials(fbxScene); print("Loading animations."); loadAnimations(fbxScene, arguments); sdkManager->Destroy(); print("Optimizing GamePlay Binary."); _gamePlayFile.adjust(); if (_autoGroupAnimations) { _gamePlayFile.groupMeshSkinAnimations(); } string outputFilePath = arguments.getOutputFilePath(); if (arguments.textOutputEnabled()) { int pos = outputFilePath.find_last_of('.'); if (pos > 2) { string path = outputFilePath.substr(0, pos); path.append(".xml"); LOG(1, "Saving debug file: %s\n", path.c_str()); if (!_gamePlayFile.saveText(path)) { LOG(1, "Error writing text file: %s\n", path.c_str()); } } } else { LOG(1, "Saving binary file: %s\n", outputFilePath.c_str()); if (!_gamePlayFile.saveBinary(outputFilePath)) { LOG(1, "Error writing binary file: %s\n", outputFilePath.c_str()); } } // Write the material file if (arguments.outputMaterialEnabled()) { int pos = outputFilePath.find_last_of('.'); if (pos > 2) { string path = outputFilePath.substr(0, pos); path.append(".material"); writeMaterial(path); } } }
int main() { // ※パスは「/」でしか通らない const char* filename = "../datas/box.fbx"; //============================================================================== // FBXオブジェクト初期化 //============================================================================== // FBXマネージャー作成 FbxManager* pFBXManager = FbxManager::Create(); // シーン作成 FbxScene* pScene = FbxScene::Create(pFBXManager, ""); // FBXのIO設定オブジェクト作成 FbxIOSettings *pIO = FbxIOSettings::Create(pFBXManager, IOSROOT); pFBXManager->SetIOSettings(pIO); // インポートオブジェクト作成 FbxImporter* pImporter = FbxImporter::Create(pFBXManager, ""); // ファイルインポート if(pImporter->Initialize(filename, -1, pFBXManager->GetIOSettings()) == false) { printf("FBXファイルインポートエラー\n"); printf("エラー内容: %s\n\n", pImporter->GetStatus().GetErrorString()); return 1; } // シーンへインポート if(pImporter->Import(pScene) == false) { printf("FBXシーンインポートエラー\n"); printf("エラー内容: %s\n\n", pImporter->GetStatus().GetErrorString()); return 1; } // ※この時点でインポートオブジェクトはいらない pImporter->Destroy(); //============================================================================== // FBXオブジェクトの処理 //============================================================================== // ノードを表示してみる traverseScene(pScene->GetRootNode()); // シーンのものすべてを三角化 FbxGeometryConverter geometryConverte(pFBXManager); geometryConverte.Triangulate(pScene, true); // メッシュ情報処理 GetMeshData(pScene->GetRootNode()); //============================================================================== // FBXオブジェクト色々破棄 //============================================================================== pIO->Destroy(); pScene->Destroy(); pFBXManager->Destroy(); printf("全処理終了\n"); getchar(); return 0; }
int main(int argc, char* argv[]) { // initialize Havok internals { hkMemorySystem::FrameInfo frameInfo(0); #ifdef _DEBUG // (Use debug mem manager to detect mem leaks in Havok code) hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initChecking(hkMallocAllocator::m_defaultMallocAllocator, frameInfo); #else hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initFreeListLargeBlock(hkMallocAllocator::m_defaultMallocAllocator, frameInfo); #endif hkBaseSystem::init( memoryRouter, havokErrorReport ); hkError& errorhandler = hkError::getInstance(); errorhandler.enableAll(); } if (argc != 2) { printf("Invalid number of input arguments\n"); printf("Usage: FBXImport <input_filename>\n"); return -1; } // Load FBX and save as HKX { const char* filename = argv[1]; FbxManager* fbxSdkManager = FbxManager::Create(); if( !fbxSdkManager ) { HK_ERROR(0x5213afed, "Unable to create FBX Manager!\n"); return -1; } FbxIOSettings* fbxIoSettings = FbxIOSettings::Create(fbxSdkManager, IOSROOT); fbxSdkManager->SetIOSettings(fbxIoSettings); FbxImporter* fbxImporter = FbxImporter::Create(fbxSdkManager,""); if (!fbxImporter->Initialize(filename, -1, fbxSdkManager->GetIOSettings())) { HK_WARN(0x5216afed, "Failed to initialize the importer! Please ensure file " << filename << " exists\n"); fbxSdkManager->Destroy(); return -1; } FbxScene* fbxScene = FbxScene::Create(fbxSdkManager,"tempScene"); if (!fbxScene) { HK_ERROR(0x5216afed, "Failed to create the scene!\n"); fbxImporter->Destroy(); fbxSdkManager->Destroy(); return -1; } fbxImporter->Import(fbxScene); fbxImporter->Destroy(); // Currently assume that the file is loaded from 3dsmax FbxAxisSystem::Max.ConvertScene(fbxScene); FbxToHkxConverter::Options options(fbxSdkManager); FbxToHkxConverter converter(options); if(converter.createScenes(fbxScene)) { int lastSlashIndex = hkString::lastIndexOf(filename,'\\') + 1; int extensionIndex = hkString::lastIndexOf(filename,'.'); hkStringBuf path; path.set(filename, lastSlashIndex); hkStringBuf name; name.set(filename + lastSlashIndex, extensionIndex - lastSlashIndex); converter.saveScenes(path, name); } else { HK_ERROR(0x0, "Failed to convert the scene!\n"); fbxSdkManager->Destroy(); return -1; } fbxSdkManager->Destroy(); } // quit Havok { hkBaseSystem::quit(); hkMemoryInitUtil::quit(); } return 0; }
~CleanUpFbx() { m_pSdkManager->Destroy(); }
/***************************************************************** * LoadLevel() Returns the only instance of the MessageManager * * Ins: szFilePath * * Outs: None * * Returns: bool * * Mod. Date: 09/02/2015 * Mod. Initials: NH *****************************************************************/ bool CLevelLoader::LoadLevel(string file_name) { #pragma region FBX initialize // Get an FBX manager FbxManager* manager = FbxManager::Create(); if (manager == 0) { return false; } // Create IO settings FbxIOSettings* io_settings = FbxIOSettings::Create(manager, IOSROOT); if (io_settings == 0) { manager->Destroy(); return false; } manager->SetIOSettings(io_settings); // Create importer FbxImporter* importer = FbxImporter::Create(manager, ""); if (importer == 0) { io_settings->Destroy(); manager->Destroy(); return false; } // Initialize importer if (importer->Initialize(file_name.c_str(), -1, io_settings) == false) { io_settings->Destroy(); manager->Destroy(); importer->Destroy(); return false; } // Create a scene FbxScene* scene = FbxScene::Create(manager, "myScene"); if (scene == 0) { io_settings->Destroy(); manager->Destroy(); importer->Destroy(); return false; } // Load the scene with contents from the file if (importer->Import(scene) == false) { io_settings->Destroy(); manager->Destroy(); importer->Destroy(); scene->Destroy(); return false; } // No longer need the importer // Traverse the scene FbxNode* root_node = scene->GetRootNode(); if (ProcessLevelNode(root_node, m_cvMeshes) == false) { importer->Destroy(); io_settings->Destroy(); root_node->Destroy(); scene->Destroy(); manager->Destroy(); return false; } importer->Destroy(); io_settings->Destroy(); root_node->Destroy(); scene->Destroy(); manager->Destroy(); #pragma endregion #pragma region Exit Door Objects srand((unsigned int)(CURRENT_TIME())); unsigned int ExitDoorIndex = rand() % 4; //for (unsigned int i = 0; i < m_cvExitDoorMeshes.size(); i++) //{ // m_cvExitDoorMeshes[i].ConvertVertices(); // m_cvExitTeleporterMeshes[i].ConvertVertices(); // if (i == ExitDoorIndex) // { // //this is the exit door // m_cpTheExitDoor = new CExitDoorObject("ExitDoor"); // m_cpTheExitDoor->AddCollider(new CCollider(true, Bounds::AABB, m_cvExitDoorMeshes[i].GetVertices())); // m_cpTheExitDoor->SetRenderMesh(new CRenderMesh(&m_cvExitDoorMeshes[i], GRAPHICS->GetVertexShader(), GRAPHICS->GetPixelShader(), nullptr, nullptr, nullptr, L"../Game/Assets/Art/2D/Textures/Door.dds")); // m_cpEnvironmentObjects.push_back(m_cpTheExitDoor); // m_cpObjectManager->AddObject(m_cpTheExitDoor, CObjectManager::eObjectType::Dynamic); // //set up teleporter // m_cpTheExitTeleporter = new CWaypointObject("ExitTeleporter"); // m_cpTheExitTeleporter->SetPosition(GetAABBCentroid(m_cvExitTeleporterMeshes[i].GetVertices())); // continue; // } // //thse are not exit doors anymore. now they are standard walls // CWallObject* newWall = new CWallObject("Wall"); // newWall->AddCollider(new CCollider(false, Bounds::AABB, m_cvExitDoorMeshes[i].GetVertices())); // newWall->SetRenderMesh(new CRenderMesh(&m_cvExitDoorMeshes[i], GRAPHICS->GetVertexShader(), GRAPHICS->GetPixelShader(), nullptr, nullptr, nullptr, L"../Game/Assets/Art/2D/Textures/Maze_Wall.dds")); // m_cpEnvironmentObjects.push_back(newWall); // m_cpObjectManager->AddObject(newWall, CObjectManager::eObjectType::Static); //} #pragma endregion CNavGraphManager::GetReference().AddNavGraph("MinotaurNavGraph", m_cpMinotaurNavGraph); return true; }
CGeometryComponent * CModelLoader::loadFbxModelFromFile(ID3D10Device *pDevice,const string& filename) { CGeometryComponent * pRenderable=NULL; FbxManager* lSdkManager = FbxManager::Create(); FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT); lSdkManager->SetIOSettings(ios); // Create an importer using our sdk manager. FbxImporter* lImporter = FbxImporter::Create(lSdkManager,""); //Sean: uncomment back to this when you compile, I am using the latest version of fbx SDK //KFbxGeometryConverter converter( lSdkManager); //Sean: has comment out the line below FbxGeometryConverter converter( lSdkManager); // Use the first argument as the filename for the importer. if(!lImporter->Initialize(filename.c_str(), -1, lSdkManager->GetIOSettings())) { return NULL; } // Create a new scene so it can be populated by the imported file. FbxScene* lScene = FbxScene::Create(lSdkManager,"myScene"); FbxAxisSystem SceneAxisSystem = lScene->GetGlobalSettings().GetAxisSystem(); //FbxAxisSystem::DirectX.ConvertScene( lScene ); INT iUpAxisSign; //Sean: Uncomment this below //KFbxAxisSystem::eUpVector UpVector = SceneAxisSystem.GetUpVector( iUpAxisSign ); //Sean: and comment this out FbxAxisSystem::EUpVector UpVector = SceneAxisSystem.GetUpVector( iUpAxisSign ); // Import the contents of the file into the scene. lImporter->Import(lScene); // The file has been imported; we can get rid of the importer. lImporter->Destroy(); FbxNode* lRootNode = lScene->GetRootNode(); FbxMesh * pMesh=NULL; if(lRootNode) { for (int i=0;i<lRootNode->GetChildCount();i++){ FbxNode * modelNode=lRootNode->GetChild(i); for(int i=0;i<modelNode->GetNodeAttributeCount();i++) { FbxNodeAttribute *pAttributeNode=modelNode->GetNodeAttributeByIndex(i); //Sean: Uncomment this //if (pAttributeNode->GetAttributeType()==KFbxNodeAttribute::eMESH) //Sean Comment this out if (pAttributeNode->GetAttributeType()==FbxNodeAttribute::eMesh) { //found mesh pMesh=(FbxMesh*)pAttributeNode; break; } } } if (pMesh) { pMesh=converter.TriangulateMesh(pMesh); FbxVector4 * verts=pMesh->GetControlPoints(); int noVerts=pMesh->GetControlPointsCount(); int noIndices=pMesh->GetPolygonVertexCount(); int *pIndices=pMesh->GetPolygonVertices(); Vertex * pVerts=new Vertex[noVerts]; for(int i=0;i<noVerts;i++) { pVerts[i].Pos.x=verts[i][0]; pVerts[i].Pos.y=verts[i][1]; pVerts[i].Pos.z=verts[i][2]; } for (int iPolygon = 0; iPolygon < pMesh->GetPolygonCount(); iPolygon++) { for (unsigned iPolygonVertex = 0; iPolygonVertex < 3; iPolygonVertex++) { int fbxCornerIndex = pMesh->GetPolygonVertex(iPolygon, iPolygonVertex); FbxVector4 fbxVertex = verts[fbxCornerIndex]; FbxVector4 fbxNormal; pMesh->GetPolygonVertexNormal(iPolygon, iPolygonVertex, fbxNormal); fbxNormal.Normalize(); //pVerts[fbxCornerIndex].Normal=D3DXVECTOR3(fbxNormal[0],fbxNormal[1],fbxNormal[2]); FbxVector2 fbxUV = FbxVector2(0.0, 0.0); FbxLayerElementUV* fbxLayerUV = pMesh->GetLayer(0)->GetUVs(); // Get texture coordinate if (fbxLayerUV) { int iUVIndex = 0; switch (fbxLayerUV->GetMappingMode()) { //Sean Uncomment this //case KFbxLayerElement::eBY_CONTROL_POINT: //Sean comment the line below out case FbxLayerElement::eByControlPoint: iUVIndex = fbxCornerIndex; break; //Sean Uncomment this //case KFbxLayerElement::eBY_POLYGON_VERTEX: //Sean comment the line below out case FbxLayerElement::eByPolygonVertex: //Sean Uncomment this //iUVIndex = pMesh->GetTextureUVIndex(iPolygon, iPolygonVertex, KFbxLayerElement::eDIFFUSE_TEXTURES); //Sean comment this out iUVIndex = pMesh->GetTextureUVIndex(iPolygon, iPolygonVertex, FbxLayerElement::eTextureDiffuse); break; } fbxUV = fbxLayerUV->GetDirectArray().GetAt(iUVIndex); //pVerts[fbxCornerIndex].TextureCoords.x=fbxUV[0]; //pVerts[fbxCornerIndex].TextureCoords.y= 1.0f-fbxUV[1]; } } } pRenderable=new CGeometryComponent(); for (int i=0;i<noVerts;i++) { pRenderable->addVertex(pVerts[i]); } for (int i=0;i<noIndices;i++) { pRenderable->addIndex(pIndices[i]); } //pRenderable->create<TexturedLitVertex>(pDevice,noVerts,noIndices,pVerts,(UINT*)pIndices); if (pVerts) { delete [] pVerts; pVerts=NULL; } //} } } lSdkManager->Destroy(); return pRenderable; }