ホーム < ゲームつくろー! < FBX習得編

その3 ノードを巡って巡って・・・


 FBXの内部は「ノード」という樹状の塊になっています。ノードから必要な情報を読み取りプログラムに取り込んでいく。それがFBX SDKの使い方(読み込み方)の基本となります。この章ではノードを辿る方法を見ていくことにしましょう。



@ KFbxNodeクラス

 ノード情報はすべてKfbxNodeクラスに格納されています。ノードはエクスプローラのように階層上に連なっていて、すべてのサブノードは「ルートノード」の下に置かれます。ルートノードは前章で取得したKFbxSceneオブジェクトから取得できます:

ルートノードを取得
KFbxNode *pRootNode = pScene->GetRootNode();

 あるノードにぶら下がっているサブノード(子ノード)の数はKFbxNode::GetChildCountメソッドで取得できます:

子ノードの数を取得
int childNodeNum = pRootNode->GetChildCount();

取得した子ノードの数から順にノードを辿る事ができます。あるノードにぶら下がっている子ノードを取得するにはKFbxNode::GetChildメソッドを用います:

子ノードを取得
for ( int i = 0; i < childNodeNum; i++ )
{
   KFbxNode *pChild = pRootNode->GetChild(i);  // 子ノードを取得
}

 もちろん、子ノードの下には孫ノードもひ孫ノードも存在します。これをすべて辿るには必然的に再帰関数が必要になります。典型的なのは次のような関数です:

ノードを辿る再帰関数
void RecursiveNode( KFdxNode *pNode )
{
   for ( int i = 0; i < childNodeNum; i++ )
   {
      KFbxNode *pChild = pRootNode->GetChild(i);  // 子ノードを取得
      RecursiveNode( pChild );
   }
}

上の関数はただノードを巡って終わるわけで楽しくも何ともありません。ここから情報を取得する仕組みを整える必要があります。



A ノードタイプ

 ノードに含まれる情報は実に様々です。それを判別するにはKFbxNode::GetNodeAttributeメソッドでノード属性クラス(KFbxNodeAttribute)のオブジェクトを取得し、そこからノードタイプを得ます:

ノードタイプを取得
KFbxNodeAttribute *pAttrib = pNode->GetNodeAttribute();
if ( pAttrib ) {
   KFbxNodeAttribute::EAttributeType type = pAttrib->GetAttributeType();
}

KFbxNodeAttribute::EAttributeType列挙型にはノードタイプが列挙されています。取得可能なフラグは次の通りです:

ノードタイプ
typedef enum
{
   eUNIDENTIFIED,        // 不定
   eNULL,                // NULL
   eMARKER,              // マーカー
   eSKELETON,            // スケルトン(ボーン)
   eMESH,                // メッシュ
   eNURB,                // NURBS
   ePATCH,               // パッチ
   eCAMERA,              // カメラ
   eCAMERA_SWITCHER,     // カメラスイッチャ
   eLIGHT,               // ライト
   eOPTICAL_REFERENCE,   // ?
   eOPTICAL_MARKER,      // ?
   eCONSTRAINT,          // 制約条件
   eNURBS_CURVE,         // NURBS曲線
   eTRIM_NURBS_SURFACE,  // NURBSトリム
   eBOUNDARY,            // 境界ボリューム配列
   eNURBS_SURFACE        // NURBS曲面
} EAttributeType;

分かる範囲です、すいません

 非常に沢山の種類がありますが、すべて使う必要はありません。以後の章ではこのノードタイプの情報について詳細を追います。

 再帰関数内ではこのノードタイプを判別して独自の取得部分を実装します:

ノードタイプで取得関数を区別(再帰関数内)
KFbxNodeAttribute::EAttributeType type = pAttrib->GetAttributeType();
switch ( type )
{
   case KFbxNodeAttribute::eUNIDENTIFIED:
   case KFbxNodeAttribute::eNULL:
      return;
   case KFbxNodeAttribute::eMESH:
      GetMesh( pAttrib );     // メッシュを作成
      return;
   case KFbxNodeAttribute::eCamera:
      GetCamera( pAttrib );   // カメラを作成
}

実は、後の章で出てきますが、各取得関数にノードから派生したKFbxNodeAttributeへのポインタを渡すのがコツです。と言うのもこれが無いと各種情報を得る事ができないんです。

 どういう事かというと、ノードの各属性を表す具体的なクラスのほとんどはKFbxNodeAttributeクラスから派生されているんです。その様子を表した下のクラス図をご覧下さい:


 FKbxNodeAttributeクラスが大親分になっていて、その下に沢山の子クラスが並んでいます。先に取得したノードのノードタイプは上の子クラスに対応しています。つまりKFbxNodeAttribute::GetAttributeTypeメソッドでノードタイプを確定させたら、KFbxNodeAttributeをダウンキャストして各具象クラスにしてしまいます。これで、各子クラスが持つ具体的なメソッドを呼び出すことができ、上のクラス図で分類された情報を取得することができます。

 次の章では、上のクラスの右上から2番目にあるKFbxMeshが持つ、3Dモデルにおいて最重要情報である「メッシュ情報」を取得してみましょう。