bool FBXScene::LoadScene(const char* filename, std::ostream& output, Vector3& minPos, Vector3& maxPos) { int lFileMajor, lFileMinor, lFileRevision; int i, lAnimStackCount; bool lStatus; FbxIOSettings *ios = FbxIOSettings::Create(mSdkManager, IOSROOT); mSdkManager->SetIOSettings(ios); FbxGeometryConverter lGConverter(mSdkManager); // Create an importer using our sdk manager. FbxImporter* pFBXImporter = FbxImporter::Create(mSdkManager,""); // Initialize the importer by providing a filename. const bool lImportStatus = pFBXImporter->Initialize(filename, -1, mSdkManager->GetIOSettings()); pFBXImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision); if( !lImportStatus ) { output << "FBX Importer Error: " << pFBXImporter->GetStatus().GetErrorString() << std::endl; if ( pFBXImporter->GetStatus() == FbxStatus::eInvalidFileVersion ) { output << "FBX version number for file " << filename << " is " << lFileMajor << " " << lFileMinor << " " << lFileRevision << std::endl; } return false; } if (pFBXImporter->IsFBX()) { output << "FBX version number for file " << filename << " is " << lFileMajor << " " << lFileMinor << " " << lFileRevision << std::endl; // From this point, it is possible to access animation stack information without // the expense of loading the entire file. output << "Animation Stack Information" << std::endl; lAnimStackCount = pFBXImporter->GetAnimStackCount(); output << " Number of Animation Stacks: " << lAnimStackCount << std::endl; output << " Current Animation Stack: " << pFBXImporter->GetActiveAnimStackName().Buffer() << std::endl; for(i = 0; i < lAnimStackCount; i++) { FbxTakeInfo* lTakeInfo = pFBXImporter->GetTakeInfo(i); output << " Animation Stack " << i << std::endl; output << " Name: " << lTakeInfo->mName.Buffer() << std::endl; output << " Description: " << lTakeInfo->mDescription.Buffer() << std::endl; output << " Import Name: " << lTakeInfo->mImportName.Buffer() << std::endl; output << " Import State: " << (lTakeInfo->mSelect ? "true" : "false") << std::endl; } } // Import the scene. lStatus = pFBXImporter->Import(mScene); if ( !lStatus ) { output << "Failed Importing FBX!" << std::endl; output << "FBX is password protected!" << std::endl; if ( pFBXImporter->GetStatus() == FbxStatus::ePasswordError ) { output << "FBX is password protected!" << std::endl; } } mFilename = pFBXImporter->GetFileName().Buffer(); // Destroy the importer. pFBXImporter->Destroy(); ios->Destroy(); ProcessScene(mScene); return lStatus; }
osgDB::ReaderWriter::ReadResult ReaderWriterFBX::readNode(const std::string& filenameInit, const Options* options) const { try { std::string ext(osgDB::getLowerCaseFileExtension(filenameInit)); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string filename(osgDB::findDataFile(filenameInit, options)); if (filename.empty()) return ReadResult::FILE_NOT_FOUND; FbxManager* pSdkManager = FbxManager::Create(); if (!pSdkManager) { return ReadResult::ERROR_IN_READING_FILE; } CleanUpFbx cleanUpFbx(pSdkManager); pSdkManager->SetIOSettings(FbxIOSettings::Create(pSdkManager, IOSROOT)); FbxScene* pScene = FbxScene::Create(pSdkManager, ""); // The FBX SDK interprets the filename as UTF-8 #ifdef OSG_USE_UTF8_FILENAME const std::string& utf8filename(filename); #else std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename)); #endif FbxImporter* lImporter = FbxImporter::Create(pSdkManager, ""); if (!lImporter->Initialize(utf8filename.c_str(), -1, pSdkManager->GetIOSettings())) { #if FBXSDK_VERSION_MAJOR < 2014 return std::string(lImporter->GetLastErrorString()); #else return std::string(lImporter->GetStatus().GetErrorString()); #endif } if (!lImporter->IsFBX()) { return ReadResult::ERROR_IN_READING_FILE; } for (int i = 0; FbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); i++) { lTakeInfo->mSelect = true; } if (!lImporter->Import(pScene)) { #if FBXSDK_VERSION_MAJOR < 2014 return std::string(lImporter->GetLastErrorString()); #else return std::string(lImporter->GetStatus().GetErrorString()); #endif } //FbxAxisSystem::OpenGL.ConvertScene(pScene); // Doesn't work as expected. Still need to transform vertices. if (FbxNode* pNode = pScene->GetRootNode()) { bool useFbxRoot = false; bool lightmapTextures = false; bool tessellatePolygons = false; if (options) { std::istringstream iss(options->getOptionString()); std::string opt; while (iss >> opt) { if (opt == "UseFbxRoot") { useFbxRoot = true; } if (opt == "LightmapTextures") { lightmapTextures = true; } if (opt == "TessellatePolygons") { tessellatePolygons = true; } } } bool bIsBone = false; int nLightCount = 0; osg::ref_ptr<Options> localOptions = NULL; if (options) localOptions = options->cloneOptions(); else localOptions = new osgDB::Options(); localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_IMAGES); std::string filePath = osgDB::getFilePath(filename); FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get(), lightmapTextures); std::set<const FbxNode*> fbxSkeletons; findLinkedFbxSkeletonNodes(pNode, fbxSkeletons); OsgFbxReader::AuthoringTool authoringTool = OsgFbxReader::UNKNOWN; if (FbxDocumentInfo* pDocInfo = pScene->GetDocumentInfo()) { struct ToolName { const char* name; OsgFbxReader::AuthoringTool tool; }; ToolName authoringTools[] = { {"OpenSceneGraph", OsgFbxReader::OPENSCENEGRAPH}, {"3ds Max", OsgFbxReader::AUTODESK_3DSTUDIO_MAX} }; FbxString appName = pDocInfo->LastSaved_ApplicationName.Get(); for (unsigned int i = 0; i < sizeof(authoringTools) / sizeof(authoringTools[0]); ++i) { if (0 == #ifdef WIN32 _strnicmp #else strncasecmp #endif (appName, authoringTools[i].name, strlen(authoringTools[i].name))) { authoringTool = authoringTools[i].tool; break; } } } OsgFbxReader reader(*pSdkManager, *pScene, fbxMaterialToOsgStateSet, fbxSkeletons, *localOptions, authoringTool, lightmapTextures, tessellatePolygons); ReadResult res = reader.readFbxNode(pNode, bIsBone, nLightCount); if (res.success()) { fbxMaterialToOsgStateSet.checkInvertTransparency(); resolveBindMatrices(*res.getNode(), reader.boneBindMatrices, reader.nodeMap); osg::Node* osgNode = res.getNode(); osgNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON); osgNode->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON); if (reader.pAnimationManager.valid()) { if (osgNode->getUpdateCallback()) { osg::Group* osgGroup = new osg::Group; osgGroup->addChild(osgNode); osgNode = osgGroup; } //because the animations may be altered after registering reader.pAnimationManager->buildTargetReference(); osgNode->setUpdateCallback(reader.pAnimationManager.get()); } FbxAxisSystem fbxAxis = pScene->GetGlobalSettings().GetAxisSystem(); if (fbxAxis != FbxAxisSystem::OpenGL) { int upSign; FbxAxisSystem::EUpVector eUp = fbxAxis.GetUpVector(upSign); bool bLeftHanded = fbxAxis.GetCoorSystem() == FbxAxisSystem::eLeftHanded; float fSign = upSign < 0 ? -1.0f : 1.0f; float zScale = bLeftHanded ? -1.0f : 1.0f; osg::Matrix mat; switch (eUp) { case FbxAxisSystem::eXAxis: mat.set(0,fSign,0,0,-fSign,0,0,0,0,0,zScale,0,0,0,0,1); break; case FbxAxisSystem::eYAxis: mat.set(1,0,0,0,0,fSign,0,0,0,0,fSign*zScale,0,0,0,0,1); break; case FbxAxisSystem::eZAxis: mat.set(1,0,0,0,0,0,-fSign*zScale,0,0,fSign,0,0,0,0,0,1); break; } osg::Transform* pTransformTemp = osgNode->asTransform(); osg::MatrixTransform* pMatrixTransform = pTransformTemp ? pTransformTemp->asMatrixTransform() : NULL; if (pMatrixTransform) { pMatrixTransform->setMatrix(pMatrixTransform->getMatrix() * mat); } else { pMatrixTransform = new osg::MatrixTransform(mat); if (useFbxRoot && isBasicRootNode(*osgNode)) { // If root node is a simple group, put all FBX elements under the OSG root osg::Group* osgGroup = osgNode->asGroup(); for(unsigned int i = 0; i < osgGroup->getNumChildren(); ++i) { pMatrixTransform->addChild(osgGroup->getChild(i)); } pMatrixTransform->setName(osgGroup->getName()); } else { pMatrixTransform->addChild(osgNode); } } osgNode = pMatrixTransform; } osgNode->setName(filenameInit); return osgNode; } } } catch (...) { OSG_WARN << "Exception thrown while importing \"" << filenameInit << '\"' << std::endl; } return ReadResult::ERROR_IN_READING_FILE; }
bool FBXReader::loadScene(FbxManager* fbxManager, FbxDocument* scene, string fileName) { int lFileMajor, lFileMinor, lFileRevision; int lSDKMajor, lSDKMinor, lSDKRevision; //int lFileFormat = -1; int i, lAnimStackCount; bool lStatus; char lPassword[1024]; // Get the file version number generate by the FBX SDK. FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision); // Create an importer. FbxImporter* lImporter = FbxImporter::Create(fbxManager, ""); // Initialize the importer by providing a filename. const bool lImportStatus = lImporter->Initialize(fileName.c_str(), -1, fbxManager->GetIOSettings()); lImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision); if (!lImportStatus) { FbxString error = lImporter->GetStatus().GetErrorString(); FBXSDK_printf("Call to FbxImporter::Initialize() failed.\n"); FBXSDK_printf("Error returned: %s\n\n", error.Buffer()); if (lImporter->GetStatus().GetCode() == FbxStatus::eInvalidFileVersion) { FBXSDK_printf("FBX file format version for this FBX SDK is %d.%d.%d\n", lSDKMajor, lSDKMinor, lSDKRevision); FBXSDK_printf("FBX file format version for file '%s' is %d.%d.%d\n\n", fileName, lFileMajor, lFileMinor, lFileRevision); } return false; } FBXSDK_printf("FBX file format version for this FBX SDK is %d.%d.%d\n", lSDKMajor, lSDKMinor, lSDKRevision); if (lImporter->IsFBX()) { FBXSDK_printf("FBX file format version for file '%s' is %d.%d.%d\n\n", fileName, lFileMajor, lFileMinor, lFileRevision); // From this point, it is possible to access animation stack information without // the expense of loading the entire file. FBXSDK_printf("Animation Stack Information\n"); lAnimStackCount = lImporter->GetAnimStackCount(); FBXSDK_printf(" Number of Animation Stacks: %d\n", lAnimStackCount); FBXSDK_printf(" Current Animation Stack: \"%s\"\n", lImporter->GetActiveAnimStackName().Buffer()); FBXSDK_printf("\n"); for (i = 0; i < lAnimStackCount; i++) { FbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); FBXSDK_printf(" Animation Stack %d\n", i); FBXSDK_printf(" Name: \"%s\"\n", lTakeInfo->mName.Buffer()); FBXSDK_printf(" Description: \"%s\"\n", lTakeInfo->mDescription.Buffer()); // Change the value of the import name if the animation stack should be imported // under a different name. FBXSDK_printf(" Import Name: \"%s\"\n", lTakeInfo->mImportName.Buffer()); // Set the value of the import state to false if the animation stack should be not // be imported. FBXSDK_printf(" Import State: %s\n", lTakeInfo->mSelect ? "true" : "false"); FBXSDK_printf("\n"); } // Set the import states. By default, the import states are always set to // true. The code below shows how to change these states. IOS_REF.SetBoolProp(IMP_FBX_MATERIAL, true); IOS_REF.SetBoolProp(IMP_FBX_TEXTURE, true); IOS_REF.SetBoolProp(IMP_FBX_LINK, true); IOS_REF.SetBoolProp(IMP_FBX_SHAPE, true); IOS_REF.SetBoolProp(IMP_FBX_GOBO, true); IOS_REF.SetBoolProp(IMP_FBX_ANIMATION, true); IOS_REF.SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true); } // Import the scene. lStatus = lImporter->Import(scene); if (lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::ePasswordError) { FBXSDK_printf("Please enter password: "******"%s", lPassword); FBXSDK_CRT_SECURE_NO_WARNING_END FbxString lString(lPassword); IOS_REF.SetStringProp(IMP_FBX_PASSWORD, lString); IOS_REF.SetBoolProp(IMP_FBX_PASSWORD_ENABLE, true); lStatus = lImporter->Import(scene); if (lStatus == false && lImporter->GetStatus().GetCode() == FbxStatus::ePasswordError) { FBXSDK_printf("\nPassword is wrong, import aborted.\n"); } } // Destroy the importer. lImporter->Destroy(); return lStatus; }
bool LoaderFbx::loadScene(std::string filename) { bool success = true; int fileMajor, fileMinor, fileRevision; int sdkMajor, sdkMinor, sdkRevision; std::stringstream message; FbxManager::GetFileFormatVersion(sdkMajor, sdkMinor, sdkRevision); FbxImporter* fbxImporter = FbxImporter::Create(fbxManager_, ""); success = fbxImporter->Initialize(filename.c_str(), -1, fbxManager_->GetIOSettings()); fbxImporter->GetFileVersion(fileMajor, fileMinor, fileRevision); if(!success) { message.str(""); message << "LoaderFbx::loadScene | Call to FbxImporter::Initialize() failed! \n Error returned: " << fbxImporter->GetStatus().GetErrorString(); ERROR_MESSAGEBOX(message.str()); if(fbxImporter->GetStatus().GetCode() == FbxStatus::eInvalidFileVersion) { std::stringstream message; message.str(""); message << "FBX file format version for this FBX SDK is " << sdkMajor << "." << sdkMinor << "." << sdkRevision << "\n" << "FBX file format version for file " << filename << " is " << fileMajor << "." << fileMinor << "." << fileRevision; ERROR_MESSAGEBOX(message.str()); } } if(fbxImporter->IsFBX()) { FBXSDK_printf("FBX file format version for file '%s' is %d.%d.%d\n\n", filename, fileMajor, fileMinor, fileRevision); // From this point, it is possible to access animation stack information without // the expense of loading the entire file. FBXSDK_printf("Animation Stack Information\n"); int animStackCount = fbxImporter->GetAnimStackCount(); FBXSDK_printf(" Number of Animation Stacks: %d\n", animStackCount); FBXSDK_printf(" Current Animation Stack: \"%s\"\n", fbxImporter->GetActiveAnimStackName().Buffer()); FBXSDK_printf("\n"); for(int i = 0; i < animStackCount; i++) { FbxTakeInfo* takeInfo = fbxImporter->GetTakeInfo(i); FBXSDK_printf(" Animation Stack %d\n", i); FBXSDK_printf(" Name: \"%s\"\n", takeInfo->mName.Buffer()); const char* debug = takeInfo->mDescription.Buffer(); // FBXSDK_printf(" Description: \"%s\"\n", takeInfo->mDescription.Buffer()); // Change the value of the import name if the animation stack should be imported // under a different name. FBXSDK_printf(" Import Name: \"%s\"\n", takeInfo->mImportName.Buffer()); // Set the value of the import state to false if the animation stack should be not // be imported. FBXSDK_printf(" Import State: %s\n", takeInfo->mSelect ? "true" : "false"); FBXSDK_printf("\n"); } // Set the import states. By default, the import states are always set to // true. The code below shows how to change these states. fbxManager_->GetIOSettings()->SetBoolProp(IMP_FBX_MATERIAL, true); fbxManager_->GetIOSettings()->SetBoolProp(IMP_FBX_TEXTURE, true); fbxManager_->GetIOSettings()->SetBoolProp(IMP_FBX_LINK, true); fbxManager_->GetIOSettings()->SetBoolProp(IMP_FBX_SHAPE, true); fbxManager_->GetIOSettings()->SetBoolProp(IMP_FBX_GOBO, true); fbxManager_->GetIOSettings()->SetBoolProp(IMP_FBX_ANIMATION, true); fbxManager_->GetIOSettings()->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true); } if(success) { success = fbxImporter->Import(fbxScene_); } if(!success) { message.str(""); message << "LoaderFbx::loadScene | Call to FbxImporter::Import() failed! \n Error returned: " << fbxImporter->GetStatus().GetErrorString(); ERROR_MESSAGEBOX(message.str()); } return success; }