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 fbxLoader2::setBindPoseCluster(FbxNode *node) { if( node->GetNodeAttribute()) { switch(node->GetNodeAttribute()->GetAttributeType()) { case FbxNodeAttribute::eMesh: FbxMesh *mesh = node->GetMesh(); for (int j = 0; j<mesh->GetDeformerCount(); j++) { FbxSkin *skin = (FbxSkin*) mesh->GetDeformer(j,FbxDeformer::eSkin); int clusters = skin->GetClusterCount(); for(int k = 0; k<clusters; k++) { FbxCluster* cluster = skin->GetCluster(k); FbxNode* boneLink = cluster->GetLink(); if(boneLink) { std::string nameLink = boneLink->GetName(); FbxAMatrix translationM; FbxAMatrix invert; cluster->GetTransformLinkMatrix(translationM); cluster->GetTransformMatrix(invert); translationM = translationM * invert.Inverse(); D3DXMATRIX mat = D3DXMATRIX((float)translationM.mData[0].mData[0], (float)translationM.mData[0].mData[1], (float)translationM.mData[0].mData[2], (float)translationM.mData[3].mData[0], (float)translationM.mData[1].mData[0], (float)translationM.mData[1].mData[1], (float)translationM.mData[1].mData[2], (float)translationM.mData[3].mData[1], (float)translationM.mData[2].mData[0], (float)translationM.mData[2].mData[1], (float)translationM.mData[2].mData[2], (float)translationM.mData[3].mData[2], 0,0,0,1); skeleton->GetBone(skeleton->GetBoneByName(nameLink))->SetTransformation(mat); } } } break; } } for (int i = 0; i<node->GetChildCount(); i++) { FbxNode* child = node->GetChild(i); setBindPoseCluster(child); } }
Material* FBXScene::GetMaterialLinkedWithPolygon(FbxMesh* pFBXMesh, int nLayerIndex, int nPolygonIndex, int nPolygonVertexIndex, int nVertexIndex) { if( nLayerIndex < 0 || nLayerIndex > pFBXMesh->GetLayerCount() ) return NULL; FbxNode* pNode = pFBXMesh->GetNode(); if( !pNode ) return NULL; FbxLayerElementMaterial* pFBXMaterial = pFBXMesh->GetLayer(nLayerIndex)->GetMaterials(); if( pFBXMaterial ) { int nMappingIndex = GetMappingIndex( pFBXMaterial->GetMappingMode(), nPolygonIndex, 0, nVertexIndex ); if( nMappingIndex < 0 ) return NULL; FbxLayerElement::EReferenceMode referenceMode = pFBXMaterial->GetReferenceMode(); if( referenceMode == FbxLayerElement::EReferenceMode::eDirect ) { if( nMappingIndex < pNode->GetMaterialCount() ) { return GetMaterial(pNode->GetMaterial(nMappingIndex)); } } else if( referenceMode == FbxLayerElement::EReferenceMode::eIndexToDirect ) { const FbxLayerElementArrayTemplate<int>& pMaterialIndexArray = pFBXMaterial->GetIndexArray(); if( nMappingIndex < pMaterialIndexArray.GetCount() ) { int nIndex = pMaterialIndexArray.GetAt(nMappingIndex); if( nIndex < pNode->GetMaterialCount() ) { return GetMaterial(pNode->GetMaterial(nIndex)); } } } } return NULL; }
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); } } } }
FbxNode* ILDLMesh::CreateMesh( FbxScene* pScene, const char* pName ) { int nVerts = (int)m_vertex_list.size(); FbxMesh* lMesh = FbxMesh::Create(pScene,pName); lMesh->InitControlPoints( nVerts ); FbxVector4* lControlPoints = lMesh->GetControlPoints(); FbxGeometryElementNormal* lGeometryElementNormal= lMesh->CreateElementNormal(); lGeometryElementNormal->SetMappingMode(FbxGeometryElement::eByControlPoint); lGeometryElementNormal->SetReferenceMode(FbxGeometryElement::eDirect); int vi = 0, glidx = 0; for( ILDLVertexIter i = m_vertex_list.begin(); i != m_vertex_list.end(); ++i, vi++ ) { ILDLVertexPtr vp = (*i); vp->m_glIdx = glidx; vec3 coords = vp->getCoords(); lControlPoints[vi] = FbxVector4( coords[0], coords[1], coords[2] ); vec3 normal = vp->getNormal(); lGeometryElementNormal->GetDirectArray().Add( FbxVector4( normal[0], normal[1], normal[2] ) ); glidx++; } for( ILDLFaceIter i = m_face_list.begin(); i != m_face_list.end(); ++i ) { ILDLFacePtr fp = *i; ILDLFaceVertexPtr fvp = fp->front(); lMesh->BeginPolygon(-1, -1, -1, false); lMesh->AddPolygon( fvp->getVertexPtr()->m_glIdx ); fvp = fvp->next(); lMesh->AddPolygon( fvp->getVertexPtr()->m_glIdx ); fvp = fvp->next(); lMesh->AddPolygon( fvp->getVertexPtr()->m_glIdx ); lMesh->EndPolygon (); } FbxNode* lNode = FbxNode::Create(pScene,pName); lNode->SetNodeAttribute(lMesh); return lNode; }
void FBXSceneEncoder::loadSkin(FbxMesh* fbxMesh, Model* model) { const int deformerCount = fbxMesh->GetDeformerCount(); for (int i = 0; i < deformerCount; ++i) { FbxDeformer* deformer = fbxMesh->GetDeformer(i); if (deformer->GetDeformerType() == FbxDeformer::eSkin) { FbxSkin* fbxSkin = FbxCast<FbxSkin>(deformer); MeshSkin* skin = new MeshSkin(); vector<string> jointNames; vector<Node*> joints; vector<Matrix> bindPoses; const int clusterCount = fbxSkin->GetClusterCount(); for (int j = 0; j < clusterCount; ++j) { FbxCluster* cluster = fbxSkin->GetCluster(j); assert(cluster); FbxNode* linkedNode = cluster->GetLink(); if (linkedNode && linkedNode->GetSkeleton()) { const char* jointName = linkedNode->GetName(); assert(jointName); jointNames.push_back(jointName); Node* joint = loadNode(linkedNode); assert(joint); joints.push_back(joint); FbxAMatrix matrix; cluster->GetTransformLinkMatrix(matrix); Matrix m; copyMatrix(matrix.Inverse(), m); bindPoses.push_back(m); } } skin->setJointNames(jointNames); skin->setJoints(joints); skin->setBindPoses(bindPoses); model->setSkin(skin); break; } } }
//------------------------------------------------------------------------------------------------------------------------------------------- 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(char* name) { FbxManager* lSdkManager = FbxManager::Create(); FbxIOSettings * ios = FbxIOSettings::Create(lSdkManager, IOSROOT); this->modelName = name; lSdkManager->SetIOSettings(ios); FbxImporter* lImporter = FbxImporter::Create(lSdkManager, ""); std::string path = MODELS_SUBDIR + std::string(name); if (!lImporter->Initialize(path.c_str(), -1, lSdkManager->GetIOSettings())) TriggerCrash("Nie mo¿na znaleœæ modelu!"); FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene"); //pobranie calego fbx'a lImporter->Import(lScene); for (int i = 0; i < lScene->GetRootNode()->GetChildCount(); i++){ //leci po wszystkich modelach w fbx FbxNode* node = lScene->GetRootNode()->GetChild(i); char* texBaseName = (char*) node->GetName(); this->objects.push_back(new ModelObject(node)); } Models.push_back(this); }
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; }
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 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 }
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); } } }
FBX::FBX(FbxScene* lScene) { material_library = new MaterialLibrary(""); // This function show how to cycle through scene elements in a linear way. const int lNodeCount = lScene->GetSrcObjectCount<FbxNode>(); FbxStatus lStatus; for (int lIndex=0; lIndex<lNodeCount; lIndex++) { FbxNode *lNode = lScene->GetSrcObject<FbxNode>(lIndex); printf("Node found: %s\n", lNode->GetName()); FbxMesh *lMesh=lNode->GetMesh(); if (lMesh) { TerrainInstance *terrain_instance=buildTerrainInstanceFromFBX(lNode); instances.push_back(terrain_instance); models.push_back(terrain_instance->getModel()); } } scene = lScene; }
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 MaterialHandler::GetMaterialData(FbxNode * pNode, MaterialExport* outputMat, SceneMap* sceneMap) { //Recursively extract the children for (int j = 0; j < pNode->GetChildCount(); j++) GetMaterialData(pNode->GetChild(j),outputMat,sceneMap); if (outputMat == nullptr) //If the first material is processed. create a new MaterialExport object { outputMat = new MaterialExport; } FbxGeometry* pGeometry = pNode->GetGeometry(); int materialCount = 0; FbxNode* node = NULL; if (pGeometry) { //If the node has any geometry node = pGeometry->GetNode(); if (node) materialCount = pNode->GetMaterialCount(); //Get the amount of materials the geometry has if (materialCount > 0) { for (int i = 0; i < materialCount; i++) { if (pNode->GetMaterial(i)) { FbxSurfaceMaterial *pMaterial = node->GetMaterial(i); //Get the material ProcessData(pMaterial, materialCount, outputMat,sceneMap); //process the data! } } } } }
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 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; }
Node::Node( FbxNode& _Node, Node* _pParent ) : m_Node( _Node ), m_pParent( _pParent ) { FBXSDK_printf( "Node Name: %s\n", _Node.GetName() ); // DisplayUserProperties(&_Node); // DisplayTarget(&_Node); // DisplayPivotsAndLimits(&_Node); // DisplayTransformPropagation(&_Node); // DisplayGeometricTransform(&_Node); FbxVector4 T = _Node.GetGeometricTranslation( FbxNode::eSourcePivot ); FbxVector4 R = _Node.GetGeometricRotation( FbxNode::eSourcePivot ); FbxVector4 S = _Node.GetGeometricScaling( FbxNode::eSourcePivot ); m_Local2Parent.SetTRS( T, R, S ); if ( m_pParent != NULL ) { m_Local2World = m_Local2Parent * m_pParent->m_Local2World; } else m_Local2World = m_Local2Parent; }
void FBXSceneInstance::ProcessSkeleton(FbxNode* pNode) { FbxSkeleton* pFBXSkeleton = pNode->GetSkeleton(); if( !pFBXSkeleton ) return; if( !m_pSkeleton ) { m_pSkeleton = new Skeleton(); } int nParentBoneIndex = -1; FbxNode* pParentNode = pNode->GetParent(); if( pParentNode ) nParentBoneIndex = m_pSkeleton->FindBoneIndex(pParentNode->GetName()); SkeletonBone* pSkeletonBone = new SkeletonBone( pNode->GetName(), nParentBoneIndex, m_pSkeleton ); m_pSkeleton->AddSkeletonBone(pSkeletonBone); int boneIndex = m_pSkeleton->FindBoneIndex(pNode->GetName()); pSkeletonBone->SetBoneIndex(boneIndex); }
void MeshImporter::LoadMesh(FbxScene* scene, ID3D11Device3* device, ID3D11DeviceContext3* context) { PrintTab("Start load meshes"); // Obtain root node FbxNode* root = scene->GetRootNode(); if (root) { // Root node is included numNodes = root->GetChildCount(true) + 1; model->entries.clear(); model->entries.reserve(numNodes); PrintTab("Number of nodes: " + to_string(numNodes)); LoadNodeMesh(root, device, context); } PrintTab("End load meshes"); }
reNode* reFBXAsset::importNode(FbxNode* fbxNode, reNode* parent) { reNode* node = new reNode; node->name(fbxNode->GetName()); FbxMatrix mat = fbxNode->EvaluateGlobalTransform(FbxTime(0)); FbxNode *fbxParent = fbxNode->GetParent(); if (!fbxParent) { node->transform (reTransform(fromFBXMatrix(mat))); } else { FbxMatrix pmat = fbxParent->EvaluateGlobalTransform(FbxTime(0)); node->transform(reTransform(fromFBXMatrix(pmat.Inverse()) * fromFBXMatrix(mat))); } if (fbxNode->GetNodeAttribute() ) { FbxNodeAttribute::EType attrType = (fbxNode->GetNodeAttribute()->GetAttributeType()); switch (attrType) { case FbxNodeAttribute::eMesh: reMesh* mesh = importMesh(fbxNode); node->renderables->add(mesh); break; } } for(int i = 0; i < fbxNode->GetChildCount(); i++) { reNode* child = importNode(fbxNode->GetChild(i), node); node->children->add(child); } return node; };
void MeshImporter::LoadMesh(FbxScene* scene, ID3D11Device3* device, ID3D11DeviceContext3* context) { PrintTab("Start load meshes"); // Obtain root node FbxNode* root = scene->GetRootNode(); assert(scene->GetPoseCount() == 1); model->fbxPose = scene->GetPose(0); if (root) { // Root node is included numNodes = root->GetChildCount(true) + 1; model->numMesh = scene->GetMemberCount<FbxMesh>(); model->entries.clear(); model->entries.reserve(model->numMesh); PrintTab("Number of nodes: " + to_string(numNodes)); //FbxAMatrix fbxGlobalRootTransform = root->EvaluateGlobalTransform(); /*for (int r = 0; r < 4; r++) for (int c = 0; c < 4; c++) { model->globalRootTransform.m[r][c] = fbxGlobalRootTransform.mData[r][c]; }*/ LoadNodeMesh(root, device, context); } PrintTab("End load meshes"); }
// メッシュ情報処理(再帰関数) 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); } }
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(); }
//-------------------------------------------------------------------------------------- void FBXScene::ProcessBoneWeights(FbxSkin* pFBXSkin, std::vector<BoneWeights>& meshBoneWeights) { FbxCluster::ELinkMode linkMode = FbxCluster::eNormalize; //Default link mode std::vector<BoneWeights> skinBoneWeights(meshBoneWeights.size(), BoneWeights()); unsigned int nClusterCount = pFBXSkin->GetClusterCount(); for( unsigned int i = 0; i < nClusterCount; ++i ) { FbxCluster* pFBXCluster = pFBXSkin->GetCluster(i); if( !pFBXCluster ) continue; linkMode = pFBXCluster->GetLinkMode(); FbxNode* pLinkNode = pFBXCluster->GetLink(); if( !pLinkNode ) continue; int nBoneIndex = m_pSkeleton->FindBoneIndex(pLinkNode->GetName()); if( nBoneIndex < 0 ) continue; SkeletonBone* pSkeletonBone = m_pSkeleton->GetSkeletonBone(nBoneIndex); FbxAMatrix matClusterTransformMatrix; FbxAMatrix matClusterLinkTransformMatrix; pFBXCluster->GetTransformMatrix(matClusterTransformMatrix); pFBXCluster->GetTransformLinkMatrix(matClusterLinkTransformMatrix); pSkeletonBone->SetBindPoseTransform2(matClusterLinkTransformMatrix); pSkeletonBone->SetBoneReferenceTransform2(matClusterTransformMatrix); int* indices = pFBXCluster->GetControlPointIndices(); double* weights = pFBXCluster->GetControlPointWeights(); for( int j = 0; j < pFBXCluster->GetControlPointIndicesCount(); ++j ) { skinBoneWeights[indices[j]].AddBoneWeight(nBoneIndex, (float)weights[j]); } } switch(linkMode) { case FbxCluster::eNormalize: //Normalize so weight sum is 1.0. for( unsigned int i = 0; i < skinBoneWeights.size(); ++i ) { skinBoneWeights[i].Normalize(); } break; case FbxCluster::eAdditive: //Not supported yet. Do nothing break; case FbxCluster::eTotalOne: //The weight sum should already be 1.0. Do nothing. break; } for( unsigned int i = 0; i < meshBoneWeights.size(); ++i ) { meshBoneWeights[i].AddBoneWeights(skinBoneWeights[i]); } }
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 } }