FBXの構造とAttribute
概要
最終更新日:2020/03/17 FBXSDKバージョン:FBX SDK 2020.0.1 VS2017 FBXファイルの構造とAttributeについて書いた記事です。 主に次の項目に該当する方に向けて書いています。
- FBXの構造が知りたい
- Attributeとは何か知りたい
- ノードのAttributeの取得方法が知りたい
- 全ノードを網羅する方法をしりたい
サンプル
サンプルはここからダウンロードできます。 環境については以下の内容となっています。
VSのバージョン | VisualStudio 2019 |
---|
FBXは木構造
FBXは木構造でデータを管理しています。 木構造は文字通り、データのつながりが木の枝葉の形状と似ていることから 名付けられた構造で、ルートと呼ばれるデータから始まります。 このルートを含めた各データの事をノードと呼んでいます。 またノードのつながりで、ルートに近い方を親、ルートから遠い方を子と呼んでいます。
ノード情報
各ノードは様々なデータを保存できるようになっています。 データの種類は「FbxNodeAttribute」が保存しており、 FBXSDKの中で列挙型が用意されています。 以下はAttributeの種類の一例です。
- eMesh:メッシュ
- eSkeleton:ボーン
- eCamera:カメラ
- eLight:ライト
- eUnknown:不明
Attributeで種類を調べればNodeにどのような情報が 保存されているかがわかります。 ゲームで主に使用するAttributeはeMeshとeSkeletonです。 頂点やマテリアルの情報はeMeshに含まれています。
FbxNodeAttributeの本質
FbxNodeAttributeは様々なデータの基底となっているクラスです。 例えばメッシュデータを保存するクラスでFbxMeshクラスがありますが、 このクラスをさかのぼっていくとFbxNodeAttributeに行きつきます。
ノードの名前とAttributeを出力する
FBXSDKを使用してFbxファイルのノードの名前とAttribute情報を全て出力します。 先ほども書いていますがFBXは木構造になっているので、データを調べたい場合は ルートノードを取得すれば全てのデータにたどり着くことが出来ます。 FBXでルートのノードを取得するにはFbxSceneの「GetRootNode」を使用します。FbxNode* root_node = fbx_scene->GetRootNode(); if (root_node == nullptr) { // 取得失敗 return 0; }
取得が成功したらノードからFbxNodeAttributeを取得します。 FbxNodeAttributeもNode内で複数設定されていることがあるので、 それらを全て取得するためにFbxNodeの「GetNodeAttributeCount」を使います。for (int i = 0; i < node->GetNodeAttributeCount(); i++) { }
GetNodeAttributeCountでNodeの持つFbxNodeAttributeの数が分かったら 一つずつ取得してAttributeの種類を調べます。 FbxNodeAttributeの取得はFbxNodeの「GetNodeAttributeByIndex」使用し、 Attributeの種類はFbxNodeAttributeの「GetAttributeType」を使います。for (int i = 0; i < node->GetNodeAttributeCount(); i++) { FbxNodeAttribute* attribute = node->GetAttribute(i); FbxNodeAttribute::EType type = attribute->GetAttributeType(); printf("attribute type => %d\n", type); }
これでAttributeの種類の取得ができたので、一つのNodeの調査完了です。 次はこのNodeが子供のNodeを持っているかを「GetChildCount」を使用して調べて 子ノードがあるなら「GetChild」で取得してAttributeを調べます。for (int i = 0; i < node->GetChildCount(); i++) { FbxNode* child = node->GetChild(i); }
これを子ノードがなくなるまで繰り返すとFbxの全ノードを網羅できます。 このAttributeと子ノードを調べる方法はMesh情報の取得などで使います。