使用SDK对FBX模型的加载与读取

来源:互联网 发布:淘宝网蚕丝被多少钱 编辑:程序博客网 时间:2024/05/22 07:03

一.初始化FBX  SDK

FbxManager* pManager = NULL;
FbxScene* pScene = NULL;
pManager = FbxManager::Create();
if( !pManager )
{
//出错处理
}
FbxIOSettings* ios = FbxIOSettings::Create(pManager, IOSROOT);
pManager->SetIOSettings(ios);
pScene = FbxScene::Create(pManager, "My Scene");
if( !pScene )
{
//出错处理
}

上面代码中出现了KFbxIOSettings类,这是一个用来配置KFbxSdkManage的对象,可以通过这个对象设置一些导入导出时的行为,比如可以选择不导入材质,动画等等。

bool LoadScene(FbxManager* pManager, FbxDocument* pScene, const char* pFilename)
{
// Create an importer.
FbxImporter* lImporter = FbxImporter::Create(pManager,"");
//Initialize the importer by providing a filename.
const bool lImportStatus = lImporter->Initialize(pFilename, -1, pManager->GetIOSettings());
if( !lImportStatus )
{
//出错处理
}
// Import the scene.
lStatus = lImporter->Import(pScene);
// Destroy the importer.
lImporter->Destroy();
return lStatus;
}
 

二.读取FBX数据

FBX采用的是类似于树是形式存储的,因此可以以类似于树的递归方法来遍历其中的每个结点,并根据结点的属性选择合适的处理操作。根节点包含了一系列子节点KFbxNode,每个KFbxNode又有其自己的子节点。KFbxNode包含了坐标变换信息,可以通过一系列get函数取得,其他数据作为KFbxNodeAttribute对象,包含在KFbxNode内部,这里的其他数据是指mesh,Nurbs,skeletion,camara,light等定义在KFbxNodeAttribute::EAttributeType中的类型。一个KFbxNode可以有多个子KFbxNode ,可以通过KFbxNodeAttribute的GetAttributeType()方法,确定当前node的所包含的实际数据类型:

1.递归处理根节点

获得根结点:KFbxNode* root = scene->GetRootNode();

递归处理每个结点: 

void ProcessNode(KFbxNode* pNode) 

{  

if(pNode->GetNodeAttribute())  

{   

switch(pNode->GetNodeAttribute()->GetAttributeType())   

{   

case KFbxNodeAttribute::eMESH:    ProcessMesh(pNode);    break;   

case KFbxNodeAttribute::eSKELETON:    ProcessSkeleton(pNode);    break;   

case KFbxNodeAttribute::eLIGHT:    ProcessLight(pNode);    break;   

case KFbxNodeAttribute::eCAMERA:    ProcessCamera();    break;   

....

}  

}   

for(int i = 0 ; i < pNode->GetChildCount() ; ++i)  

{   

ProcessNode(pNode->GetChild(i));  

}

在FBX的存储中,每个父结点可以包含多个子结点,但每个子结点只有一个根结点,而且这其中的联系是双向的,这样很方便,比如在处理Skeleton时就常常需要从子结点中得到父结点的matrix等信息,而这种双向关系使得这些操作很容易实现。注意,上述代码中有pNode->GetNodeAttribute()检查操作是必须的,因为并不是所有的结点都有相应的属性(Attribute也是以子结点的方式关联到当前的结点上的,因而可能为空)。


2.加载网格

void ProcessMesh(KFbxNode* pNode) 
 KFbxMesh* pMesh = pNode->GetMesh();
 if(pMesh == NULL) { return; } 
 D3DXVECTOR3 vertex[3]; 
 D3DXVECTOR4 color[3]; 
 D3DXVECTOR3 normal[3]; 
 D3DXVECTOR3 tangent[3]; 
 D3DXVECTOR2 uv[3][2]; 
 int triangleCount = pMesh->GetPolygonCount();
 int vertexCounter = 0; 
 for(int i = 0 ; i < triangleCount ; ++i) 
 
 for(int j = 0 ; j < 3 ; ++j) 
 
 int ctrlPointIndex = pMesh->GetPolygonVertex(i , j); 
// Read the vertex 
 ReadVertex(pMesh , ctrlPointIndex , &vertex[j]); 
 // Read the color of each vertex 
 ReadColor(pMesh , ctrlPointIndex , vertexCounter , &color[j]); 
 // Read the UV of each vertex 
 for(int k = 0 ; k < 2 ; ++k) 
 
 ReadUV(pMesh , ctrlPointIndex , pMesh->GetTextureUVIndex(i, j) , k , &(uv[j][k])); 
 // Read the normal of each vertex 
 ReadNormal(pMesh , ctrlPointIndex , vertexCounter , &normal[j]); 
 // Read the tangent of each vertex 
 ReadTangent(pMesh , ctrlPointIndex , vertexCounter , &tangent[j]); 
 vertexCounter++; 
 
 // 根据读入的信息组装三角形,并以某种方式使用即可,比如存入到列表中、保存到文件等...
}




 


0 0
原创粉丝点击