Autodesk FBX SDK Program 中文 (一)

这是我的FBX SDK学习笔记。如文有错误。麻烦各位大大指出 微笑


为什么要使用FBX SDK?

由于3D建模软件都被AutoDesk收购了。FBX能够在各个建模软件之间互相导入导出,在非常多游戏引擎中也用FBX来直接导入然后编辑。


学会使用FBX SDK后该干什么?

用FBX SDK解析出在fbx文件里保存的顶点、骨骼、贴图、灯光、法线等信息后,保存为自己的模型格式或者直接渲染出来。嗯。对。FBX是作为中间件存在,不会直接用在游戏中。


Autodesk FBX SDK Program 中文 (一)

要直接贴代码了。

代码中会有一些中文的解释。出自有道翻译……偷笑

首先看看环境配置,一个普通的空project。


加入头文件路径:



加入链接文件文件夹:



加入链接文件:

阿嘞,没有链接文件。

我们在代码里面把lib加进来就好了。


复制dll文件到debug文件夹:



还缺一个 fbx文件……。从网上下一个吧。放到project文件夹(看各人设置吧。VS默认是这里)


好了万事具备,贴代码!

#include<fbxsdk.h>

#pragma comment(lib,"libfbxsdk.lib")


int numTabs=0;

void PrintTabs()  //打印tabs。造出像xml那样的效果
{
	for (int i = 0; i < numTabs; i++)
	{
		printf("\t");
	}
}


/**
*依据节点属性的不同,返回字符串。就是返回节点属性的名字
**/
FbxString GetAttributeTypeName(FbxNodeAttribute::EType type)
{
	switch (type)
	{
	case FbxNodeAttribute::eUnknown: return "UnknownAttribute";
	case FbxNodeAttribute::eNull: return "Null";
	case FbxNodeAttribute::eMarker: return "marker";  //马克……
	case FbxNodeAttribute::eSkeleton: return "Skeleton"; //骨骼
	case FbxNodeAttribute::eMesh: return "Mesh"; //网格
	case FbxNodeAttribute::eNurbs: return "Nurbs"; //曲线
	case FbxNodeAttribute::ePatch: return "Patch"; //Patch面片
	case FbxNodeAttribute::eCamera: return "Camera"; //摄像机
	case FbxNodeAttribute::eCameraStereo: return "CameraStereo"; //立体
	case FbxNodeAttribute::eCameraSwitcher: return "CameraSwitcher"; //切换器
	case FbxNodeAttribute::eLight: return "Light"; //灯光
	case FbxNodeAttribute::eOpticalReference: return "OpticalReference"; //光学基准
	case FbxNodeAttribute::eOpticalMarker: return "OpticalMarker";
	case FbxNodeAttribute::eNurbsCurve: return "Nurbs Curve";//NURBS曲线
	case FbxNodeAttribute::eTrimNurbsSurface: return "Trim Nurbs Surface"; //曲面剪切?
	case FbxNodeAttribute::eBoundary: return "Boundary"; //边界
	case FbxNodeAttribute::eNurbsSurface: return "Nurbs Surface"; //Nurbs曲面
	case FbxNodeAttribute::eShape: return "Shape"; //形状
	case FbxNodeAttribute::eLODGroup: return "LODGroup"; //
	case FbxNodeAttribute::eSubDiv: return "SubDiv";
	default: return "UnknownAttribute";
	}
}



/**
*打印一个属性
**/
void PrintAttribute(FbxNodeAttribute* pattribute)
{
	if(!pattribute)
	{
		return;
	}
	FbxString typeName=GetAttributeTypeName(pattribute->GetAttributeType());
	FbxString attrName=pattribute->GetName();
	PrintTabs();

	//FbxString.Buffer() 才是我们须要的字符数组
	printf("<attribute type='%s' name='%s'/>\n ",typeName.Buffer(),attrName.Buffer());
}


/**
*打印出一个节点的属性,而且递归打印出全部子节点的属性;
**/
void PrintNode(FbxNode* pnode)
{
	PrintTabs();

	const char* nodeName=pnode->GetName(); //获取节点名字

	FbxDouble3 translation=pnode->LclTranslation.Get();//获取这个node的位置、旋转、缩放
	FbxDouble3 rotation=pnode->LclRotation.Get();
	FbxDouble3 scaling=pnode->LclScaling.Get();

	//打印出这个node的概览属性
	printf("<node name='%s' translation='(%f,%f,%f)' rotation='(%f,%f,%f)' scaling='(%f,%f,%f)'>\n",
		nodeName,
		translation[0],translation[1],translation[2],
		rotation[0],rotation[1],rotation[2],
		scaling[0],scaling[1],scaling[2]);

	numTabs++;

	//打印这个node 的全部属性
	for (int i = 0; i < pnode->GetNodeAttributeCount(); i++)
	{
		PrintAttribute(pnode->GetNodeAttributeByIndex(i));
	}

	//递归打印全部子node的属性
	for (int j = 0; j < pnode->GetChildCount(); j++)
	{
		PrintNode(pnode->GetChild(j));
	}

	numTabs--;
	PrintTabs();
	printf("</node>\n");
}


int main(int argc,char** argv)
{
	const char* filename="City-1.fbx";

	//创建SDKManager
	FbxManager* pSdkManager=FbxManager::Create();

	
	FbxIOSettings *pFbxIOSettings=FbxIOSettings::Create(pSdkManager,filename);

	//设置归属
	pSdkManager->SetIOSettings(pFbxIOSettings);

	//创建FbxImporter用来导入fbx文件
	FbxImporter* pImporter=FbxImporter::Create(pSdkManager,"");

	if(!pImporter->Initialize(filename,-1,pSdkManager->GetIOSettings()))
	{
		printf("Call to FbxImporter::Initialize() failed");
		printf("Error returned :%s\n\n", pImporter->GetStatus().GetErrorString());
		return -1;
	}

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

	pImporter->Import(pScene);

	pImporter->Destroy();

	//递归打印出这个场景以下的节点的属性
	//注意我们不会打印出Root节点由于root节点不包括不论什么属性
	FbxNode* pRootNode=pScene->GetRootNode();
	if(pRootNode)
	{
		int nodeCount=pRootNode->GetChildCount();
		for (int i = 0; i < nodeCount; i++)
		{
			PrintNode(pRootNode->GetChild(i));
		}
	}
	pSdkManager->Destroy();

	return 0;
}

执行结果:



posted @ 2017-04-26 14:31  yxysuanfa  阅读(1383)  评论(0编辑  收藏  举报