Example #1
0
osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode(
    const osg::Node& node,
    const std::string& filename,
    const Options* options) const
{
    try
    {
        std::string ext = osgDB::getLowerCaseFileExtension(filename);
        if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;

        osg::ref_ptr<Options> localOptions = options ?
            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
        localOptions->getDatabasePathList().push_front(osgDB::getFilePath(filename));

        FbxManager* pSdkManager = FbxManager::Create();

        if (!pSdkManager)
        {
            return WriteResult::ERROR_IN_WRITING_FILE;
        }

        CleanUpFbx cleanUpFbx(pSdkManager);

        pSdkManager->SetIOSettings(FbxIOSettings::Create(pSdkManager, IOSROOT));

        bool useFbxRoot = false;
        if (options)
        {
            std::istringstream iss(options->getOptionString());
            std::string opt;
            while (iss >> opt)
            {
                if (opt == "Embedded")
                {
                    pSdkManager->GetIOSettings()->SetBoolProp(EXP_FBX_EMBEDDED, true);
                }
                else if (opt == "UseFbxRoot")
                {
                    useFbxRoot = true;
                }
            }
        }

        FbxScene* pScene = FbxScene::Create(pSdkManager, "");
        pluginfbx::WriterNodeVisitor writerNodeVisitor(pScene, pSdkManager, filename,
            options, osgDB::getFilePath(node.getName().empty() ? filename : node.getName()));
        if (useFbxRoot && isBasicRootNode(node))
        {
            // If root node is a simple group, put all elements under the FBX root
            const osg::Group * osgGroup = node.asGroup();
            for (unsigned int child = 0; child < osgGroup->getNumChildren(); ++child)
            {
                const_cast<osg::Node *>(osgGroup->getChild(child))->accept(writerNodeVisitor);
            }
        }
        else {
            // Normal scene
            const_cast<osg::Node&>(node).accept(writerNodeVisitor);
        }

        FbxDocumentInfo* pDocInfo = pScene->GetDocumentInfo();
        bool needNewDocInfo = pDocInfo != NULL;
        if (needNewDocInfo)
        {
            pDocInfo = FbxDocumentInfo::Create(pSdkManager, "");
        }
        pDocInfo->LastSaved_ApplicationName.Set(FbxString("OpenSceneGraph"));
        pDocInfo->LastSaved_ApplicationVersion.Set(FbxString(osgGetVersion()));
        if (needNewDocInfo)
        {
            pScene->SetDocumentInfo(pDocInfo);
        }

        FbxExporter* lExporter = FbxExporter::Create(pSdkManager, "");
        pScene->GetGlobalSettings().SetAxisSystem(FbxAxisSystem::eOpenGL);

        // Ensure the directory exists or else the FBX SDK will fail
        if (!osgDB::makeDirectoryForFile(filename)) {
            OSG_NOTICE << "Can't create directory for file '" << filename << "'. FBX SDK may fail creating the file." << std::endl;
        }

        // 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

        if (!lExporter->Initialize(utf8filename.c_str()))
        {
#if FBXSDK_VERSION_MAJOR < 2014
            return std::string(lExporter->GetLastErrorString());
#else
            return std::string(lExporter->GetStatus().GetErrorString());
#endif
        }
        if (!lExporter->Export(pScene))
        {
#if FBXSDK_VERSION_MAJOR < 2014
            return std::string(lExporter->GetLastErrorString());
#else
            return std::string(lExporter->GetStatus().GetErrorString());
#endif
        }

        return WriteResult::FILE_SAVED;
    }
    catch (const std::string& s)
    {
        return s;
    }
    catch (const char* s)
    {
        return std::string(s);
    }
    catch (...)
    {
    }

    return WriteResult::ERROR_IN_WRITING_FILE;
}
Example #2
0
int main(int argc, char** argv) {
	if (argc < 2) {
		printf("Usage: emdfbx model.emd skeleton.esk output.fbx\n       Can include multiple emd and esk files into one fbx.");
		getchar();
		return 1;
	}

	LibXenoverse::initializeDebuggingLog();

	vector<string> model_filenames;
	vector<string> skeleton_filenames;
	vector<string> animation_filenames;
	string export_filename = "";

	for (int i = 1; i < argc; i++)  {
		string parameter = ToString(argv[i]);

		string extension = LibXenoverse::extensionFromFilename(parameter);

		if (extension == "emd") {
			model_filenames.push_back(parameter);
		}

		if (extension == "esk") {
			skeleton_filenames.push_back(parameter);
		}

		if (extension == "ean") {
			animation_filenames.push_back(parameter);
		}

		if (extension == "fbx") {
			export_filename = parameter;
		}
	}

	if (!export_filename.size()) {
		if (model_filenames.size()) {
			export_filename = model_filenames[0] + ".fbx";
		}
		else if (skeleton_filenames.size()) {
			export_filename = skeleton_filenames[0] + ".fbx";
		}
		else {
			export_filename = "Out.fbx";
		}
	}

	// Create FBX Manager
	FbxManager *sdk_manager = FbxManager::Create();
	FbxIOSettings *ios = FbxIOSettings::Create(sdk_manager, IOSROOT);
	ios->SetBoolProp(EXP_FBX_EMBEDDED, true);
	sdk_manager->SetIOSettings(ios);

	// Create Scene
	vector<FbxNode *> global_fbx_bones;
	global_fbx_bones.reserve(300);
	vector<size_t> global_fbx_bones_index;													//TODO find a better way to link skeleton and animations
	global_fbx_bones_index.reserve(300);

	vector<FbxAnimCurveNode *> global_fbx_animation;
	global_fbx_animation.reserve(300);

	FbxScene *scene = FbxScene::Create(sdk_manager, "EMDFBXScene");


	// Load Shaders and convert it to fx file (will be use by fbx).
	vector<string> shader_names;
	shader_names.push_back("adam_shader/shader_age_vs.emb");								//must specified vs folloxed by ps shaders
	shader_names.push_back("adam_shader/shader_age_ps.emb");
	shader_names.push_back("adam_shader/shader_default_vs.emb");
	shader_names.push_back("adam_shader/shader_default_ps.emb");
	

	bool needs_install_shaders = false;
	for (size_t i = 0; i < shader_names.size(); i++) {
		if (!LibXenoverse::fileCheck(shader_names[i])) {
			needs_install_shaders = true;
			break;
		}
	}

	if (needs_install_shaders) {
		printf("Shaders not found. Please use Xenoviewer to prepare shaders in bin folder.");
		return -1;
	}

	for (size_t i = 0; i+1 < shader_names.size(); i+=2) {
		
		LibXenoverse::EMB *shader_pack_vs = new LibXenoverse::EMB();
		LibXenoverse::EMB *shader_pack_ps = new LibXenoverse::EMB();

		if (!shader_pack_vs->load(shader_names[i])) {
			delete shader_pack_vs;
			printf("Couldn't load Shader Pack %s. File is either missing, open by another application, or corrupt.", shader_names[i].c_str());
			continue;
		}
		if (!shader_pack_ps->load(shader_names[i+1])) {
			delete shader_pack_vs;
			delete shader_pack_ps;
			printf("Couldn't load Shader Pack %s. File is either missing, open by another application, or corrupt.", shader_names[i].c_str());
			continue;
		}

		shader_pack_vs->exportShadersToFx(shader_pack_vs, shader_pack_ps);					//convert all shaders in fx file with defaults program parameters (like Ogre's version).
	}



	//build FBX skeleton
	for (size_t i = 0; i < skeleton_filenames.size(); i++) {
		LibXenoverse::ESK *esk_skeleton = new LibXenoverse::ESK();
		esk_skeleton->load(skeleton_filenames[i]);
		vector<FbxNode *> fbx_bones = esk_skeleton->createFBXSkeleton(scene);

		for (size_t j = 0; j < fbx_bones.size(); j++) {
			global_fbx_bones.push_back(fbx_bones[j]);
			global_fbx_bones_index.push_back(j);											//kepp index of bone to link with animations.
		}
	}



	//build FBX animations
	for (size_t i = 0; i < animation_filenames.size(); i++) {
		
		string filename = animation_filenames.at(i);
		string ean_name = LibXenoverse::nameFromFilenameNoExtension(filename, true);

		//vector<FbxAnimCurveNode *> global_fbx_animation;

		LibXenoverse::EAN *animation = new LibXenoverse::EAN();
		if (animation->load(filename)) {

			std::vector<FbxAnimStack *> list_AnimStack;
			size_t nbAnims = animation->getAnimations().size();
			for (size_t j = 0; j < nbAnims; j++) {													//we create only one stack and one layer by animation. each will animate all bones of all skeleton.

				LibXenoverse::EANAnimation *anim_tmp = &(animation->getAnimations().at(j));

				FbxAnimStack* lAnimStack = FbxAnimStack::Create(scene, anim_tmp->getName().c_str());
				FbxAnimLayer* lAnimLayer = FbxAnimLayer::Create(scene, (anim_tmp->getName() + "_Layer0").c_str());
				lAnimStack->AddMember(lAnimLayer);

				list_AnimStack.push_back(lAnimStack);
			}

			size_t k = 0;
			for (vector<FbxNode *>::iterator it = global_fbx_bones.begin(); it != global_fbx_bones.end(); it++) {

				vector<FbxAnimCurveNode *> fbx_anim = animation->exportFBXAnimations(scene, list_AnimStack, *it, global_fbx_bones_index.at(k));

				for (size_t j = 0; j < fbx_anim.size(); j++) {
					global_fbx_animation.push_back(fbx_anim[j]);
				}
				k++;
			}
		}
		else {
			delete animation;
			animation = NULL;
		}
	}




	for (size_t i = 0; i < model_filenames.size(); i++) {
		string node_name = LibXenoverse::nameFromFilenameNoExtension(model_filenames[i]);
		string path = model_filenames[i].substr(0, model_filenames[i].size() - LibXenoverse::nameFromFilename(model_filenames[i]).size());

		LibXenoverse::EMD *emd_model = new LibXenoverse::EMD();
		emd_model->load(model_filenames[i]);

		// Fill Scene
		FbxNode *lMeshNode = NULL;

		// Create Node
		lMeshNode = FbxNode::Create(scene, node_name.c_str());
		lMeshNode->LclTranslation.Set(FbxVector4(0, 0, 0));
		lMeshNode->LclScaling.Set(FbxVector4(1, 1, 1));
		lMeshNode->LclRotation.Set(FbxVector4(0, 0, 0));

		// Create and attach Mesh
		FbxMesh *lMesh = emd_model->exportFBX(scene, lMeshNode, path);
		lMeshNode->SetNodeAttribute(lMesh);

		if (global_fbx_bones.size()) {
			emd_model->exportFBXSkin(scene, lMesh, global_fbx_bones, lMeshNode->EvaluateGlobalTransform());
		}

		// Add node to scene
		FbxNode *lRootNode = scene->GetRootNode();
		lRootNode->AddChild(lMeshNode);

	}

	// Export FBX
	int lFileFormat = sdk_manager->GetIOPluginRegistry()->GetNativeWriterFormat();
	FbxExporter* lExporter = FbxExporter::Create(sdk_manager, "");
	bool lExportStatus = lExporter->Initialize(export_filename.c_str(), lFileFormat, sdk_manager->GetIOSettings());

	if (!lExportStatus) {
		printf("Call to FbxExporter::Initialize() failed.\n");
		printf("Error returned: %s\n\n", lExporter->GetStatus().GetErrorString());
		return 1;
	}

	scene->GetGlobalSettings().SetAxisSystem(FbxAxisSystem::eMax);
	scene->GetGlobalSettings().SetSystemUnit(FbxSystemUnit::m);
	

	// Export scene
	lExporter->Export(scene);
	lExporter->Destroy();
	return 0;
}
	HRESULT FBXLoader::loadFBXFile(char* filePath, VertexBuffer** vBuf, IndexBuffer** iBuf, Renderer* renderer, bool centerShift)
	{
		if (g_pFbxSdkManager == nullptr)
		{
			g_pFbxSdkManager = FbxManager::Create();

			FbxIOSettings* pIOsettings = FbxIOSettings::Create(g_pFbxSdkManager, IOSROOT);
			g_pFbxSdkManager->SetIOSettings(pIOsettings);
		}

		this->shiftCenter = centerShift;

		FbxImporter* pImporter = FbxImporter::Create(g_pFbxSdkManager, "");
		FbxScene* pFbxScene = FbxScene::Create(g_pFbxSdkManager, "");

		bool bSuccess = pImporter->Initialize(filePath, -1, g_pFbxSdkManager->GetIOSettings());
		if (!bSuccess) return E_FAIL;

		bSuccess = pImporter->Import(pFbxScene);
		if (!bSuccess) return E_FAIL;

		FbxAxisSystem sceneAxisSystem = pFbxScene->GetGlobalSettings().GetAxisSystem();
		FbxAxisSystem DirectXAxisSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded);

		if (sceneAxisSystem != DirectXAxisSystem)
		{
			DirectXAxisSystem.ConvertScene(pFbxScene);
		}

		pImporter->Destroy();

		FbxNode* pFbxRootNode = pFbxScene->GetRootNode();

		if (pFbxRootNode)
		{
			// Check if the getChildCount is > 1  TODO
			int test = pFbxRootNode->GetChildCount();

			for (int i = 0; i < pFbxRootNode->GetChildCount(); i++)
			{
				FbxNode* pFbxChildNode = pFbxRootNode->GetChild(i);

				if (pFbxChildNode->GetNodeAttribute() == NULL)
					continue;

				FbxNodeAttribute::EType AttributeType = pFbxChildNode->GetNodeAttribute()->GetAttributeType();

				if (AttributeType != FbxNodeAttribute::eMesh)
					continue;

				FbxMesh* pMesh = (FbxMesh*)pFbxChildNode->GetNodeAttribute();

				int numControlPoints = pMesh->GetControlPointsCount();
				bool initial = true;
				float xMin, yMin, zMin;
				float xMax, yMax, zMax;
				float xIn, yIn, zIn;

				float xCenter, yCenter, zCenter;

				if (this->shiftCenter){

					for (int c = 0; c < numControlPoints; c++) {
						xIn = (float)pMesh->GetControlPointAt(c).mData[0];
						yIn = (float)pMesh->GetControlPointAt(c).mData[1];
						zIn = (float)pMesh->GetControlPointAt(c).mData[2];

						if (initial) {
							xMin = xIn;
							yMin = yIn;
							zMin = zIn;

							xMax = xIn;
							yMax = yIn;
							zMax = zIn;

							initial = false;
						}
						else {
							if (xIn < xMin) {
								xMin = xIn;
							}

							if (yIn < yMin) {
								yMin = yIn;
							}

							if (zIn < zMin) {
								zMin = zIn;
							}

							if (xIn > xMax) {
								xMax = xIn;
							}

							if (yIn > yMax) {
								yMax = yIn;
							}

							if (zIn > zMax) {
								zMax = zIn;
							}
						}
					}
					xCenter = (xMin + xMax) / 2.0f;
					yCenter = (yMin + yMax) / 2.0f;
					zCenter = (zMin + zMax) / 2.0f;
				}
				else {
					xCenter = 0;
					yCenter = 0;
					zCenter = 0;
				}

				FbxVector4* pVertices = pMesh->GetControlPoints();
				int vertexCount = pMesh->GetPolygonVertexCount();

				//Vertex vertex;
				Vertex* vertexArray = new Vertex[vertexCount];
				//Vertex vertexArray[2592];


				int numIndices = vertexCount;
				unsigned int* indexArray = new unsigned int[numIndices];


				FbxVector4 fbxNorm(0, 0, 0, 0);
				FbxVector2 fbxUV(0, 0);
				bool isMapped;

				int vertexIndex = 0;

				// Loop iterates through the polygons and fills the vertex and index arrays for the buffers
				for (int j = 0; j < pMesh->GetPolygonCount(); j++)
				{
					int iNumVertices = pMesh->GetPolygonSize(j);

					assert(iNumVertices == 3);

					//1st vertex
					int controlIndex = pMesh->GetPolygonVertex(j, 2);
					pMesh->GetPolygonVertexUV(j, 2, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 2, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;

					//2nd vertex
					controlIndex = pMesh->GetPolygonVertex(j, 1);
					pMesh->GetPolygonVertexUV(j, 1, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 1, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;

					//3rd vertex
					controlIndex = pMesh->GetPolygonVertex(j, 0);
					pMesh->GetPolygonVertexUV(j, 0, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 0, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;
				}

				// Generate vertex and index buffers from the vertex and index arrays
				*vBuf = renderer->createVertexBuffer(vertexArray, vertexCount);
				*iBuf = renderer->createIndexBuffer(indexArray, numIndices);

				delete[] vertexArray;
				delete[] indexArray;
			}
		}
		return S_OK;
	}
Example #4
0
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;
}
osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode(
    const osg::Node& node,
    const std::string& filename,
    const Options* options) const
{
    try
    {
        std::string ext = osgDB::getLowerCaseFileExtension(filename);
        if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;

        osg::ref_ptr<Options> localOptions = options ?
            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
        localOptions->getDatabasePathList().push_front(osgDB::getFilePath(filename));

        FbxManager* pSdkManager = FbxManager::Create();

        if (!pSdkManager)
        {
            return WriteResult::ERROR_IN_WRITING_FILE;
        }

        CleanUpFbx cleanUpFbx(pSdkManager);

        pSdkManager->SetIOSettings(FbxIOSettings::Create(pSdkManager, IOSROOT));

        bool useFbxRoot = false;
        bool ascii(false);
        std::string exportVersion;
        if (options)
        {
            std::istringstream iss(options->getOptionString());
            std::string opt;
            while (iss >> opt)
            {
                if (opt == "Embedded")
                {
                    pSdkManager->GetIOSettings()->SetBoolProp(EXP_FBX_EMBEDDED, true);
                }
                else if (opt == "UseFbxRoot")
                {
                    useFbxRoot = true;
                }
                else if (opt == "FBX-ASCII")
                {
                    ascii = true;
                }
                else if (opt == "FBX-ExportVersion")
                {
                    iss >> exportVersion;
                }
            }
        }

        FbxScene* pScene = FbxScene::Create(pSdkManager, "");

        if (options)
        {
            if (options->getPluginData("FBX-AssetUnitMeter"))
            {
                float unit = *static_cast<const float*>(options->getPluginData("FBX-AssetUnitMeter"));
                FbxSystemUnit kFbxSystemUnit(unit*100);
                pScene->GetGlobalSettings().SetSystemUnit(kFbxSystemUnit);
            }
        }

        pluginfbx::WriterNodeVisitor writerNodeVisitor(pScene, pSdkManager, filename,
            options, osgDB::getFilePath(node.getName().empty() ? filename : node.getName()));
        if (useFbxRoot && isBasicRootNode(node))
        {
            // If root node is a simple group, put all elements under the FBX root
            const osg::Group * osgGroup = node.asGroup();
            for (unsigned int child = 0; child < osgGroup->getNumChildren(); ++child)
            {
                const_cast<osg::Node *>(osgGroup->getChild(child))->accept(writerNodeVisitor);
            }
        }
        else {
            // Normal scene
            const_cast<osg::Node&>(node).accept(writerNodeVisitor);
        }

        FbxDocumentInfo* pDocInfo = pScene->GetDocumentInfo();
        bool needNewDocInfo = pDocInfo != NULL;
        if (needNewDocInfo)
        {
            pDocInfo = FbxDocumentInfo::Create(pSdkManager, "");
        }
        pDocInfo->LastSaved_ApplicationName.Set(FbxString("OpenSceneGraph"));
        pDocInfo->LastSaved_ApplicationVersion.Set(FbxString(osgGetVersion()));
        if (needNewDocInfo)
        {
            pScene->SetDocumentInfo(pDocInfo);
        }

        FbxExporter* lExporter = FbxExporter::Create(pSdkManager, "");
        pScene->GetGlobalSettings().SetAxisSystem(FbxAxisSystem::eOpenGL);

        // Ensure the directory exists or else the FBX SDK will fail
        if (!osgDB::makeDirectoryForFile(filename)) {
            OSG_NOTICE << "Can't create directory for file '" << filename << "'. FBX SDK may fail creating the file." << std::endl;
        }

        // 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

        // Output format selection. Here we only handle "recent" FBX, binary or ASCII.
        // pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription() / GetReaderFormatCount() gives the following list:
        //FBX binary (*.fbx)
        //FBX ascii (*.fbx)
        //FBX encrypted (*.fbx)
        //FBX 6.0 binary (*.fbx)
        //FBX 6.0 ascii (*.fbx)
        //FBX 6.0 encrypted (*.fbx)
        //AutoCAD DXF (*.dxf)
        //Alias OBJ (*.obj)
        //Collada DAE (*.dae)
        //Biovision BVH (*.bvh)
        //Motion Analysis HTR (*.htr)
        //Motion Analysis TRC (*.trc)
        //Acclaim ASF (*.asf)
        int format = ascii ? pSdkManager->GetIOPluginRegistry()->FindWriterIDByDescription("FBX ascii (*.fbx)") : -1;        // -1 = Default
        if (!lExporter->Initialize(utf8filename.c_str(), format))
        {
#if FBXSDK_VERSION_MAJOR < 2014
            return std::string(lExporter->GetLastErrorString());
#else
            return std::string(lExporter->GetStatus().GetErrorString());
#endif
        }

        if (!exportVersion.empty() && !lExporter->SetFileExportVersion(FbxString(exportVersion.c_str()), FbxSceneRenamer::eNone)) {
            std::stringstream versionsStr;
            char const * const * versions = lExporter->GetCurrentWritableVersions();
            if (versions) for(; *versions; ++versions) versionsStr << " " << *versions;
            OSG_WARN << "Can't set FBX export version to '" << exportVersion << "'. Using default. Available export versions are:" << versionsStr.str() << std::endl;
        }

        if (!lExporter->Export(pScene))
        {
#if FBXSDK_VERSION_MAJOR < 2014
            return std::string(lExporter->GetLastErrorString());
#else
            return std::string(lExporter->GetStatus().GetErrorString());
#endif
        }

        return WriteResult::FILE_SAVED;
    }
Example #6
0
void LoadMeshes(Scene* pScene, std::vector<uint32_t>* loadedMeshIDs)
{
    FbxManager* fbxManager = FbxManager::Create();

    FbxIOSettings* pFbxIOSettings = FbxIOSettings::Create(fbxManager, IOSROOT);
    fbxManager->SetIOSettings(pFbxIOSettings);

    (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_MATERIAL, true);
    (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_TEXTURE, true);
    (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_LINK, false);
    (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_SHAPE, false);
    (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_GOBO, false);
    (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_ANIMATION, true);
    (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);

    bool bEmbedMedia = true;
    (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_MATERIAL, true);
    (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_TEXTURE, true);
    (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_EMBEDDED, bEmbedMedia);
    (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_SHAPE, true);
    (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_GOBO, true);
    (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_ANIMATION, true);
    (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_GLOBAL_SETTINGS, true);

    FbxImporter* pFbxImporter = FbxImporter::Create(fbxManager, "");

    // Initialize the importer.
    bool result = pFbxImporter->Initialize(pScene->loadPath.c_str(), -1, fbxManager->GetIOSettings());
    if (!result) {
        printf("Get error when init FBX Importer: %s\n\n",
            pFbxImporter->GetStatus().GetErrorString());
        exit(-1);
    }

    // fbx version number
    int major, minor, revision;
    pFbxImporter->GetFileVersion(major, minor, revision);

    // import pFbxScene
    FbxScene* pFbxScene = FbxScene::Create(fbxManager, "myScene");
    pFbxImporter->Import(pFbxScene);
    pFbxImporter->Destroy();
    pFbxImporter = nullptr;

    // check axis system
    FbxAxisSystem axisSystem = pFbxScene->GetGlobalSettings().GetAxisSystem();
    FbxAxisSystem vulkanAxisSystem(FbxAxisSystem::eYAxis,
        FbxAxisSystem::eParityOdd,
        FbxAxisSystem::eRightHanded);
    if (axisSystem != vulkanAxisSystem) {
        axisSystem.ConvertScene(pFbxScene);
    }

    // check unit system
    FbxSystemUnit systemUnit = pFbxScene->GetGlobalSettings().GetSystemUnit();
    if (systemUnit.GetScaleFactor() != 1.0) {
        FbxSystemUnit::cm.ConvertScene(pFbxScene);
    }

    // Triangulate Mesh
    FbxGeometryConverter fbxGeometryConverter(fbxManager);
    fbxGeometryConverter.Triangulate(pFbxScene, true);

    // Load Texture
    int textureCount = pFbxScene->GetTextureCount();
    for (int i = 0; i < textureCount; ++i) {
        FbxTexture* pFbxTexture = pFbxScene->GetTexture(i);
        FbxFileTexture* pFbxFileTexture = FbxCast<FbxFileTexture>(pFbxTexture);
        if (pFbxTexture && pFbxFileTexture->GetUserDataPtr()) {
        }
    }
    LoadMeshes(pFbxScene->GetRootNode(), pScene->meshes);
}
Example #7
0
CGeometryComponent * CModelLoader::loadFbxModelFromFile(ID3D10Device *pDevice,const string& filename)
{
	CGeometryComponent * pRenderable=NULL;

	FbxManager* lSdkManager = FbxManager::Create();
	FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT);
    lSdkManager->SetIOSettings(ios);

    // Create an importer using our sdk manager.
    FbxImporter* lImporter = FbxImporter::Create(lSdkManager,"");
	//Sean: uncomment back to this when you compile, I am using the latest version of fbx SDK
	//KFbxGeometryConverter converter( lSdkManager);
	//Sean: has comment out the line below
	FbxGeometryConverter converter( lSdkManager);

	 
    // Use the first argument as the filename for the importer.
	if(!lImporter->Initialize(filename.c_str(), -1, lSdkManager->GetIOSettings())) {
		return NULL;
    }

	// Create a new scene so it can be populated by the imported file.
    FbxScene* lScene = FbxScene::Create(lSdkManager,"myScene");
	FbxAxisSystem SceneAxisSystem = lScene->GetGlobalSettings().GetAxisSystem();
    //FbxAxisSystem::DirectX.ConvertScene( lScene );

    INT iUpAxisSign;
    //Sean: Uncomment this below
	//KFbxAxisSystem::eUpVector UpVector = SceneAxisSystem.GetUpVector( iUpAxisSign );
	//Sean: and comment this out
	FbxAxisSystem::EUpVector UpVector = SceneAxisSystem.GetUpVector( iUpAxisSign );

    // Import the contents of the file into the scene.
    lImporter->Import(lScene);

    // The file has been imported; we can get rid of the importer.
    lImporter->Destroy();

	FbxNode* lRootNode = lScene->GetRootNode();
	FbxMesh * pMesh=NULL;
	if(lRootNode) {
		for (int i=0;i<lRootNode->GetChildCount();i++){
			FbxNode * modelNode=lRootNode->GetChild(i);
			for(int i=0;i<modelNode->GetNodeAttributeCount();i++)
			{
				FbxNodeAttribute *pAttributeNode=modelNode->GetNodeAttributeByIndex(i);
				//Sean: Uncomment this
				//if (pAttributeNode->GetAttributeType()==KFbxNodeAttribute::eMESH)
				//Sean Comment this out
				if (pAttributeNode->GetAttributeType()==FbxNodeAttribute::eMesh)
				{
					//found mesh
					pMesh=(FbxMesh*)pAttributeNode;
					break;
				}
			}
		}
		if (pMesh)
		{
			pMesh=converter.TriangulateMesh(pMesh);
			FbxVector4 * verts=pMesh->GetControlPoints();
			int noVerts=pMesh->GetControlPointsCount();

			int noIndices=pMesh->GetPolygonVertexCount();
			int *pIndices=pMesh->GetPolygonVertices();

			Vertex * pVerts=new Vertex[noVerts];
			for(int i=0;i<noVerts;i++)
			{

					pVerts[i].Pos.x=verts[i][0];
					pVerts[i].Pos.y=verts[i][1];
					pVerts[i].Pos.z=verts[i][2];
			}

			for (int iPolygon = 0; iPolygon < pMesh->GetPolygonCount(); iPolygon++) { 
				for (unsigned iPolygonVertex = 0; iPolygonVertex < 3; iPolygonVertex++) {	
					int fbxCornerIndex = pMesh->GetPolygonVertex(iPolygon, iPolygonVertex);
					FbxVector4 fbxVertex = verts[fbxCornerIndex];

					FbxVector4 fbxNormal;	
					pMesh->GetPolygonVertexNormal(iPolygon, iPolygonVertex, fbxNormal);	
					fbxNormal.Normalize();	
					//pVerts[fbxCornerIndex].Normal=D3DXVECTOR3(fbxNormal[0],fbxNormal[1],fbxNormal[2]);
					FbxVector2 fbxUV = FbxVector2(0.0, 0.0);	
					FbxLayerElementUV* fbxLayerUV = pMesh->GetLayer(0)->GetUVs();
					// Get texture coordinate	
					if (fbxLayerUV) {		
						int iUVIndex = 0;		
						switch (fbxLayerUV->GetMappingMode()) {	
							//Sean Uncomment this
							//case KFbxLayerElement::eBY_CONTROL_POINT:
							//Sean comment the line below out
							case FbxLayerElement::eByControlPoint:
								iUVIndex = fbxCornerIndex;				
							break;	
							//Sean Uncomment this
							//case KFbxLayerElement::eBY_POLYGON_VERTEX:
							//Sean comment the line below out
							case FbxLayerElement::eByPolygonVertex:
								//Sean Uncomment this
								//iUVIndex = pMesh->GetTextureUVIndex(iPolygon, iPolygonVertex, KFbxLayerElement::eDIFFUSE_TEXTURES);	
								//Sean comment this out
								iUVIndex = pMesh->GetTextureUVIndex(iPolygon, iPolygonVertex, FbxLayerElement::eTextureDiffuse);	
							break;		
						}		
						fbxUV = fbxLayerUV->GetDirectArray().GetAt(iUVIndex);	
						//pVerts[fbxCornerIndex].TextureCoords.x=fbxUV[0];
						//pVerts[fbxCornerIndex].TextureCoords.y= 1.0f-fbxUV[1];
					}
				}
			}

			pRenderable=new CGeometryComponent();
			for (int i=0;i<noVerts;i++)
			{
				pRenderable->addVertex(pVerts[i]);
			}
			for (int i=0;i<noIndices;i++)
			{
				pRenderable->addIndex(pIndices[i]);
			}
			//pRenderable->create<TexturedLitVertex>(pDevice,noVerts,noIndices,pVerts,(UINT*)pIndices);
			if (pVerts)
			{
				delete [] pVerts;
				pVerts=NULL;
			}
			//}

		}
    }

	lSdkManager->Destroy();

	

	return pRenderable;
}
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;
}
Example #9
0
	boost::shared_ptr<FBXScene> FBXManager::loadScene(const std::string& filename)
	{
		PROFILE;
		FbxImporter* importer  = nullptr;
		FbxScene* scene = nullptr;
		std::string pathAbs;
		std::string pathRel;

		pathRel = m_pFilesystem->resourcePathRel(Filesystem::ResourceType::Fbx, filename);
		pathAbs = m_pFilesystem->resourcePathAbs(Filesystem::ResourceType::Fbx, filename);
		if (pathAbs.empty()) {
			return boost::shared_ptr<FBXScene>();
		}

		LOGI << "Loading FBX file '" << pathRel << "'..";

		importer = FbxImporter::Create(m_pFbxManager,"");
		if(!importer->Initialize(pathAbs.c_str(), -1, m_pFbxManager->GetIOSettings())) {
			LOGE << "FbxImporter initialization for failed with " << importer->GetStatus().GetErrorString();
			return false;
		}

		scene = FbxScene::Create(m_pFbxManager, filename.c_str());
		if(!scene)
		{
			LOGE << "Unable to create a FbxScene";
			return boost::shared_ptr<FBXScene>();
		}

		if (!importer->Import(scene)) {
			LOGE << "Failed to import scene '" << filename << "'";
			return boost::shared_ptr<FBXScene>();
		}

		// Convert Axis System if needed
		FbxAxisSystem sceneAxisSystem = scene->GetGlobalSettings().GetAxisSystem();
		FbxAxisSystem axisSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eRightHanded);
		if(sceneAxisSystem != axisSystem)
		{
			LOGW << "Scene needed axis convertion";
			axisSystem.ConvertScene(scene);
		}

		//// Convert Unit System if needed
		//FbxSystemUnit sceneSystemUnit = scene->GetGlobalSettings().GetSystemUnit();
		//if(sceneSystemUnit.GetScaleFactor() != 1.0)
		//{
		//	LOGW << "Scene needed unit convertion";
		//	FbxSystemUnit::cm.ConvertScene(scene);
		//}

		// Convert fbxMesh, NURBS and patch into triangle fbxMesh
		FbxGeometryConverter geomConverter(m_pFbxManager);
		geomConverter.Triangulate(scene, true);

		// Split meshes per material, so that we only have one material per fbxMesh (for VBO support)
		geomConverter.SplitMeshesPerMaterial(scene, true);

		importer->Destroy();

		return boost::shared_ptr<FBXScene>(new FBXScene(scene, m_pDatabase));
	}