这是Autodesk FBX SDK学习笔记第二篇,以下部分汉字翻译自Autodesk FBX SDK Program,翻译人:有道翻译。
上一篇讲了一些FBX SDK的基本操作,创建FbxManager这些,也写了我们第一个FBX SDK 的例子。
今天是FBX SDK指南的第二篇,创建一个FBX文件转换器,有什么用?
把FBX转换成DAE、Obj这些格式啦!把FBX 二进制转换成文本格式啦!
这一篇的知识点:
1、FbxManager的创建与销毁
2、FbxImporter的创建与使用
3、FbxExporter的使用
4、Fbx SDK支持的文件格式
Autodesk FBX SDK document本篇地址:
http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html
不知道是MFC还是.Net 。这两个我一个都不会,所以还是写个控制台的……
#include<fbxsdk.h> #pragma comment(lib,"libfbxsdk.lib") FbxManager *g_pFbxManager=NULL; /*** 初始化FbxSDK ***/ bool InitializeFbxSDK() { bool bRet=false; do { //创建FbxManager g_pFbxManager=FbxManager::Create(); //创建FbxIOSetting FbxIOSettings *pFbxIOSettings=FbxIOSettings::Create(g_pFbxManager,IOSROOT); //绑定关系 g_pFbxManager->SetIOSettings(pFbxIOSettings); bRet=true; } while (0); return bRet; } /*** 获取Fbx SDK 支持读入的格式 ***/ void GetFileCanImport() { int count= g_pFbxManager->GetIOPluginRegistry()->GetReaderFormatCount(); printf("支持导入以下 %d 种文件格式:\n",count); FbxString s; int i=0; for (int i = 0; i <count; i++) { s+=g_pFbxManager->GetIOPluginRegistry()->GetReaderFormatDescription(i); //获取描述 //s+=g_pFbxManager->GetIOPluginRegistry()->GetReaderFormatExtension(i); //获取文件后缀 s="%d : "+s+" \n"; printf(s.Buffer(),i); s.Clear(); } } /*** 获取Fbx SDK 可以导出的格式 ***/ void GetFileCanExport() { int count=g_pFbxManager->GetIOPluginRegistry()->GetWriterFormatCount(); printf("支持导出以下 %d 种文件格式:\n",count); FbxString s; int i=0; for (int i = 0; i < count; i++) { s+=g_pFbxManager->GetIOPluginRegistry()->GetWriterFormatDescription(i); //获取描述 //s+=g_pFbxManager->GetIOPluginRegistry()->GetWriterFormatExtension(i);//获取文件后缀 s="%d : "+s+" \n"; printf(s.Buffer(),i); s.Clear(); } } /*** 读入一个Fbx文件到FbxScene ***/ bool ImportFbxModel(FbxScene* scene,const char* importfilename) { int fileVerMajorNum,fileVerMinorNum,fileVerRevision; //文件大版本号、小版本号,修正版本号 int sdkVerMajorNum,sdkVerMinorNum,sdkVerRevision; //FBX SDK版本号 int animStackCount; //动画的数量 bool bRet=false; char password[1024]; //密码,文件可能加密了需要输入密码 //获取FBX SDK的版本号 FbxManager::GetFileFormatVersion(sdkVerMajorNum,sdkVerMinorNum,sdkVerRevision); //创建FbxImporter FbxImporter *pFbxImporter=FbxImporter::Create(g_pFbxManager,importfilename); //初始化FbxImporter const bool importret= pFbxImporter->Initialize(importfilename,-1,g_pFbxManager->GetIOSettings()); //获取Fbx文件的版本号 pFbxImporter->GetFileVersion(fileVerMajorNum,fileVerMinorNum,fileVerRevision); if(!importret) //导入出错 { FbxString errorStr=pFbxImporter->GetStatus().GetErrorString(); printf("\nFbxImporter初始化失败,错误原因:%s\n",errorStr.Buffer()); if(pFbxImporter->GetStatus().GetCode() == FbxStatus::eInvalidFileVersion) //如果是文件版本不正确 { printf("\n FBX SDK 版本:%d.%d.%d\n",sdkVerMajorNum,sdkVerMinorNum,sdkVerRevision); printf("\nFBX 文件版本 :%d.%d.%d\n",fileVerMajorNum,fileVerMinorNum,fileVerRevision); } return false; } printf("\n ***** 导入文件成功****** \n"); printf("\n FBX SDK 版本:%d.%d.%d \n",sdkVerMajorNum,sdkVerMinorNum,sdkVerRevision); if(pFbxImporter->IsFBX() ) //如果导入的文件是FBX格式 { printf("\n FBX 文件版本 :%d.%d.%d \n",fileVerMajorNum,fileVerMinorNum,fileVerRevision); //在FBX文件中,一个Scene中可能有一个或多个 "animation stack",一个"animation stack"里面存放一个动画数据,如果想获取"animation stack"的信息,不必要载入全部的Scene printf("\n Animation stack 信息:\n"); animStackCount=pFbxImporter->GetAnimStackCount(); printf("数量:%d\n ",animStackCount); printf("名称:%s\n ",pFbxImporter->GetActiveAnimStackName()); for (int i = 0; i < animStackCount; i++) { FbxTakeInfo *pFbxTakeInfo=pFbxImporter->GetTakeInfo(i); printf("Animation Stack %d\n",i); printf(" Name: %s\n",pFbxTakeInfo->mName.Buffer()); printf(" Description: %s\n",pFbxTakeInfo->mDescription.Buffer()); printf(" Import Name: %s\n",pFbxTakeInfo->mImportName.Buffer()); //导入进来的名字 printf(" Import State: %s\n",pFbxTakeInfo->mSelect ?"true":"false"); } //导入内容设置,默认导入所有内容 g_pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_MATERIAL,true); g_pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_TEXTURE,true); g_pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_LINK,true); g_pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_SHAPE,true); g_pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_GOBO,true); g_pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_ANIMATION,true); g_pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS,true); } //如果导入的文件不是FBX格式,那就没有上面的逻辑 //导入Fbx到场景 bRet = pFbxImporter->Import(scene); //如果文件导入出错,并且是返回错误Code是密码错误 if(bRet==false && pFbxImporter->GetStatus().GetCode()==FbxStatus::ePasswordError) { printf("请输入密码:\n"); password[0]='\0'; FBXSDK_CRT_SECURE_NO_WARNING_BEGIN//这个宏是用来关闭4996警告。类似scanf strcpy strcat在vs下都会有警告 scanf("%s",password); FBXSDK_CRT_SECURE_NO_WARNING_END FbxString passwdStr(password); g_pFbxManager->GetIOSettings()->SetStringProp(IMP_FBX_PASSWORD,passwdStr);//对FbxIOSetting设置StringProp,即字符串属性,Prop这里指property g_pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_PASSWORD_ENABLE,true);//设置Bool属性,是否使用密码 bRet=pFbxImporter->Import(scene); //输入密码后重新Import if(bRet==false && pFbxImporter->GetStatus().GetCode()==FbxStatus::ePasswordError) { printf("文件导入错误,密码错误!"); } } pFbxImporter->Destroy(); return bRet; } /*** 导出FbxScene到模型文件 ***/ bool ExportFbxSceneToModel(FbxScene* scene,const char* exportfilename,int exportformat,bool pexportmedia) { bool bRet=false; //创建FbxExporter FbxExporter *pFbxExport = FbxExporter::Create(g_pFbxManager,""); if(exportformat<0 || exportformat>=g_pFbxManager->GetIOPluginRegistry()->GetWriterFormatCount()) { //如果选择导出的文件格式不支持 printf(" 不支持导出该种格式!! \n"); return false; exportformat=g_pFbxManager->GetIOPluginRegistry()->GetNativeWriterFormat(); printf(" 尝试默认的格式(FBX)导出:%d ",exportformat); if(!pexportmedia) //如果不导出多媒体 { int formatcount=g_pFbxManager->GetIOPluginRegistry()->GetWriterFormatCount(); //尝试导出FBX的 ascii文件,即能看到内容能够的 for (int i = 0; i < formatcount; i++) { if(g_pFbxManager->GetIOPluginRegistry()->WriterIsFBX(i)) { FbxString desStr=g_pFbxManager->GetIOPluginRegistry()->GetWriterFormatDescription(i); if(desStr.Find("ascii")>=0) { exportformat=i; break; } } } } } //选择导出格式正确的话就没有上面的逻辑 if(!pFbxExport->Initialize(exportfilename,-1,g_pFbxManager->GetIOSettings())) { printf("FbxExport->Initialize Faild \n"); printf("FbxExport 初始化失败原因:%s",pFbxExport->GetStatus().GetErrorString()); return false; } if(g_pFbxManager->GetIOPluginRegistry()->WriterIsFBX(exportformat)) { g_pFbxManager->GetIOSettings()->SetBoolProp(EXP_FBX_MATERIAL,true); g_pFbxManager->GetIOSettings()->SetBoolProp(EXP_FBX_TEXTURE,true); g_pFbxManager->GetIOSettings()->SetBoolProp(EXP_FBX_EMBEDDED,pexportmedia); g_pFbxManager->GetIOSettings()->SetBoolProp(EXP_FBX_SHAPE,true); g_pFbxManager->GetIOSettings()->SetBoolProp(EXP_FBX_GOBO,true); g_pFbxManager->GetIOSettings()->SetBoolProp(EXP_FBX_ANIMATION,true); g_pFbxManager->GetIOSettings()->SetBoolProp(EXP_FBX_GLOBAL_SETTINGS,true); } bRet=pFbxExport->Export(scene); pFbxExport->Destroy(); return bRet; } /*** 转换一个模型文件 ***/ void ConvertModelFile(const char *importfilename,const char *exportfilename,int writefileformat) { printf("导入文件路径:%s\n 导出文件路径:%s \n 导出文件格式:%d\n",importfilename,exportfilename,writefileformat); //创建FbxScene,名字就叫做宝箱吧 Baoxiang FbxScene *pFbxScene=FbxScene::Create(g_pFbxManager,"Baoxiang"); printf("\n ****** 转换开始 ****** \n"); bool b=ImportFbxModel(pFbxScene,importfilename); if(b) { printf("\n** 模型文件载入成功 ****\n"); } else { printf("\n** 模型文件载入失败 ****\n"); pFbxScene->Destroy(); return; } printf("\n** 开始导出 ****\n"); b=ExportFbxSceneToModel(pFbxScene,exportfilename,writefileformat,false); if(b) { printf("\n** 导出模型文件成功 ****\n"); } else { printf("\n** 导出模型文件失败 ****\n"); pFbxScene->Destroy(); return; } } int main(int argc,char **argv) { InitializeFbxSDK(); GetFileCanImport(); GetFileCanExport(); char importfilename[1024]; int exportformat=0; char exportfilename[1024]; printf("\n请输入导入文件路径:"); scanf("%s",importfilename); printf("\n请输入导出格式:"); scanf("%d",&exportformat); printf("\n请输入导出文件路径:"); scanf("%s",exportfilename); ConvertModelFile(importfilename,exportfilename,exportformat); system("pause"); return 0; }
项目打包下载:
http://code.taobao.org/svn/xgameengine/trunk/OtherProject/FbxDemo
Autodesk FBX SDK Program 中文 (二),布布扣,bubuko.com
Autodesk FBX SDK Program 中文 (二)
原文地址:http://blog.csdn.net/huutu/article/details/36247427