アニメーションデータを含むXファイルの取り扱い

普通にただ静止状態のメッシュを表示するのはものすごく楽なDirectXなのですが、アニメーションデータを含むXファイルを表示させるのは一苦労だ。いや、一苦労どころの騒ぎじゃない。もう少しなんとかならんもんか?と思うこと間違いない。

アニメーションを含まないXファイルの場合

今までのファイルを D3DXLoadMeshFromX メソッドで、ファイルを読み込み、メッシュ情報、マテリアル情報を取得して、そこから DrawSubset でメッシュを描画していけばいい。
ちょっと参考書を見れば、ほとんどどれも同じことをやっているので、それらをコピペして気になる部分を後から少々修正すればいい。特に問題はない。

アニメーションを含むXファイルの場合

これがアニメーションを含んだXファイルになったとたん、今までDirectXが以下に水面下でいろいろやってたのか、その苦労をアプリケーションプログラマに見せつけてやらん、とばかりに牙をむいてくる。
それでもやろうとするなら、その前に用語をいくつか抑えておいたほうがいい。「フレーム」とは、3DCGソフトで言うところの「ボーン」。「アニメーションメッシュ」とは、アニメーション情報を持つメッシュデータのことで、頂点1つにつき複数のフレームの影響を受けるアニメーションに対応するのが「スキンアニメーションメッシュ」。
アニメーションデータを持つXファイルを読み込む関数は、D3DXLoadMeshHierarchyFromX で、一見すると D3DXLoadMeshFromX とあまり変わらないので、何が難しいのか?どこが面倒なのか?と思うかもしれないが、この引数のうち、4個目の引数が問題なのだ。
この引数は、次のように指定されている。

pAlloc
  [in] ID3DXAllocateHierarchy インターフェイスへのポインタ。 

この ID3DXAllocateHierarchy インターフェイス がなんと仮想メソッドを持つクラスで、自前で ID3DXAllocateHierarchy を継承したクラスを作り、その内部を実装しないといけないのだ。
この部分をアプリケーションプログラマが実装しなければいけない理由は一応あって、アプリケーションプログラマがフレーム情報やメッシュ情報を拡張できるようになっている、ということである。
(しかし、普通そのあたりの情報なんて、基本部分を押さえてくれれば、外部から情報を取得するインターフェイスさえあれば特に問題ないのでは?と思ったりもするのだが。。)
DirectX SDKを見ると、とてもやさしく、SkinnedMesh/skinnedmesh.cpp で定義してあるではありませんか。

class CAllocateHierarchy: public ID3DXAllocateHierarchy

また、このサンプルは、フレーム情報の拡張のサンプルでもあって、D3DXFRAME と、D3DXMESHCONTAINER も継承して拡張しています。
って、もっと簡単でシンプルなサンプルを見たいのになぁー、と思う気持ちはきっと、天才集団の中にいたら分からなくなってしまうのですね。それらを全部コピペして使うほどの勇気もない自分はなんだか納得いかない気持ちになってしまいます。

ネットでサンプルを探す

「悩んだときのgoogle」ということで、googleで探してみたら、http://www.h6.dion.ne.jp/~game296o/DXG_No25_LoadAnimationFromXFile.htmlというページが結構詳細に説明してくれています。これはすばらしい。
このページを基準にして、難しいんだと腹をくくってから、いろんなページも読みはじめると大体の内容が分かってきます。
1-Xファイルの読み込み - MyProgrammingNote Wiki*
2007-04-11
http://home7.highway.ne.jp/nomura_y/prog004.htm
http://www.interq.or.jp/aquarius/ikeda3dr/game/html/skinnedmesh.htm

本屋でサンプルを探す

ネットの情報でもいいのだけど、できれば物理的に助けてほしい、という場合は、この本。

CD-ROMに入っているソースがとても役に立ちます。

こんな感じで

そうやっていろいろ見ていたら、なんとなく分かってきて、なんとなく描画されました。ただ、アニメーションをさせるのはもう一歩先の話らしいけど・・・。