FBXの構造とAttribute

概要

最終更新日:2020/03/17
FBXSDKバージョン:FBX SDK 2020.0.1 VS2017

FBXファイルの構造とAttributeについて書いた記事です。
主に次の項目に該当する方に向けて書いています。
  • FBXの構造が知りたい
  • Attributeとは何か知りたい
  • ノードのAttributeの取得方法が知りたい
  • 全ノードを網羅する方法をしりたい

サンプル

サンプルはここからダウンロードできます。
環境については以下の内容となっています。

開発環境
VSのバージョン VisualStudio 2019


FBXは木構造

FBXは木構造でデータを管理しています。
木構造は文字通り、データのつながりが木の枝葉の形状と似ていることから
名付けられた構造で、ルートと呼ばれるデータから始まります。
このルートを含めた各データの事をノードと呼んでいます。

model_render_0066

またノードのつながりで、ルートに近い方を、ルートから遠い方をと呼んでいます。

model_render_0067

ノード情報

各ノードは様々なデータを保存できるようになっています。
データの種類は「FbxNodeAttribute」が保存しており、
FBXSDKの中で列挙型が用意されています。
以下はAttributeの種類の一例です。
  • eMesh:メッシュ
  • eSkeleton:ボーン
  • eCamera:カメラ
  • eLight:ライト
  • eUnknown:不明
Attributeで種類を調べればNodeにどのような情報が
保存されているかがわかります。

model_render_0065

ゲームで主に使用するAttributeはeMeshとeSkeletonです。
頂点やマテリアルの情報はeMeshに含まれています。

FbxNodeAttributeの本質

FbxNodeAttributeは様々なデータの基底となっているクラスです。
例えばメッシュデータを保存するクラスでFbxMeshクラスがありますが、
このクラスをさかのぼっていくとFbxNodeAttributeに行きつきます。

model_render_0073

ノードの名前とAttributeを出力する

FBXSDKを使用してFbxファイルのノードの名前とAttribute情報を全て出力します。
先ほども書いていますがFBXは木構造になっているので、データを調べたい場合は
ルートノードを取得すれば全てのデータにたどり着くことが出来ます。
FBXでルートのノードを取得するにはFbxSceneの「GetRootNode」を使用します。

model_render_0059
FbxNode* root_node = fbx_scene->GetRootNode();
if (root_node == nullptr)
{
	// 取得失敗
	return 0;
}

model_render_0068

取得が成功したらノードからFbxNodeAttributeを取得します。
FbxNodeAttributeもNode内で複数設定されていることがあるので、
それらを全て取得するためにFbxNodeの「GetNodeAttributeCount」を使います。

model_render_0060
for (int i = 0; i < node->GetNodeAttributeCount(); i++)
{
}

GetNodeAttributeCountでNodeの持つFbxNodeAttributeの数が分かったら
一つずつ取得してAttributeの種類を調べます。
FbxNodeAttributeの取得はFbxNodeの「GetNodeAttributeByIndex」使用し、
Attributeの種類はFbxNodeAttributeの「GetAttributeType」を使います。

model_render_0061
model_render_0062
for (int i = 0; i < node->GetNodeAttributeCount(); i++)
{
	FbxNodeAttribute* attribute = node->GetAttribute(i);

	FbxNodeAttribute::EType type = attribute->GetAttributeType();

	printf("attribute type => %d\n", type);
}

model_render_0069

これでAttributeの種類の取得ができたので、一つのNodeの調査完了です。
次はこのNodeが子供のNodeを持っているかを「GetChildCount」を使用して調べて
子ノードがあるなら「GetChild」で取得してAttributeを調べます。

model_render_0063
model_render_0064
for (int i = 0; i < node->GetChildCount(); i++)
{
	FbxNode* child = node->GetChild(i);
}

model_render_0070
これを子ノードがなくなるまで繰り返すとFbxの全ノードを網羅できます。
このAttributeと子ノードを調べる方法はMesh情報の取得などで使います。