3Dプログラミング応用 1-1B

~スキンメッシュ対応のxfile表示~

1-1-6.ID3DXSkinInfo::ConvertToBlendedMesh 関数について

ID3DXMesh関数の説明

この関数にはID3DXMeshを入力してID3DXMeshが返ってくる。

もちろんそのまま戻ってくるのではなく、内部では


○頂点、描画面を並べ替えて最適化

○ボーンの影響をうける範囲ごとに、メッシュをサブセットに分割

○頂点情報にブレンド加重値を付与

○ボーンに合わせて頂点を移動


などの細かい処理が行われている。

使う側としては「この関数を通すとメッシュがスキンに対応する」ことが理解できていれば良い。


▲TOP

1-1-7.D3DXBONECOMBINATION 構造体について

ConvertToBlenderMesh関数で戻ってくる ID3DXBuffer には、

D3DXBONECOMBINATION構造体が NumBoneCombinations 個入っている。


↓この構造体の前半部分は、メッシュのサブセットの定義である。

メッシュサブセット情報を格納する D3DXATTRIBUTERANGE構造体 と比較すると一目瞭然である。

D3DXBONECOMBINATION構造体の情報1
D3DXBONECOMBINATION構造体の情報2

↓Boneidには該当サブセットが「どのボーンから影響を受けるか」の情報が格納されている。

BoneCombination構造体の情報
  

▲TOP

1-1-8.実際の描画処理

上記の図でサブセットNを描画する場合 どのようなコードになるか見てみよう。


○ブレンド用にワールド行列を複数設定する

pDev->SetTransform( D3DTS_WORLD(0) , BoneMatrix[ BoneCombination[N].Boneid[0] );

pDev->SetTransform( D3DTS_WORLD(1) , BoneMatrix[ BoneCombination[N].Boneid[1] );


○パラメータにはブレンドに使うボーン数-1をわたす

pDev->SetRenderState( D3DRS_VERTEXBLEND , 1 );


○使用するマテリアルは、AttribIDで指定されている

pDev->SetMaterial( Material[ BoneCombination[N].AttribID ] );


pMesh->DrawSubset( N );


非スキンメッシュとの違いは、


  •    ・ワールド座標を複数設定する
  •    ・D3DRS_VERTEXBLENDを設定する
  •    ・マテリアルIDをBoneCombinationから取得する

の3点となる。

  

▲TOP

1-1-9.構造体の拡張

これまで見てきたように、スキンメッシュ描画にはより多くの情報を管理する必要があるが、

それらのほとんどはFrame情報やMeshContainer情報と組み合わせて利用する。

これらを一元管理できるように D3DXFRAME構造体 および D3DXMESHCONTAINER構造体 を継承した独自の構造体を作成する。


◆ MyAllocateHierarchy.h(一部抜粋)

MyAllocateHierarchy.h(一部)
  

▲TOP

1-1-10.CMyAllocateHierarchyクラスに追記

◆ MyAllocateHierarchy.cpp

MyAllocateHierarchy.cpp
  

▲TOP

1-1-11.CAnimateObjectクラスに追記

◆ AnimateObject.h

AnimateObject.h

◆ AnimateObject.cpp(コンストラクタ・デストラクタ)

CAnimateObjectコンストラクタ・デストラクタ

◆ AnimateObject.cpp(Create データ生成)

CAnimateObject Create データ生成

◆ AnimateObject.cpp(UpdateFrame)

CAnimateObject UpdateFrame

↓以下、1-1-10追加関数

RenderSkin
SetSkinInfo他
  

▲TOP

1-1-12.動作確認

↓コンパイルして実行すると下図のようになる

見た目は1-1-5と大差ないが、ちゃんと頭に髪の毛が生えていればOK。

1-1-12 動作確認
  

▲TOP

>「1-1C モーションの再生」へ続く