FbxNode* FBXScene::findNode(FbxNodeAttribute::EType type) { FbxNode* node = m_pScene->GetRootNode(); std::vector<FbxNode*> toExplore; for (int i = 0; i < node->GetChildCount(); ++i) { toExplore.push_back(node->GetChild(i)); } while (!toExplore.empty()) { node = toExplore.back(); toExplore.pop_back(); if (node->GetNodeAttribute()->GetAttributeType() == type) { return node; } for (int i = 0; i < node->GetChildCount(); ++i) { toExplore.push_back(node->GetChild(i)); } } LOGE << "Couldn't find any node of type " << fbxUtility::getAttributeStr(type); return nullptr; }
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(); }
bool Model::loadFBXFromFile(const string& fileName) { //initialize the sdk manager FbxManager *manager = FbxManager::Create(); //setting up the IO settings object FbxIOSettings *settings = FbxIOSettings::Create(manager, IOSROOT); manager->SetIOSettings(settings); //creating the importer FbxImporter *importer = FbxImporter::Create(manager, ""); //initializing the importer with contents of file if (!importer->Initialize(fileName.c_str(), -1, settings)) return false; //creating a scene to be filled with objects FbxScene *scene = FbxScene::Create(manager, "myScene"); importer->Import(scene); FbxGeometryConverter geomConverter(manager); geomConverter.Triangulate(scene, true); FbxNode *root = scene->GetRootNode(); if (root) { //printf("Root Node: %s\n", root->GetName()); int childCount = root->GetChildCount(); for (int i = 0; i < childCount; i++) processNode(root->GetChild(i), 1); } importer->Destroy(); return true; }
/////////////////////////////////////////////////////////////////////////////////////// // Go through all the children of the root node and call a function that // recursively iterates through the rest of the tree /////////////////////////////////////////////////////////////////////////////////////// void ProcessContent::Start(FbxScene* pScene) { int i; FbxNode* lNode = pScene->GetRootNode(); ////////////////////////////////////////////////////////////// // GRAB GLOBAL INFO FIRST ProcessGlobalData(&pScene->GetGlobalSettings()); ////////////////////////////////////////////////////////////// // NOW RECUR THROUGH TREE if(lNode) { for(i = 0; i < lNode->GetChildCount(); i++) { RecurThroughChildren(lNode->GetChild(i)); } } // Weld all components that can be matched and fix indices into triangle list m_writeData.WeldData(); // Get rid of unused materials m_procMat.DeleteUnused(); }
void FBXImporter::WalkHierarchy() { FbxNode* root = mScene->GetRootNode(); for (int i = 0; i < root->GetChildCount(); i++) { WalkHierarchy(root->GetChild(i), 0); } }
void WalkHierarchy(const FbxScene* pScene) { FbxNode* root = pScene->GetRootNode(); for (int i=0;i<root->GetChildCount();i++) { WalkHierarchy(root->GetChild(i)); } }
JNIEXPORT jboolean JNICALL Java_de_tesis_dynaware_javafx_graphics_importers_fbx_JFbxLib_nextSibling(JNIEnv *env, jobject obj) { // Check FBX file has been opened. if (!isOpen()) { throwFileClosedException(env); } FbxNode *parent = currentNode->GetParent(); if (parent!=NULL) { const int siblingCount = parent->GetChildCount(false); for (int i=0; i<siblingCount-1; i++) { FbxNode *sibling = parent->GetChild(i); if (currentNode == sibling) { currentNode = parent->GetChild(i+1); return JNI_TRUE; } } } return JNI_FALSE; }
//-------------------------------------------------------------------------- void SaveContent(FbxScene* pScene, const VeDirectoryPtr& spDest) noexcept { FbxNode* lNode = pScene->GetRootNode(); if (lNode) { for (int i = 0; i < lNode->GetChildCount(); i++) { SaveContent(lNode->GetChild(i), spDest); } } }
Bone::Bone(FbxNode& node) : index ( -1 ) , name ( node.GetName() ) , parentName ( node.GetParent() != nullptr ? node.GetParent()->GetName() : "none" ) , numChildren ( unsigned(node.GetChildCount()) ) , transformation ( to_gua::mat4f(node.EvaluateLocalTransform()) ) , offsetMatrix ( scm::math::mat4f::identity() ) { for (int i = 0; i < node.GetChildCount(); ++i) { FbxSkeleton const* skelnode { node.GetChild(i)->GetSkeleton() }; if (skelnode && skelnode->GetSkeletonType() == FbxSkeleton::eEffector && node.GetChild(i)->GetChildCount() == 0) { Logger::LOG_DEBUG << node.GetChild(i)->GetName() << " is effector, ignoring it" << std::endl; } else { auto child = std::make_shared<Bone>(*(node.GetChild(i))); children.push_back(child); } } }
void FbxParser::ProcessScene(std::vector<GS::BaseMesh*>& meshs, std::vector<GS::Light*>& lights,GS::Camera& camera) { int i; FbxNode* lNode = mpFbxScene->GetRootNode(); if(lNode) { for(i = 0; i < lNode->GetChildCount(); i++) { ProcessNode(lNode->GetChild(i),meshs,lights, camera); } } }
// メッシュ情報処理(再帰関数) void GetMeshData(FbxNode *parent, VertexDataArray& outVertexData) { // メッシュだけ処理 int numKids = parent->GetChildCount(); for(int i = 0; i < numKids; i++) { FbxNode *child = parent->GetChild(i); // メッシュを見つけたら if(child->GetMesh()) { FbxMesh* pMesh = child->GetMesh();// static_cast<FbxMesh*>(child->GetNodeAttribute()); printf("メッシュ発見\n"); printf("名前:%s\n", pMesh->GetName()); printf("ポリゴン数:%d\n", pMesh->GetPolygonCount()); printf("マテリアル数:%d\n", pMesh->GetElementMaterialCount()); printf("コントロールポイント数(頂点座標):%d\n", pMesh->GetControlPointsCount()); printf("UV数:%d\n", pMesh->GetTextureUVCount()); FbxArray<FbxVector4> normals; pMesh->GetPolygonVertexNormals(normals); printf("法線数:%d\n", normals.GetCount()); // 頂点情報取得 GetFBXVertexData(pMesh, outVertexData); } // マテリアル int numMat = child->GetMaterialCount(); for(int j = 0; j < numMat; ++j) { FbxSurfaceMaterial* mat = child->GetMaterial(j); if(mat) { GetMatrialData(mat); } } if(numMat == 0) { printf("マテリアルなし\n"); } child->GetChild(0); // 更に子を処理 GetMeshData(child, outVertexData); } }
void ContentReader(FbxScene* pScene) { int i; FbxNode* lNode = pScene->GetRootNode(); FbxAMatrix rootGlobleMatrix; if(lNode) { for(i = 0; i<lNode->GetChildCount(); i++) { ContentReader(lNode->GetChild(i),rootGlobleMatrix); } } printf("\nload finished\n"); }
FbxNode *AssetConverter::nextNode() { if (!m_nodes.empty()) { FbxNode *ret = m_nodes.front(); for (int i = 0; i < ret->GetChildCount(); i++) { m_nodes.push_back(ret->GetChild(i)); } m_nodes.pop_front(); return ret; } return NULL; }
std::vector<LoaderFbxModelDesc> LoaderFbx::load(std::string filename) { meshLoader_->reset(); materialLoader_->reset(); textureLoader_->reset(); animationLoader_->reset(); modelDescs_.clear(); bool success = true; if(fbxScene_) { fbxScene_->Destroy(); fbxScene_ = nullptr; success = createFbxScene(); } else success = createFbxScene(); if(success) success = loadScene(filename); FbxAxisSystem sceneAxisSystem = fbxScene_->GetGlobalSettings().GetAxisSystem(); FbxAxisSystem xkillAxisSystem(FbxAxisSystem::eDirectX); if(sceneAxisSystem != xkillAxisSystem) xkillAxisSystem.ConvertScene(fbxScene_); sceneAxisSystem = fbxScene_->GetGlobalSettings().GetAxisSystem(); FbxNode* node = fbxScene_->GetRootNode(); if(node) { for(int i=0; i<node->GetChildCount(); i++) parseNode(node->GetChild(i)); } for(unsigned int i=0; i<modelDescs_.size(); i++) { std::vector<LoaderFbxAnimationDesc> animationDescs; animationLoader_->parseAnimation(fbxScene_, &animationDescs, modelDescs_[i].getMeshDesc().getBoneNodes()); modelDescs_[i].setAnimationDescs(animationDescs); } return modelDescs_; }
void FBXSceneEncoder::loadScene(FbxScene* fbxScene) { Scene* scene = new Scene(); scene->setId(fbxScene->GetName()); if (scene->getId().length() == 0) { scene->setId("__SCENE__"); } // Load all of the nodes and their contents. FbxNode* rootNode = fbxScene->GetRootNode(); if (rootNode) { print("Triangulate."); FbxGeometryConverter converter(rootNode->GetFbxManager()); converter.Triangulate(fbxScene, true); //triangulateRecursive(rootNode); print("Load nodes."); // Don't include the FBX root node in the GPB. const int childCount = rootNode->GetChildCount(); for (int i = 0; i < childCount; ++i) { Node* node = loadNode(rootNode->GetChild(i)); if (node) { scene->add(node); } } } // Load the MeshSkin information from the scene's poses. loadBindShapes(fbxScene); // Find the ambient light of the scene FbxColor ambientColor = fbxScene->GetGlobalSettings().GetAmbientColor(); scene->setAmbientColor((float)ambientColor.mRed, (float)ambientColor.mGreen, (float)ambientColor.mBlue); // Assign the first camera node (if there is one) in the scene as the active camera // This ensures that if there's a camera in the scene that it is assigned as the // active camera. // TODO: add logic to find the "active" camera node in the fbxScene scene->setActiveCameraNode(scene->getFirstCameraNode()); _gamePlayFile.addScene(scene); }
void FBXSceneEncoder::loadMaterials(FbxScene* fbxScene) { FbxNode* rootNode = fbxScene->GetRootNode(); if (rootNode) { // Don't include the FBX root node const int childCount = rootNode->GetChildCount(); for (int i = 0; i < childCount; ++i) { FbxNode* fbxNode = rootNode->GetChild(i); if (fbxNode) { loadMaterial(fbxNode); } } } }
//------------------------------------------------------------------------------------------------------------------------------------------- void FBXReader::transferDataFromSceneToModel(FbxScene* scene, Model* &model){ model = new Model(); LOG_DEBUG << "Start transferring data from scene to model..."; FbxNode* rootNode = scene->GetRootNode(); model->InitRootNode(); Node* rootModelNode = model->RootNode; for (int i = 0; i < rootNode->GetChildCount(); i++) { Node* newNode = new Node(); if (transferData(rootNode->GetChild(i), newNode)){ rootModelNode->Children.push_back(newNode); rootModelNode->NumChildren = rootModelNode->Children.size(); } } LOG_DEBUG << "Finish traferring data from scene to model !"; }
// 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(); }
Model::Model(const std::string &filename) { key = filename; if (ResourceManager::access<Data *>(key)) return; int level = 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); // Create an importer using the SDK manager. FbxImporter* lImporter = FbxImporter::Create(lSdkManager, ""); Data *model = new Data(); // Create a new scene so that it can be populated by the imported file. if (!lImporter->Initialize(filename.c_str(), -1, lSdkManager->GetIOSettings())) { LOG(FATAL) << "Failed to load model " << filename; } // 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. 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(); if (lRootNode) { LOG(INFO) << "Root Node " << lRootNode->GetName(); for (int i = 0; i < lRootNode->GetChildCount(); i++) { level = processNode(lRootNode->GetChild(i), level, *model); } } ResourceManager::store(filename, Resource::Type::Model, model); }
GameObject * loadFBXFromFile(const std::string& filename) { GameObject *rootGo = NULL; level = 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); // Create an importer using the SDK manager. FbxImporter* lImporter = FbxImporter::Create(lSdkManager, ""); // Create a new scene so that it can be populated by the imported file. if (!lImporter->Initialize(filename.c_str(), -1, lSdkManager->GetIOSettings())) { return rootGo; } // 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. 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(); if (lRootNode) { rootGo = new GameObject(); rootGo->setTransform(new Transform()); std::cout << "Root Node " << lRootNode->GetName() << std::endl; for (int i = 0; i < lRootNode->GetChildCount(); i++) { processNode(lRootNode->GetChild(i), rootGo); } } return rootGo; }
void Tools::DisplayGenericInfo::DisplayGenericInfo( FbxScene *i_scene ) { DisplayCommon::DisplayString( "\n\n--------------------\nGeneric Info\n--------------------" ); int i; FbxNode* lRootNode = i_scene->GetRootNode(); for( i = 0; i < lRootNode->GetChildCount(); i++ ) { DisplayGenericInfo( lRootNode->GetChild(i), 0 ); } #ifdef DISPLAY_PROPERTY_INFORMATION //Other objects directly connected onto the scene for( i = 0; i < i_scene->GetSrcObjectCount(); i++ ) { DisplayProperties( i_scene->GetSrcObject(i) ); } #endif // #ifdef DISPLAY_PROPERTY_INFORMATION }
FbxNode *AssetConverter::firstNode() { FbxNode *node = m_scene->GetRootNode(); if (node) { for (int i = 0; i < node->GetChildCount(); i++) { m_nodes.push_back(node->GetChild(i)); } } if (!m_nodes.empty()) { FbxNode *ret = m_nodes.front(); m_nodes.pop_front(); return ret; } return NULL; }
void initializeFbxSdk() { const char* lFilename = "testCube.fbx"; mySdkManager = FbxManager::Create(); // Create the IO settings object. FbxIOSettings *ios = FbxIOSettings::Create(mySdkManager, IOSROOT); mySdkManager->SetIOSettings(ios); // Create an importer using the SDK manager. FbxImporter* lImporter = FbxImporter::Create(mySdkManager,""); // Use the first argument as the filename for the importer. if(!lImporter->Initialize(lFilename, -1, mySdkManager->GetIOSettings())) { printf("Call to FbxImporter::Initialize() failed.\n"); printf("Error returned: %s\n\n", lImporter->GetStatus().GetErrorString()); exit(-1); } // Create a new scene so that it can be populated by the imported file. FbxScene* lScene = FbxScene::Create(mySdkManager,"myScene"); // Import the contents of the file into the scene. lImporter->Import(lScene); // The file is imported, so get rid of the importer. lImporter->Destroy(); // 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(); if(lRootNode) { for(int i = 0; i < lRootNode->GetChildCount(); i++) PrintNode(lRootNode->GetChild(i)); } // Destroy the SDK manager and all the other objects it was handling. mySdkManager->Destroy(); }
bool id::FBX::Model::init(FbxScene* scene) { FbxNode* rootNode = scene->GetRootNode(); size_t numChild, numMesh; _scene = scene; if (rootNode) { numChild = rootNode->GetChildCount(); for (size_t i = 0 ; i < numChild ; ++i) if (!initRec(rootNode->GetChild(i), -1)) return false; numMesh = _meshes.size(); for (size_t i = 0 ; i < numMesh ; ++i) if (_meshes[i].hasDeformation && !_meshes[i].deformation.Init(_meshes[i].node, _meshes[i].node->GetMesh())) return false; return allocBones(); } return false; }
void ImportSkeletalMeshLOD( class USkeletalMesh* SelectedSkelMesh, const FString& Filename, int32 LODLevel ) { // Check the file extension for FBX. Anything that isn't .FBX is rejected const FString FileExtension = FPaths::GetExtension(Filename); const bool bIsFBX = FCString::Stricmp(*FileExtension, TEXT("FBX")) == 0; if (bIsFBX) { #if WITH_APEX_CLOTHING FClothingBackup ClothingBackup; if(LODLevel == 0) { ApexClothingUtils::BackupClothingDataFromSkeletalMesh(SelectedSkelMesh, ClothingBackup); } #endif// #if WITH_APEX_CLOTHING UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance(); // don't import material and animation UnFbx::FBXImportOptions* ImportOptions = FFbxImporter->GetImportOptions(); ImportOptions->bImportMaterials = false; ImportOptions->bImportTextures = false; ImportOptions->bImportAnimations = false; if ( !FFbxImporter->ImportFromFile( *Filename, FPaths::GetExtension( Filename ) ) ) { // Log the error message and fail the import. FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, LOCTEXT("FBXImport_ParseFailed", "FBX file parsing failed.")), FFbxErrors::Generic_FBXFileParseFailed); } else { bool bUseLODs = true; int32 MaxLODLevel = 0; TArray< TArray<FbxNode*>* > MeshArray; TArray<FString> LODStrings; TArray<FbxNode*>* MeshObject = NULL;; // Populate the mesh array FFbxImporter->FillFbxSkelMeshArrayInScene(FFbxImporter->Scene->GetRootNode(), MeshArray, false); // Nothing found, error out if (MeshArray.Num() == 0) { FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, LOCTEXT("FBXImport_NoMesh", "No meshes were found in file.")), FFbxErrors::Generic_MeshNotFound); FFbxImporter->ReleaseScene(); return; } MeshObject = MeshArray[0]; // check if there is LODGroup for this skeletal mesh for (int32 j = 0; j < MeshObject->Num(); j++) { FbxNode* Node = (*MeshObject)[j]; if (Node->GetNodeAttribute() && Node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eLODGroup) { // get max LODgroup level if (MaxLODLevel < (Node->GetChildCount() - 1)) { MaxLODLevel = Node->GetChildCount() - 1; } } } // No LODs found, switch to supporting a mesh array containing meshes instead of LODs if (MaxLODLevel == 0) { bUseLODs = false; MaxLODLevel = SelectedSkelMesh->LODInfo.Num(); } // Create LOD dropdown strings LODStrings.AddZeroed(MaxLODLevel + 1); LODStrings[0] = FString::Printf( TEXT("Base") ); for(int32 i = 1; i < MaxLODLevel + 1; i++) { LODStrings[i] = FString::Printf(TEXT("%d"), i); } int32 SelectedLOD = LODLevel; if (SelectedLOD > SelectedSkelMesh->LODInfo.Num()) { // Make sure they don't manage to select a bad LOD index FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, FText::Format(LOCTEXT("FBXImport_InvalidLODIdx", "Invalid mesh LOD index {0}, no prior LOD index exists"), FText::AsNumber(SelectedLOD))), FFbxErrors::Generic_Mesh_LOD_InvalidIndex); } else { TArray<FbxNode*> SkelMeshNodeArray; if (bUseLODs || ImportOptions->bImportMorph) { for (int32 j = 0; j < MeshObject->Num(); j++) { FbxNode* Node = (*MeshObject)[j]; if (Node->GetNodeAttribute() && Node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eLODGroup) { if (Node->GetChildCount() > SelectedLOD) { SkelMeshNodeArray.Add(Node->GetChild(SelectedLOD)); } else // in less some LODGroups have less level, use the last level { SkelMeshNodeArray.Add(Node->GetChild(Node->GetChildCount() - 1)); } } else { SkelMeshNodeArray.Add(Node); } } } // Import mesh USkeletalMesh* TempSkelMesh = NULL; // @todo AssetImportData does this temp skeletal mesh need import data? UFbxSkeletalMeshImportData* TempAssetImportData = NULL; TempSkelMesh = (USkeletalMesh*)FFbxImporter->ImportSkeletalMesh(GetTransientPackage(), bUseLODs? SkelMeshNodeArray: *MeshObject, NAME_None, (EObjectFlags)0, TempAssetImportData); // Add imported mesh to existing model bool bImportSucceeded = false; if( TempSkelMesh ) { bImportSucceeded = FFbxImporter->ImportSkeletalMeshLOD(TempSkelMesh, SelectedSkelMesh, SelectedLOD); // Mark package containing skeletal mesh as dirty. SelectedSkelMesh->MarkPackageDirty(); } if(ImportOptions->bImportMorph) { FFbxImporter->ImportFbxMorphTarget(SkelMeshNodeArray, SelectedSkelMesh, SelectedSkelMesh->GetOutermost(), SelectedLOD); } if (bImportSucceeded) { // Notification of success FNotificationInfo NotificationInfo(FText::GetEmpty()); NotificationInfo.Text = FText::Format(NSLOCTEXT("UnrealEd", "LODImportSuccessful", "Mesh for LOD {0} imported successfully!"), FText::AsNumber(SelectedLOD)); NotificationInfo.ExpireDuration = 5.0f; FSlateNotificationManager::Get().AddNotification(NotificationInfo); } else { // Notification of failure FNotificationInfo NotificationInfo(FText::GetEmpty()); NotificationInfo.Text = FText::Format(NSLOCTEXT("UnrealEd", "LODImportFail", "Failed to import mesh for LOD {0}!"), FText::AsNumber(SelectedLOD)); NotificationInfo.ExpireDuration = 5.0f; FSlateNotificationManager::Get().AddNotification(NotificationInfo); } } // Cleanup for (int32 i=0; i<MeshArray.Num(); i++) { delete MeshArray[i]; } } FFbxImporter->ReleaseScene(); #if WITH_APEX_CLOTHING if(LODLevel == 0) { ApexClothingUtils::ReapplyClothingDataToSkeletalMesh(SelectedSkelMesh, ClothingBackup); } ApexClothingUtils::ReImportClothingSectionsFromClothingAsset(SelectedSkelMesh); #endif// #if WITH_APEX_CLOTHING } }
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; }
HRESULT CStaticMesh::Load_StaticMesh(const char* szFilePath,const char* szFileName, FbxManager* _pFBXManager, FbxIOSettings* _pIOsettings, FbxScene* _pFBXScene, FbxImporter* _pImporter) { HRESULT hr = E_FAIL; vector<UINT> vecIndeces; string strFullPath; strFullPath.clear(); strFullPath = szFilePath; strFullPath += szFileName;//경로에 파일이름 추가 if (!(_pImporter->Initialize(strFullPath.c_str(), -1, _pFBXManager->GetIOSettings()))) FAILED_CHECK_MSG(E_FAIL, L"Static Mesh Init Failed"); if (!(_pImporter->Import(_pFBXScene))) FAILED_CHECK_MSG(E_FAIL, L"Static Mesh Import Failed"); FbxGeometryConverter clsConverter(_pFBXManager); clsConverter.Triangulate(_pFBXScene, false); FbxNode* pRootNode = _pFBXScene->GetRootNode(); if (!pRootNode) return E_FAIL; vector<VTXTEX> vecVTXTEX; for (int i = 0; i < pRootNode->GetChildCount(); ++i) { FbxNode* pChildNode = pRootNode->GetChild(i); if (pChildNode->GetNodeAttribute() == NULL) continue; FbxNodeAttribute::EType AttributeType = pChildNode->GetNodeAttribute()->GetAttributeType(); if (AttributeType != FbxNodeAttribute::eMesh) continue; FbxMesh* pMesh = (FbxMesh*)pChildNode->GetNodeAttribute(); // 임폴트 하려는 메쉬의 데이터 D3DXVECTOR3 vPos; D3DXVECTOR2 vOutUV; D3DXVECTOR3 vOutNormal; FbxVector4* mControlPoints = pMesh->GetControlPoints(); int iVTXCounter = 0; for (int j = 0; j < pMesh->GetPolygonCount(); j++) // 폴리곤의 인덱스 { int iNumVertices = pMesh->GetPolygonSize(j); assert(iNumVertices == 3); FbxGeometryElementUV* VtxUV = pMesh->GetElementUV(0); FbxGeometryElementNormal* VtxNormal = pMesh->GetElementNormal(0); for (int k = 0; k < iNumVertices; k++) // 폴리곤을 구성하는 버텍스의 인덱스 { //정점 데이터 얻는곳 int iControlPointIndex = pMesh->GetPolygonVertex(j, k); // 컨트롤 포인트 = 하나의 버텍스 int iTextureUVIndex = pMesh->GetTextureUVIndex(j, k); // Control = Vertex //int iNormalIndex = pMesh->GetPolygonVertexIndex(j, k); ++iVTXCounter; vPos.x = (float)mControlPoints[iControlPointIndex].mData[0]; vPos.y = -(float)mControlPoints[iControlPointIndex].mData[1]; vPos.z = (float)mControlPoints[iControlPointIndex].mData[2]; //uv 얻기 switch (VtxUV->GetMappingMode()) // UV값 추출 { case FbxGeometryElement::eByControlPoint: // 하나의 컨트롤 포인트가 하나의 노멀벡터를 가질때 switch (VtxUV->GetReferenceMode()) { case FbxGeometryElement::eDirect: { vOutUV.x = static_cast<float>(VtxUV->GetDirectArray().GetAt(iControlPointIndex).mData[0]); vOutUV.y = static_cast<float>(VtxUV->GetDirectArray().GetAt(iControlPointIndex).mData[1]); } break; case FbxGeometryElement::eIndexToDirect: { int index = VtxUV->GetIndexArray().GetAt(iControlPointIndex); vOutUV.x = static_cast<float>(VtxUV->GetDirectArray().GetAt(index).mData[0]); vOutUV.y = static_cast<float>(VtxUV->GetDirectArray().GetAt(index).mData[1]); } break; default: throw std::exception("Invalid Reference"); } break; case FbxGeometryElement::eByPolygonVertex: // Sharp Edge 포인트가 존재할때 고로 우리가 실질적으로 쓰는곳 switch (VtxUV->GetReferenceMode()) { case FbxGeometryElement::eDirect: { vOutUV.x = static_cast<float>(VtxUV->GetDirectArray().GetAt(iTextureUVIndex).mData[0]); vOutUV.y = 1 - static_cast<float>(VtxUV->GetDirectArray().GetAt(iTextureUVIndex).mData[1]); } case FbxGeometryElement::eIndexToDirect: { vOutUV.x = static_cast<float>(VtxUV->GetDirectArray().GetAt(iTextureUVIndex).mData[0]); vOutUV.y = 1 - static_cast<float>(VtxUV->GetDirectArray().GetAt(iTextureUVIndex).mData[1]); } break; default: throw std::exception("invalid Reference"); } break; default: throw std::exception("Invalid Reference"); break; } //노멀얻기 switch (VtxNormal->GetMappingMode()) // 노멀값 추출 { case FbxGeometryElement::eByControlPoint: // 하나의 컨트롤 포인트가 하나의 노멀벡터를 가질때 switch (VtxNormal->GetReferenceMode()) { case FbxGeometryElement::eDirect: { vOutNormal.x = static_cast<float>(VtxNormal->GetDirectArray().GetAt(iControlPointIndex).mData[0]); vOutNormal.y = static_cast<float>(VtxNormal->GetDirectArray().GetAt(iControlPointIndex).mData[1]); vOutNormal.z = static_cast<float>(VtxNormal->GetDirectArray().GetAt(iControlPointIndex).mData[2]); } break; case FbxGeometryElement::eIndexToDirect: { int index = VtxNormal->GetIndexArray().GetAt(iControlPointIndex); vOutNormal.x = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[0]); vOutNormal.y = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[1]); vOutNormal.z = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[2]); } break; default: throw std::exception("Invalid Reference"); } break; case FbxGeometryElement::eByPolygonVertex: // Sharp Edge 포인트가 존재할때 고로 우리가 실질적으로 쓰는곳 switch (VtxNormal->GetReferenceMode()) { case FbxGeometryElement::eDirect: { int index = VtxNormal->GetIndexArray().GetAt(iVTXCounter); vOutNormal.x = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[0]); vOutNormal.y = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[1]); vOutNormal.z = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[2]); } case FbxGeometryElement::eIndexToDirect: { int index = VtxNormal->GetIndexArray().GetAt(iVTXCounter); vOutNormal.x = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[0]); vOutNormal.y = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[1]); vOutNormal.z = static_cast<float>(VtxNormal->GetDirectArray().GetAt(index).mData[2]); } break; default: throw std::exception("invalid Reference"); } break; default: throw std::exception("Invalid Reference"); break; } VTXTEX vtxtex; vtxtex.vPos = vPos; vtxtex.vNormal = vOutNormal; vtxtex.vTexUV = vOutUV; vecVTXTEX.push_back(vtxtex); //int index = VtxUV->GetIndexArray().GetAt(iTextureUVIndex); vecIndeces.push_back(VtxUV->GetIndexArray().GetAt(iTextureUVIndex)); } } } unsigned int n = vecVTXTEX.size(); VTXTEX* pVTXTex = new VTXTEX[n]; for (unsigned int i = 0; i < vecVTXTEX.size(); ++i) { pVTXTex[i].vPos = vecVTXTEX[i].vPos; pVTXTex[i].vNormal = vecVTXTEX[i].vNormal; pVTXTex[i].vTexUV = vecVTXTEX[i].vTexUV; } m_iVertices = vecVTXTEX.size(); m_iVertexStrides = sizeof(VTXTEX); m_iVertexOffsets = 0; MakeVertexNormal((BYTE*)pVTXTex, NULL); D3D11_BUFFER_DESC tBufferDesc; ZeroMemory(&tBufferDesc, sizeof(D3D11_BUFFER_DESC)); tBufferDesc.Usage = D3D11_USAGE_DEFAULT; tBufferDesc.ByteWidth = m_iVertexStrides * m_iVertices; tBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; tBufferDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA tData; ZeroMemory(&tData, sizeof(D3D11_SUBRESOURCE_DATA)); tData.pSysMem = pVTXTex; hr = CDevice::GetInstance()->m_pDevice->CreateBuffer(&tBufferDesc, &tData, &m_VertexBuffer); ::Safe_Delete(pVTXTex); if (FAILED(hr)) return E_FAIL; D3D11_BUFFER_DESC cbd; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.ByteWidth = sizeof(ConstantBuffer); cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbd.CPUAccessFlags = 0; cbd.MiscFlags = 0; cbd.StructureByteStride = 0; hr = CDevice::GetInstance()->m_pDevice->CreateBuffer(&cbd, NULL, &m_ConstantBuffer); if (FAILED(hr)) { MessageBox(NULL, L"System Message", L"Constant Buffer Error", MB_OK); return hr; } return S_OK; }
HRESULT FBXLoader::loadFBXFile(char* filePath, VertexBuffer** vBuf, IndexBuffer** iBuf, Renderer* renderer, bool centerShift) { if (g_pFbxSdkManager == nullptr) { g_pFbxSdkManager = FbxManager::Create(); FbxIOSettings* pIOsettings = FbxIOSettings::Create(g_pFbxSdkManager, IOSROOT); g_pFbxSdkManager->SetIOSettings(pIOsettings); } this->shiftCenter = centerShift; FbxImporter* pImporter = FbxImporter::Create(g_pFbxSdkManager, ""); FbxScene* pFbxScene = FbxScene::Create(g_pFbxSdkManager, ""); bool bSuccess = pImporter->Initialize(filePath, -1, g_pFbxSdkManager->GetIOSettings()); if (!bSuccess) return E_FAIL; bSuccess = pImporter->Import(pFbxScene); if (!bSuccess) return E_FAIL; FbxAxisSystem sceneAxisSystem = pFbxScene->GetGlobalSettings().GetAxisSystem(); FbxAxisSystem DirectXAxisSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded); if (sceneAxisSystem != DirectXAxisSystem) { DirectXAxisSystem.ConvertScene(pFbxScene); } pImporter->Destroy(); FbxNode* pFbxRootNode = pFbxScene->GetRootNode(); if (pFbxRootNode) { // Check if the getChildCount is > 1 TODO int test = pFbxRootNode->GetChildCount(); for (int i = 0; i < pFbxRootNode->GetChildCount(); i++) { FbxNode* pFbxChildNode = pFbxRootNode->GetChild(i); if (pFbxChildNode->GetNodeAttribute() == NULL) continue; FbxNodeAttribute::EType AttributeType = pFbxChildNode->GetNodeAttribute()->GetAttributeType(); if (AttributeType != FbxNodeAttribute::eMesh) continue; FbxMesh* pMesh = (FbxMesh*)pFbxChildNode->GetNodeAttribute(); int numControlPoints = pMesh->GetControlPointsCount(); bool initial = true; float xMin, yMin, zMin; float xMax, yMax, zMax; float xIn, yIn, zIn; float xCenter, yCenter, zCenter; if (this->shiftCenter){ for (int c = 0; c < numControlPoints; c++) { xIn = (float)pMesh->GetControlPointAt(c).mData[0]; yIn = (float)pMesh->GetControlPointAt(c).mData[1]; zIn = (float)pMesh->GetControlPointAt(c).mData[2]; if (initial) { xMin = xIn; yMin = yIn; zMin = zIn; xMax = xIn; yMax = yIn; zMax = zIn; initial = false; } else { if (xIn < xMin) { xMin = xIn; } if (yIn < yMin) { yMin = yIn; } if (zIn < zMin) { zMin = zIn; } if (xIn > xMax) { xMax = xIn; } if (yIn > yMax) { yMax = yIn; } if (zIn > zMax) { zMax = zIn; } } } xCenter = (xMin + xMax) / 2.0f; yCenter = (yMin + yMax) / 2.0f; zCenter = (zMin + zMax) / 2.0f; } else { xCenter = 0; yCenter = 0; zCenter = 0; } FbxVector4* pVertices = pMesh->GetControlPoints(); int vertexCount = pMesh->GetPolygonVertexCount(); //Vertex vertex; Vertex* vertexArray = new Vertex[vertexCount]; //Vertex vertexArray[2592]; int numIndices = vertexCount; unsigned int* indexArray = new unsigned int[numIndices]; FbxVector4 fbxNorm(0, 0, 0, 0); FbxVector2 fbxUV(0, 0); bool isMapped; int vertexIndex = 0; // Loop iterates through the polygons and fills the vertex and index arrays for the buffers for (int j = 0; j < pMesh->GetPolygonCount(); j++) { int iNumVertices = pMesh->GetPolygonSize(j); assert(iNumVertices == 3); //1st vertex int controlIndex = pMesh->GetPolygonVertex(j, 2); pMesh->GetPolygonVertexUV(j, 2, "map1", fbxUV, isMapped); pMesh->GetPolygonVertexNormal(j, 2, fbxNorm); vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter; vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter; vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter; vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0]; vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1]; vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0]; vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1]; vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2]; indexArray[vertexIndex] = vertexIndex; vertexIndex++; //2nd vertex controlIndex = pMesh->GetPolygonVertex(j, 1); pMesh->GetPolygonVertexUV(j, 1, "map1", fbxUV, isMapped); pMesh->GetPolygonVertexNormal(j, 1, fbxNorm); vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter; vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter; vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter; vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0]; vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1]; vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0]; vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1]; vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2]; indexArray[vertexIndex] = vertexIndex; vertexIndex++; //3rd vertex controlIndex = pMesh->GetPolygonVertex(j, 0); pMesh->GetPolygonVertexUV(j, 0, "map1", fbxUV, isMapped); pMesh->GetPolygonVertexNormal(j, 0, fbxNorm); vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter; vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter; vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter; vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0]; vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1]; vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0]; vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1]; vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2]; indexArray[vertexIndex] = vertexIndex; vertexIndex++; } // Generate vertex and index buffers from the vertex and index arrays *vBuf = renderer->createVertexBuffer(vertexArray, vertexCount); *iBuf = renderer->createIndexBuffer(indexArray, numIndices); delete[] vertexArray; delete[] indexArray; } } return S_OK; }
FBXSceneImporter::FBXSceneImporter(std::string file_name) { std::string log_file_name = file_name; log_file_name.append("log.txt"); myfile.open(log_file_name.c_str()); // Initialize the SDK manager. This object handles memory management. lSdkManager = FbxManager::Create(); FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT); lSdkManager->SetIOSettings(ios); // Create an importer using the SDK manager. FbxImporter* lImporter = FbxImporter::Create(lSdkManager, ""); // Use the first argument as the filename for the importer. if (!lImporter->Initialize(file_name.c_str(), -1, lSdkManager->GetIOSettings())) { myfile << "Call to FbxImporter::Initialize() failed.\n"; myfile << "Error returned: " << lImporter->GetStatus().GetErrorString() << ""; myfile.close(); exit(-1); } // Create a new scene so that it can be populated by the imported file. lScene = FbxScene::Create(lSdkManager, "myScene"); // Import the contents of the file into the scene. lImporter->Import(lScene); // The file is imported, so get rid of the importer. lImporter->Destroy(); FbxGeometryConverter converter(lSdkManager); converter.Triangulate(lScene, true); scene_to_fill = new Scene(Utilities::get_file_name_from_path_wo_extension(file_name)); resource_manager.add_scene(scene_to_fill); // 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(); if (lRootNode) { for (int i = 0; i < lRootNode->GetChildCount(); i++) { read_node(lRootNode->GetChild(i)); } } if (lRootNode) { for (int i = 0; i < lRootNode->GetChildCount(); i++) { PrintNode(lRootNode->GetChild(i)); } } // Destroy the SDK manager and all the other objects it was handling. myfile.close(); lSdkManager->Destroy(); }
UObject* UFbxFactory::RecursiveImportNode(void* VoidFbxImporter, void* VoidNode, UObject* InParent, FName InName, EObjectFlags Flags, int32& NodeIndex, int32 Total, TArray<UObject*>& OutNewAssets) { UObject* NewObject = NULL; FbxNode* Node = (FbxNode*)VoidNode; if (Node->GetNodeAttribute() && Node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eLODGroup && Node->GetChildCount() > 0 ) { // import base mesh NewObject = ImportANode(VoidFbxImporter, Node->GetChild(0), InParent, InName, Flags, NodeIndex, Total); if ( NewObject ) { OutNewAssets.Add(NewObject); } bool bImportMeshLODs; if ( ImportUI->MeshTypeToImport == FBXIT_StaticMesh ) { bImportMeshLODs = ImportUI->StaticMeshImportData->bImportMeshLODs; } else if ( ImportUI->MeshTypeToImport == FBXIT_SkeletalMesh ) { bImportMeshLODs = ImportUI->SkeletalMeshImportData->bImportMeshLODs; } else { bImportMeshLODs = false; } if (NewObject && bImportMeshLODs) { // import LOD meshes for (int32 LODIndex = 1; LODIndex < Node->GetChildCount(); LODIndex++) { FbxNode* ChildNode = Node->GetChild(LODIndex); ImportANode(VoidFbxImporter, ChildNode, InParent, InName, Flags, NodeIndex, Total, NewObject, LODIndex); } } } else { if (Node->GetMesh()) { NewObject = ImportANode(VoidFbxImporter, Node, InParent, InName, Flags, NodeIndex, Total); if ( NewObject ) { OutNewAssets.Add(NewObject); } } for (int32 ChildIndex=0; ChildIndex<Node->GetChildCount(); ++ChildIndex) { UObject* SubObject = RecursiveImportNode(VoidFbxImporter,Node->GetChild(ChildIndex),InParent,InName,Flags,NodeIndex,Total,OutNewAssets); if ( SubObject ) { OutNewAssets.Add(SubObject); } if (NewObject==NULL) { NewObject = SubObject; } } } return NewObject; }