// Add the specified node to the node array. Also, add recursively // all the parent node of the specified node to the array. void AddNodeRecursively(FbxArray<FbxNode*>& pNodeArray, FbxNode* pNode) { if (pNode) { AddNodeRecursively(pNodeArray, pNode->GetParent()); if (pNodeArray.Find(pNode) == -1) { // Node not in the list, add it pNodeArray.Add(pNode); } } }
// メッシュ情報処理(再帰関数) 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); } }
// Find all poses in this scene. void FillPoseArray(FbxScene* pScene, FbxArray<FbxPose*>& pPoseArray) { const int lPoseCount = pScene->GetPoseCount(); for (int i=0; i < lPoseCount; ++i) { pPoseArray.Add(pScene->GetPose(i)); } }
void FBXFillMeshArrayRecursive( FbxNode* pNode, FbxArray<FbxMesh*>& pMeshArray ) { if( pNode ) { if( pNode->GetNodeAttribute() ) { if( pNode->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh ) { pMeshArray.Add( pNode->GetMesh() ); } } const int lCount = pNode->GetChildCount(); for( int i = 0; i < lCount; i++ ) FBXFillMeshArrayRecursive( pNode->GetChild(i), pMeshArray ); } }
void FBXFillCameraArrayRecursive( FbxNode* pNode, FbxArray<FbxNode*>& pCameraArray) { if( pNode ) { if( pNode->GetNodeAttribute() ) { if( pNode->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eCamera ) { pCameraArray.Add( pNode ); } } const int lCount = pNode->GetChildCount(); for( int i = 0; i < lCount; i++ ) FBXFillCameraArrayRecursive( pNode->GetChild(i), pCameraArray ); } }
void FBXScene::ProcessAnimations(FbxScene* pScene) { m_pAnimationController = new AnimationController(); FbxNode* pRootNode = pScene->GetRootNode(); if(!pRootNode) return; float fFrameRate = (float)FbxTime::GetFrameRate(pScene->GetGlobalSettings().GetTimeMode()); FbxArray<FbxString*> takeArray; FbxDocument* pDocument = FbxCast<FbxDocument>(pScene); // dynamic_cast<FbxDocument*>(pScene); if( pDocument ) pDocument->FillAnimStackNameArray(takeArray); for( int i = 0; i < takeArray.GetCount(); ++i ) { FbxString* takeName = takeArray.GetAt(i); if( std::string(takeName->Buffer()) != "Default" ) { /// ARRRGHHH SÄTTER ALLTID FÖRSTA HÄR!!!!!!!!!!!!!!!!!! FbxTakeInfo* lCurrentTakeInfo = pScene->GetTakeInfo(takeName->Buffer()); FbxAnimStack* lAnimStack = FbxCast<FbxAnimStack>(pScene->GetSrcObject<FbxAnimStack>(i)); pScene->GetEvaluator()->SetContext(lAnimStack); FbxTime KStart; FbxTime KStop; if(lCurrentTakeInfo) { KStart = lCurrentTakeInfo->mLocalTimeSpan.GetStart(); KStop = lCurrentTakeInfo->mLocalTimeSpan.GetStop(); } else { // Take the time line value FbxTimeSpan lTimeLineTimeSpan; pScene->GetGlobalSettings().GetTimelineDefaultTimeSpan(lTimeLineTimeSpan); KStart = lTimeLineTimeSpan.GetStart(); KStop = lTimeLineTimeSpan.GetStop(); } float fStart = (float)KStart.GetSecondDouble(); float fStop = (float)KStop.GetSecondDouble(); if( fStart < fStop ) { int nKeyFrames = int((fStop-fStart)*fFrameRate); Animation* pAnimation = new Animation(takeName->Buffer(), nKeyFrames, fFrameRate); m_pAnimationController->AddAnimation(pAnimation); ProcessAnimation(pRootNode, takeName->Buffer(), fFrameRate, fStart, fStop); } } delete takeName; } takeArray.Clear(); }
/** * Add a bind pose to the scene based on the FbxMesh and skinning settings of the given node */ void FFbxExporter::CreateBindPose(FbxNode* MeshRootNode) { if (!MeshRootNode) { return; } // In the bind pose, we must store all the link's global matrix at the time of the bind. // Plus, we must store all the parent(s) global matrix of a link, even if they are not // themselves deforming any model. // Create a bind pose with the link list FbxArray<FbxNode*> lClusteredFbxNodes; int i, j; if (MeshRootNode->GetNodeAttribute()) { int lSkinCount=0; int lClusterCount=0; switch (MeshRootNode->GetNodeAttribute()->GetAttributeType()) { case FbxNodeAttribute::eMesh: case FbxNodeAttribute::eNurbs: case FbxNodeAttribute::ePatch: lSkinCount = ((FbxGeometry*)MeshRootNode->GetNodeAttribute())->GetDeformerCount(FbxDeformer::eSkin); //Go through all the skins and count them //then go through each skin and get their cluster count for(i=0; i<lSkinCount; ++i) { FbxSkin *lSkin=(FbxSkin*)((FbxGeometry*)MeshRootNode->GetNodeAttribute())->GetDeformer(i, FbxDeformer::eSkin); lClusterCount+=lSkin->GetClusterCount(); } break; } //if we found some clusters we must add the node if (lClusterCount) { //Again, go through all the skins get each cluster link and add them for (i=0; i<lSkinCount; ++i) { FbxSkin *lSkin=(FbxSkin*)((FbxGeometry*)MeshRootNode->GetNodeAttribute())->GetDeformer(i, FbxDeformer::eSkin); lClusterCount=lSkin->GetClusterCount(); for (j=0; j<lClusterCount; ++j) { FbxNode* lClusterNode = lSkin->GetCluster(j)->GetLink(); AddNodeRecursively(lClusteredFbxNodes, lClusterNode); } } // Add the patch to the pose lClusteredFbxNodes.Add(MeshRootNode); } } // Now create a bind pose with the link list if (lClusteredFbxNodes.GetCount()) { // A pose must be named. Arbitrarily use the name of the patch node. FbxPose* lPose = FbxPose::Create(Scene, MeshRootNode->GetName()); // default pose type is rest pose, so we need to set the type as bind pose lPose->SetIsBindPose(true); for (i=0; i<lClusteredFbxNodes.GetCount(); i++) { FbxNode* lKFbxNode = lClusteredFbxNodes.GetAt(i); FbxMatrix lBindMatrix = lKFbxNode->EvaluateGlobalTransform(); lPose->Add(lKFbxNode, lBindMatrix); } // Add the pose to the scene Scene->AddPose(lPose); } }
FbxModelData* FBXLoader::loadModel( const char* aFile ) { FBX_LOG("FBXLoader Creating ModelData..."); myLoadingModel = new FbxModelData; FBX_LOG("Success!"); FBX_LOG("FBXLoader Creating TextureData..."); myLoadingModel->myTextureData = new TextureData(); FBX_LOG("Success!"); FBX_LOG("FBXLoader Loading Scene..."); auto scene = LoadScene(aFile); FBX_LOG("Successfully loaded scene!"); FBX_LOG("FBXLoader Loading Textures..."); //TextureData const int lTextureCount = scene->GetTextureCount(); for (int lTextureIndex = 0; lTextureIndex < lTextureCount; ++lTextureIndex) { FbxTexture * lTexture = scene->GetTexture(lTextureIndex); FbxFileTexture * lFileTexture = reinterpret_cast<FbxFileTexture*>(lTexture); if (lFileTexture && !lFileTexture->GetUserDataPtr()) { const FbxString lFileName = lFileTexture->GetFileName(); unsigned int lTextureObject = 0; lTextureObject; bool lStatus = false; lStatus; const FbxString lAbsFbxFileName = FbxPathUtils::Resolve(aFile); const FbxString lAbsFolderName = FbxPathUtils::GetFolderName(lAbsFbxFileName); const FbxString lTextureFileName = lAbsFolderName + "\\" + lFileTexture->GetRelativeFileName();// FbxPathUtils::GetFileName(lFileName); const FbxString lResolvedFileName = lAbsFolderName + "\\" + FbxPathUtils::GetFileName(lFileName);// lFileTexture->GetRelativeFileName();;// FbxPathUtils::Bind(lAbsFolderName, lTextureFileName); TextureInfo info; info.myFileName = lResolvedFileName; //info.myFileName += "\\"; info.myFileName = lFileTexture->GetRelativeFileName(); myLoadingModel->myTextureData->myTextures.push_back(info); lFileTexture->SetFileName(lResolvedFileName); } } FBX_LOG("Success!"); FBX_LOG("FBXLoader Loading Animations..."); FbxArray<FbxString*> animationNames; FbxArray<FbxPose*> poses; scene->FillAnimStackNameArray(animationNames); scene->FillPoseArray(poses); FbxAnimStack * lCurrentAnimationStack = nullptr; FbxAnimLayer* lCurrentAnimLayer = nullptr; if(animationNames.GetCount() > 0) { lCurrentAnimationStack = scene->FindMember<FbxAnimStack>(animationNames[0]->Buffer()); if (lCurrentAnimationStack != NULL) { lCurrentAnimLayer = lCurrentAnimationStack->GetMember<FbxAnimLayer>(); } } //lCurrentAnimLayer->IsR myLoadingModel->myAnimation = new AnimationData(); FbxPose* pose = nullptr; if(poses.GetCount() > 0) { pose = poses[0]; } LoadAnimation(*myLoadingModel->myAnimation,scene->GetRootNode(),FbxAMatrix(),pose, lCurrentAnimLayer,-1); LoadNodeRecursive(myLoadingModel, *myLoadingModel->myAnimation, scene->GetRootNode(), FbxAMatrix(), pose, lCurrentAnimLayer, -1); FBX_LOG("Success!"); return myLoadingModel; }
// Find all the cameras in this scene. void FillCameraArray(FbxScene* pScene, FbxArray<FbxNode*>& pCameraArray) { pCameraArray.Clear(); FillCameraArrayRecursive(pScene->GetRootNode(), pCameraArray); }
void GeometryLoaderDX11::loadFBXFile( std::string szFilename, std::vector<GeometryPtr>& vGeomVector, std::vector<std::string>& vNames ) { FileSystem fs; szFilename = fs.GetModelsFolderS() + szFilename; pFBXManager = FbxManager::Create(); if( !pFBXManager ) Log::Get().Write( L"CGeometryLoader11.cpp: Error creating FBX Manager!" ); FbxIOSettings* pIOS = FbxIOSettings::Create( pFBXManager, IOSROOT ); pFBXManager->SetIOSettings( pIOS ); FbxString lPath = FbxGetApplicationDirectory(); pFBXManager->LoadPluginsDirectory( lPath.Buffer() ); FbxScene* pScene = FbxScene::Create( pFBXManager, "" ); int /*nFileMajor,*/ nFileMinor, nFileRevision; int nSDKMajor, nSDKMinor, nSDKRevision; int i, /*nAnimationStack,*/ lFileFormat; // bool bStatus; // char szPassword[1024]; FbxManager::GetFileFormatVersion( nSDKMajor, nSDKMinor, nSDKRevision ); FbxImporter* pImporter = FbxImporter::Create( pFBXManager, "" ); if (!pFBXManager->GetIOPluginRegistry()->DetectReaderFileFormat(szFilename.c_str(), lFileFormat) ) { // Unrecognizable file format. Try to fall back to FbxImporter::eFBX_BINARY lFileFormat = pFBXManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary (*.fbx)" );; } bool ImportStatus = pImporter->Initialize( szFilename.c_str(), lFileFormat, pFBXManager->GetIOSettings() ); pImporter->GetFileVersion( nFileMinor, nFileMinor, nFileRevision ); if( !ImportStatus ) { Log::Get().Write( L"CGeometryLoader11.cpp: FbxImporter Initialize failed!" ); return; } ImportStatus = pImporter->Import( pScene ); if( !ImportStatus ) { Log::Get().Write( L"CGeometryLoader11.cpp: FbxImporter failed to import the file to the scene!" ); return; } FbxAxisSystem SceneAxisSystem = pScene->GetGlobalSettings().GetAxisSystem(); FbxAxisSystem AxisSystem( FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded ); if( SceneAxisSystem != AxisSystem ) { AxisSystem.ConvertScene( pScene ); } //FbxSystemUnit SceneSystemUnit = pScene->GetGlobalSettings().GetSystemUnit(); //if( SceneSystemUnit.GetScaleFactor() != 1.0f ) // FbxSystemUnit::cm.ConvertScene( pScene ); FBXTriangulateRecursive( pScene->GetRootNode() ); FbxArray<FbxMesh*> vMeshs; FBXFillMeshArray( pScene, vMeshs ); unsigned short usVertexCount = 0; unsigned short usTriangleCount = 0; unsigned short usGroupCount = 0; unsigned short usMaterialCount = 0; unsigned short usIndicesCount = 0; for( i = 0; i < vMeshs.GetCount(); i++ ) { Log::Get().Write( L"CGeometryLoader11.cpp: Loading File!" ); std::string name = vMeshs[i]->GetNode()->GetName(); vNames.push_back( name ); usVertexCount = vMeshs[i]->GetControlPointsCount(); if( usVertexCount == 0 ) continue; usTriangleCount = vMeshs[i]->GetPolygonVertexCount() / 3; usIndicesCount = vMeshs[i]->GetPolygonVertexCount(); VertexElementDX11* pPositions = new VertexElementDX11( 3, usTriangleCount * 3 ); pPositions->m_SemanticName = VertexElementDX11::PositionSemantic; pPositions->m_uiSemanticIndex = 0; pPositions->m_Format = DXGI_FORMAT_R32G32B32_FLOAT; pPositions->m_uiInputSlot = 0; pPositions->m_uiAlignedByteOffset = 0; pPositions->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pPositions->m_uiInstanceDataStepRate = 0; VertexElementDX11* pTexCoords = new VertexElementDX11( 2, usTriangleCount * 3 ); pTexCoords->m_SemanticName = VertexElementDX11::TexCoordSemantic; pTexCoords->m_uiSemanticIndex = 0; pTexCoords->m_Format = DXGI_FORMAT_R32G32_FLOAT; pTexCoords->m_uiInputSlot = 0; pTexCoords->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pTexCoords->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pTexCoords->m_uiInstanceDataStepRate = 0; VertexElementDX11* pNormals = new VertexElementDX11( 3, usTriangleCount * 3 ); pNormals->m_SemanticName = VertexElementDX11::NormalSemantic; pNormals->m_uiSemanticIndex = 0; pNormals->m_Format = DXGI_FORMAT_R32G32B32_FLOAT; pNormals->m_uiInputSlot = 0; pNormals->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pNormals->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pNormals->m_uiInstanceDataStepRate = 0; Vector3f* pPos = pPositions->Get3f(0); Vector3f* pNorm = pNormals->Get3f(0); Vector2f* pTex = pTexCoords->Get2f(0); FbxVector4* pFBXVerts = new FbxVector4[usVertexCount]; memcpy( pFBXVerts, vMeshs[i]->GetControlPoints(), usVertexCount * sizeof(FbxVector4)); TriangleIndices face; GeometryPtr pGeomPointer( new GeometryDX11() ); for( int j = 0; j < usTriangleCount; j++ ) { int nIndex = 0; FbxVector4 FBXNorm( 0, 0, 0, 0 ); FbxVector2 FBXUV( 0, 0 ); face.P1() = nIndex = vMeshs[i]->GetPolygonVertex( j, 0 ); pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0]; pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1]; pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2]; vMeshs[i]->GetPolygonVertexNormal( j, 0, FBXNorm ); pNorm[nIndex].x = (float)FBXNorm[0]; pNorm[nIndex].y = (float)FBXNorm[1]; pNorm[nIndex].z = (float)FBXNorm[2]; vMeshs[i]->GetPolygonVertexUV( j, 0, "map1", FBXUV ); pTex[nIndex].x = (float)FBXUV[0]; pTex[nIndex].y = (float)FBXUV[1]; face.P2() = nIndex = vMeshs[i]->GetPolygonVertex( j, 1 ); pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0]; pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1]; pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2]; vMeshs[i]->GetPolygonVertexNormal( j, 1, FBXNorm ); pNorm[nIndex].x = (float)FBXNorm[0]; pNorm[nIndex].y = (float)FBXNorm[1]; pNorm[nIndex].z = (float)FBXNorm[2]; vMeshs[i]->GetPolygonVertexUV( j, 1, "map1", FBXUV ); pTex[nIndex].x = (float)FBXUV[0]; pTex[nIndex].y = (float)FBXUV[1]; face.P3() = nIndex = vMeshs[i]->GetPolygonVertex( j, 2 ); pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0]; pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1]; pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2]; vMeshs[i]->GetPolygonVertexNormal( j, 2, FBXNorm ); pNorm[nIndex].x = (float)FBXNorm[0]; pNorm[nIndex].y = (float)FBXNorm[1]; pNorm[nIndex].z = (float)FBXNorm[2]; vMeshs[i]->GetPolygonVertexUV( j, 2, "map1", FBXUV ); pTex[nIndex].x = (float)FBXUV[0]; pTex[nIndex].y = (float)FBXUV[1]; pGeomPointer->AddFace( face ); } for( int j = 0; j < usVertexCount; j++ ) { pNorm[j].Normalize(); } pGeomPointer->AddElement( pPositions ); pGeomPointer->AddElement( pNormals ); pGeomPointer->AddElement( pTexCoords ); delete[] pFBXVerts; vGeomVector.push_back( pGeomPointer ); vMeshs[i]->Destroy(); vMeshs[i] = NULL; } pImporter->Destroy(); pImporter = NULL; pScene->Destroy(); pScene = NULL; pIOS->Destroy(); pIOS = NULL; pFBXManager->Destroy(); pFBXManager = NULL; }
void FBXFillMeshArray( FbxScene* pScene, FbxArray<FbxMesh*>& pMeshArray ) { pMeshArray.Clear(); FBXFillMeshArrayRecursive( pScene->GetRootNode(), pMeshArray ); }