その5 レイヤーとマッピングとリファレンス
前章ではメッシュ(KFbxMesh)からポリゴンの情報とメッシュ単位の頂点情報(頂点数・頂点座標配列)を得る方法を見てきました。その中で1つのメッシュに複数の「レイヤー」が重なると説明しました。
この章ではレイヤーから頂点の情報を取得する方法、そしてそこでお世話になる「マッピング」と「リファレンス」について見ていきます。とても重要なんです。
@ レイヤーの持つ情報
メッシュに定義されているレイヤー(KFbxLayer)を取得するにはKFbxMesh::GetLayerメソッドを用います:
頂点数と頂点座標配列を取得 for ( int v = 0; v < vertexNum; v++ ) {
// 頂点vの位置座標情報
KFbxVector4 Coordinate = pVertexAry[v];
// レイヤー取得
for ( int l = 0; l < layerNum; l++ ) {
KFbxLayer pLayer = pMesh->GetLayer(l);
// レイヤーから頂点vについての情報を得る//
}
}
このようにして得た1つのレイヤーには以下のような情報が含まれています:
・ Normals
・ UVs
・ Textures (diffuse, ambient, specular, etc.)
・ Materials
・ Polygon Groups
・ Vertex Colors
・ Smoothing information
・ Custom User Data
法線、UV、テクスチャ、マテリアル、ポリゴングループ、頂点カラー、平滑化情報そしてユーザデータの情報が含まれています。これらは「要素(Element)」と呼ばれています。各要素の情報を取得するためのメソッドがKFbxLayerクラスにはたっぷり含まれています。
各要素は最終的には配列やオブジェクトの形で情報を取得できます。しかし、同じ要素でも配列に並ぶ情報の意味合いが異なる事があります。例えば法線の場合は頂点単位で設定されているのか面単位で設定されているのかという違いがあります。配列にどう配置されているのかを知るには、各要素で「マッピング情報」を確認する必要があります。
各要素のマッピング情報は、もちろん要素によって別々です。レイヤーから要素を取り出すには各要素の取得メソッドを用います。例えば法線情報を取り出すにはKFbxLayer::GetNormalsメソッドを用います。このメソッドはKFbxLayerElementNormalオブジェクトを返します:
法線オブジェクトの取得 for ( int l = 0; l < layerNum; l++ )
KFbxLayerElementNormal* pNormalAry = pMesh->GetLayer(l)->GetNormals();
KFbxLayerElement***系のクラスにはマッピングモードを取得できるGetMappingModeメソッドがあります:
要素のマッピングモードの取得 KFbxLayerElement::EMappingMode mode = pNormalAry->GetMappingMode();
GetMappingModeの戻り値はKFbxLayerElement::EMappingMode列挙型です。この列挙型には次の定義があります:
・ eNONE
・ eBY_CONTROL_POINT
・ eBY_POLYGON_VERTEX
・ eBY_POLYGON
・ eBY_EDGE
・ eALL_SAME
これらの違いを一つずつ見ていきます。
○ eNONE
マッピング定義がありません。
○ eBY_CONTROL_POINT
「コントロールポイント(制御点)」というモデルの表面の形状を決める点に対して1つのマッピング座標が定義されています。3Dモデルにはポリゴンをベースとする物と自由曲面をベースとするものがあります。コントロールポイントはそのうちの自由曲面ベースのモデルに対して定義される点です。滑らかな表面上の点のイメージです。
○ eBY_POLYGON_VERTEX
ポリゴンを構成する頂点に対してマッピングされています。DirectXで扱う頂点と同じです。
○ eBY_POLYGON
全ポリゴンに対してただ1つだけマッピングされています。法線等ではありませんが、こういう要素ももちろんあります。
○ eBY_EDGE
メッシュのエッジに対してマッピングされています。これは平滑化要素が使われている事を表しています。プログラムで扱う事は殆ど無いと思います。
○ eALL_SAME
全サーフェイスに対してただ1つだけマッピングされています。
各要素によってどれが使われるかだいたい決まっています。例えば法線ならeBY_CONTROL_POINTかeBY_POLYGON_VERTEXのどちらかです。何でも読み込める物を作るのではないならば、これらのフラグに適うようなモデルを作るようにした方が良いかと思います。
さて、マッピングモードは要素の使われ方を表す情報ですが、実際に要素のがどう格納されているかは別のフラグを知る必要があります。それが「リファレンス情報」です。
B リファレンス情報
リファレンス情報は要素が配列にどう格納されているかを表すフラグです。1つの要素のリファレンス情報はKFbxLayerElement::GetReferenceModeメソッドを通してKFbxLayerElement::EReferenceMode列挙型として取得できます。この列挙型には次の3つが定義されています:
・ eDIRECT
・ eINDEX
・ eINDEX_TO_DIRECT
これも違いを知っておく必要があります。
○ eDIRECT
Directという名前の通り、欲しい要素が配列に直接格納されています。KFbxLayerEementはmDirectArrayとmIndexArrayという2つの配列を持っています。eDIRECTフラグである要素はmDirectArrayに要素が格納されてます。
○ eINDEX
これはFBX v5.0まで使用されていたフラグで、FBX v6.0以降からは次のeINDEX_TO_DIRECTに統合されています。
○ eINDEX_TO_DIRECT
これはマニュアルでも長々と説明されています(^-^;。これは先ほど説明したmDirectArrayとmIndexArratの両方に情報が含まれています。mIndexArrayには要素へのインデックス番号が、そしてmDirectArrayには要素本体が格納されています。この仕組みは3D描画時にインデックスバッファを作るのと一緒です。例えば頂点が何度も重なる所に要素も重ねてしまうとメモリスペースを多大に圧迫します。容量の多い要素は重ならないように最適化しておいて、うんと小さい整数値(インデックス)で重なりを表現すればメモリが節約できます。
マッピング情報とリファレンス情報を見ることで、レイヤー内の注目する要素の種別と格納されているデータが確定します。次の章では実際にこれらの情報を元にしてレイヤーごとの頂点情報を取得してみたいと思います。