void FBXSceneEncoder::loadBindShapes(FbxScene* fbxScene) { float m[16]; const int poseCount = fbxScene->GetPoseCount(); for (int i = 0; i < poseCount; ++i) { FbxPose* pose = fbxScene->GetPose(i); assert(pose); if (pose->IsBindPose() && pose->GetCount() > 0) { FbxNode* fbxNode = pose->GetNode(0); if (fbxNode->GetMesh() != NULL) { Node* node = _gamePlayFile.getNode(fbxNode->GetName()); assert(node && node->getModel()); Model* model = node->getModel(); if (model && model->getSkin()) { MeshSkin* skin = model->getSkin(); copyMatrix(pose->GetMatrix(0), m); skin->setBindShape(m); } } } } }
void SetBindPose() { assert( g_pFBXScene != nullptr ); g_BindPoses.clear(); INT iPoseCount = g_pFBXScene->GetPoseCount(); for( INT i = 0; i < iPoseCount; ++i ) { auto pPose = g_pFBXScene->GetPose( i ); INT iNodeCount = pPose->GetCount(); ExportLog::LogMsg( 4, "Found %spose: \"%s\" with %d nodes", pPose->IsBindPose() ? "bind " : "", pPose->GetName(), iNodeCount ); for( INT j = 0; j < iNodeCount; ++j ) { auto pPoseNode = pPose->GetNode( j ); ExportLog::LogMsg( 5, "Pose node %d: %s", j, pPoseNode->GetName() ); } if( pPose->IsBindPose() ) { g_BindPoses.push_back( pPose ); } } if( g_BindPoses.empty() ) { if( g_pScene->Settings().bExportAnimations ) { ExportLog::LogWarning( "No valid bind pose found; will export scene using the default pose." ); } return; } size_t dwPoseCount = g_BindPoses.size(); for( size_t i = 0; i < dwPoseCount; ++i ) { FbxPose* pPose = g_BindPoses[i]; INT iNodeCount = pPose->GetCount(); for( INT j = 0; j < iNodeCount; ++j ) { auto pNode = pPose->GetNode( j ); auto matNode = pPose->GetMatrix( j ); PoseMap::iterator iter = g_BindPoseMap.find( pNode ); if( iter != g_BindPoseMap.end() ) { FbxMatrix matExisting = iter->second; if( matExisting != matNode ) { ExportLog::LogWarning( "Node \"%s\" found in more than one bind pose, with conflicting transforms.", pNode->GetName() ); } } g_BindPoseMap[pNode] = matNode; } } ExportLog::LogMsg( 3, "Created bind pose map with %Iu nodes.", g_BindPoseMap.size() ); }