//----------------------------------------------------------------------------------- static void ImportSkeletons(SceneImport* import, FbxNode* node, MatrixStack4x4& matrixStack, Skeleton* skeleton, int parentJointIndex, std::map<int, FbxNode*>& nodeToJointIndex) { if (nullptr == node) { return; } Matrix4x4 mat = GetNodeTransform(node); matrixStack.Push(mat); //Walk the attributes, looking for doot doots. int attributeCount = node->GetNodeAttributeCount(); for (int attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex) { FbxNodeAttribute* attribute = node->GetNodeAttributeByIndex(attributeIndex); if ((attribute != nullptr) && (attribute->GetAttributeType() == FbxNodeAttribute::eSkeleton)) { //So we have a skeleton FbxSkeleton* fbxSkele = (FbxSkeleton*)attribute; Skeleton* newSkeleton = ImportSkeleton(import, matrixStack, skeleton, parentJointIndex, fbxSkele, nodeToJointIndex); //newSkeleton will either be the same skeleton passed, or a new skeleton, or no skeleton if it was a bad node. //If we got something back- it's what we p[ass on to the next generation. if (newSkeleton != nullptr) { skeleton = newSkeleton; parentJointIndex = skeleton->GetLastAddedJointIndex(); } } } //do the rest of the tree int childCount = node->GetChildCount(); for (int childIndex = 0; childIndex < childCount; ++childIndex) { ImportSkeletons(import, node->GetChild(childIndex), matrixStack, skeleton, parentJointIndex, nodeToJointIndex); } matrixStack.Pop(); }
bool MeshImportFBX::Import( const char* filename, NVSHARE::MeshImportInterface *callback ) { char message[OUTPUT_TEXT_BUFFER_SIZE+1] = ""; message[OUTPUT_TEXT_BUFFER_SIZE] = '\0'; const char* localName = getFileName( filename ); KString fileName = KString( filename ); KString filePath = fileName.Left( localName - filename ); m_sdkManager = KFbxSdkManager::Create(); if(m_sdkManager == NULL) return false; // Create the importer. int fileFormat = -1; //int registeredCount; //int pluginId; //m_sdkManager->GetIOPluginRegistry()->RegisterReader( CreateFBXImporterReader, GetFBXImporterReaderInfo, // pluginId, registeredCount, FillFBXImporterReaderIOSettings ); m_importer = KFbxImporter::Create( m_sdkManager, "" ); if( !m_sdkManager->GetIOPluginRegistry()->DetectFileFormat( filename, fileFormat ) ) { // Unrecognizable file format. Try to fall back to KFbxImporter::eFBX_BINARY fileFormat = m_sdkManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary (*.fbx)" );; } m_importer->SetFileFormat( fileFormat ); // Initialize the importer by providing a filename. if( !m_importer->Initialize( filename ) ) return false; // Create the scene. m_scene = KFbxScene::Create( m_sdkManager, "" ); if (m_importer->IsFBX()) { // Set the import states. By default, the import states are always set to // true. The code below shows how to change these states. IOSREF.SetBoolProp(IMP_FBX_MATERIAL, true); IOSREF.SetBoolProp(IMP_FBX_TEXTURE, true); IOSREF.SetBoolProp(IMP_FBX_LINK, true); IOSREF.SetBoolProp(IMP_FBX_SHAPE, true); IOSREF.SetBoolProp(IMP_FBX_GOBO, true); IOSREF.SetBoolProp(IMP_FBX_ANIMATION, true); IOSREF.SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true); } sprintf_s( message, OUTPUT_TEXT_BUFFER_SIZE, "Importing file %s", filename ); outputMessage( message ); if( !m_importer->Import(m_scene) ) return false; //// Convert Axis System to what is used in this example, if needed //KFbxAxisSystem sceneAxisSystem = m_scene->GetGlobalSettings().GetAxisSystem(); //KFbxAxisSystem ourAxisSystem(sceneAxisSystem.KFbxAxisSystem::ZAxis, KFbxAxisSystem::ParityOdd, KFbxAxisSystem::LeftHanded); //if( sceneAxisSystem != ourAxisSystem ) //{ // ourAxisSystem.ConvertScene(m_scene); //} //// Convert Unit System to what is used in this example, if needed //KFbxSystemUnit sceneSystemUnit = m_scene->GetGlobalSettings().GetSystemUnit(); //if( sceneSystemUnit.GetScaleFactor() != 1.0 ) //{ // // KFbxSystemUnit ourSystemUnit(1.0); // ourSystemUnit.ConvertScene(m_scene); // //} m_callback = callback; ImportSkeleton(); m_takeName = NULL; m_takeInfo = NULL; m_takeNameArray.Clear(); int takeCount = m_importer->GetTakeCount(); int tSelected = -1; for(int t = 0; t < takeCount; t++ ) { m_takeInfo = m_importer->GetTakeInfo(t); m_takeNameArray.Add( &m_takeInfo->mName ); if(m_takeInfo->mSelect) tSelected = t; } if(tSelected == -1 && takeCount > 0) tSelected = 0; if(tSelected >= 0) { m_takeInfo = m_importer->GetTakeInfo(tSelected); m_takeName = m_takeNameArray[tSelected]; m_scene->SetCurrentTake( m_takeName->Buffer() ); if (!ImportAnimation()) { Release(); return false; } } m_scene->FillMaterialArray(m_MaterialArray); ProcessScene(); //// Load the texture data in memory (for supported formats) //LoadSupportedTextures(m_scene, m_textureArray); sprintf_s( message, OUTPUT_TEXT_BUFFER_SIZE, "done!" ); outputMessage( message ); m_scene->Destroy(true, true); m_scene = NULL; m_importer->Destroy(true, true); m_importer = NULL; m_sdkManager->Destroy(); m_sdkManager = NULL; return true; }
bool SMDImporter::Parse ( FILE *f ) { char *buffer = NULL; try { fseek(f, 0, SEEK_END ); long fl = ftell ( f ); fseek (f, 0,SEEK_SET); buffer = new char [fl + 7]; fread (buffer,fl,sizeof(char),f); buffer[fl] = '\r'; buffer[fl+1] = '\n'; buffer[fl+2] = 'E'; buffer[fl+3] = 'N'; buffer[fl+4] = 'D'; buffer[fl+5] = 0; fixNames ( buffer ); char seps[] = " \t\n\r"; char *token = GetNextToken (buffer, seps); int smdversion = NextTokenAsInteger(); if ( strcmp ( token, "version" )) { XSILogMessage ( L"SMDImport: Not an SMD file.", XSI::siErrorMsg ); return false; } if ( smdversion != 1 ) { XSILogMessage ( L"SMDImport: Attempting to load unsupported SMD version.", XSI::siWarningMsg ); } while (1) { char *currenttok = GetNextToken (NULL, seps); if ( !strcmp ( currenttok, "nodes")) { if ( !ImportNodes () ) { return false; } } if ( !strcmp ( currenttok, "skeleton")) { if ( !ImportSkeleton () ) { return false; } } if ( !strcmp ( currenttok, "triangles")) { if ( !ImportTriangles () ) { return false; } } if ( !strcmp ( currenttok, "vertexanimation")) { if ( !ImportVertexAnimation () ) { return false; } } if (!strcmp ( currenttok, "END")) { break; // were done } } // // Create Hierarchy // } catch (...) { XSILogMessage ( L"SMDImport: Invalid or corrupted SMD file.", XSI::siErrorMsg ); return false; } delete [] buffer; return true; }