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

その8 レイヤー要素を取得する:テクスチャ


 この章ではレイヤー要素の中のテクスチャ情報を取得します。重複を避けるために前章までの説明を前提とします。まだご覧になっていない方は面倒かもしれませんがこの章まで読み進めて下さい。



@ テクスチャ情報

 FBXのレイヤーに含まれるテクスチャはKFbxLayerElementTexture::GetDirectメソッドで得られるKFbxTextureにまとめられます。これらのクラスからは主に次の情報が取得できます

・ ファイル名
・ マッピングタイプ (平面、球状、シリンダ、etc...)
・ 平面マッピング軸 (X、Y、Z軸)
・ テクスチャ使用 (標準、シャドーマップ、ライトマップ、etc...)
・ ラップモード (リピート、クランプ)
・ トリミング領域
・ ブレンドモード (アルファ合成、加算合成、乗算合成)
・ 透過度

 沢山あるのですが、何だかんだで必要な情報です。

 KFbxTextureを取得するには次のようにします:

KFbxTextureを取得
KFbxLayerElementTexture *pTextureElem;

int TextureNum = pTextureElem->GetDirectArray().GetCount();
for ( int t = 0; t < TextureNum; t++ )
{
   KFbxTexture *pTexture = pTextureElem->GetDirectArray().GetAt(t);
}


○ ファイル名

 適用されるテクスチャのファイル名はKFbxLayerElementTexture::GetFileNameメソッドで取得できます:

ファイル名を取得
const char* fileName = pTexture->GetFileName();


○ マッピングタイプ

 マッピングタイプはテクスチャをモデルにどのように貼り付けるかを表したフラグでKFbxTexture::EMappingType列挙型に定義されています:

マッピングタイプ列挙型
typedef enum
{
   eNULL,          // 不定
   ePLANAR,        // 平面
   eSPHERICAL,     // 球面
   eCYLINDRICAL,   // シリンダ(円柱)
   eBOX,           // ボックス(立方体)
   eFACE,          // ?
   eUV,            // UVマップ
   eENVIRONMENT    // 環境マップ
} EMappingType;

マッピングタイプを得るにはKFbxTexture::GetMappingTypeメソッドを用います:

マッピングタイプを取得
KFbxTexture::EMappingType MappingType = pTexture->GetMappingType();

FBXは3Dモデリングツール間の汎用フォーマットとして作られているので、ゲームで使用するにあたってはすべてのマッピングタイプに対応する必要は無いかなと思います。大抵は貼り付けが容易なUVマップになると思います。


○ 平面マッピング軸

 マッピングタイプが平面だった時に貼り付ける軸の方向です。これはKFbxTexture::GetPlanarMappingNormalメソッドを用います:

平面マッピング軸を取得
KFbxTexture::EPlanarMappingNormal PlanarMappingNormal = pTexture->GetPlanarMappingNormal();

戻り値のEPlanarMappingNormal列挙型は次の通りです:

KFbxTexture::EPlanarMappingNormal列挙型
typedef enum
{
   ePLANAR_NORMAL_X,
   ePLANAR_NORMAL_Y,
   ePLANAR_NORMAL_Z
} EPlanarMappingNormal;

見たままですね。このフラグをゲームで直接使用する事は少ないかもしれません。


○ テクスチャ使用

 テクスチャを何に使用するかを判定するフラグです。KFbxTexture::GetTextureUseメソッドで得られます:

テクスチャ使用を取得
KFbxTexture::ETextureUse TextureUse = pTexture->GetTextureUse();

KFbxTexture::ETextureUse列挙型は次の通りです:

KFbxTexture::ETextureUse列挙型
typedef enum
{
   eSTANDARD,                 // 標準
   eSHADOW_MAP,               // シャドーマップ
   eLIGHT_MAP,                // ライトマップ
   eSPHERICAL_REFLEXION_MAP,  // 球面反射マップ
   eSPHERE_REFLEXION_MAP,     // 球面反射マップ
   eBUMP_NORMAL_MAP           // バンプ法線マップ
} ETextureUse;


○ ラップモード

 UVが0以下及び1以上の範囲で定義されている時にテクスチャをどう貼り付けるかを判別するフラグです。KFbxTexture::GetWrapModeUメソッドとKFbxTexture::GetWrapModeVメソッドで取得できます:

ラップモードを取得
KFbxTexture::EWrapMode WrapMode_U = pTexture->GetWrapModeU();
KFbxTexture::EWrapMode WrapMode_V = pTexture->GetWrapModeV();

KFbxTexture::EWrapMode列挙型は次の通りです:

KFbxTexture::EWrapMode
typedef enum
{
   eREPEAT,   // 繰り返し
   eCLAMP     // 切り取り
} EWrapMode;

eREPEATはテクスチャを同じように繰り返します。タイル張りのようになるわけです。eCLAMPははみ出たUVにはテクスチャを張りません。この設定はDirect3DのIDirect3DDevice9::SetSamplerStateメソッドで反映できます。


○ トリミング領域

 テクスチャの使用範囲を限定する場合にはトリミング領域(クリッピング領域)に有効な値が格納されてきます。トリミング領域は次のようなメソッドで取得できます:

トリミング領域を取得
// クリッピング
double left   = pTexture->GetCroppingLeft();
double top    = pTexture->GetCroppingTop();
double right  = pTexture->GetCroppingRight();
double bottom = pTexture->GetCroppingBottom();

bool isCropping = true;
if ( left == 0.0 &&right == 0.0 && top == 0.0f && bottom == 0.0f )
   isCropping = false; // クリッピングしない

戻り値はクリッピングされるテクセル座標値です。トリミングが設定されていない場合、すべての値が0になるようです。その場合はクリッピングしないようにします。


○ ブレンドモード

 ブレンドモードはテクスチャの合成方法を判別するフラグです。これはFbxTextureではなくてFbxLayerElementTexture::GetBlendModeで取得します:

ブレンドモードを取得
KFbxLayerElementTexture::EBlendMode BlendMode = pTextureElem->GetBlendMode();

戻り値のKFbxLayerElementTexture::EBlendMode列挙型にはブレンド方法が定義されています:

KFbxLayerElementTexture::EBlendMode列挙型
typedef enum
{
   eTRANSLUCENT,   // アルファ合成
   eADD,           // 加算合成
   eMODULATE,      // 乗算合成
   eMODULATE2,     // 2倍乗算合成
   eMAXBLEND       // 終端(使用しません)
} EBlendMode;

これはレイヤー単位での合成方法を示しています。つまりレイヤー0番が最初にモデルに貼り付けられた後、続くレイヤー1番のテクスチャが上の合成方法で0番と合成されます。合成の詳しい式は特に難しい部分は無いと思いますので省略します。


○ 透過度

 透過度もレイヤー単位の値でFbxLayerElementTexture::GetAlphaメソッドで得られます。これは合成時のアルファの調節値となります:

透過度を取得
double alpha = pTextureElem->GetAlpha();


 これでテクスチャに関する情報はだいたい取得できました。問題はこの情報をどうプログラム側で反映させるかですが、それについては別章で試行錯誤してみたいと思います。