Microsoft DirectX 8.0 (C++)

シーンの階層の実装

一連の単純なオブジェクトから複雑なオブジェクトが構築される階層モデルは、行列スタックを使用することで簡単に構築できるようになる。

シーンやトランスフォームでは、階層は通常ツリー データ構造として表現される。ツリー データ構造内の各ノードには行列が含まれる。特定の行列は、ノードの親からノードへの座標系の変化を表す。たとえば、人間の腕をモデリングしている場合、次のような階層を実装する場合がある。

この階層では、Body 行列が胴体をワールド内に配置する。UpperArm 行列には肩の回転、LowerArm 行列にはひじの回転、Hand 行列には手首の回転がそれぞれ含まれる。手がどこでワールドと関連するかを決定するには、Body から Hand までの行列をすべて乗算する。

前の階層は、各ノードに子が 1 つずつしかなかったので、非常に単純であった。より詳細に手をモデリングする場合は、指を追加することになる。5 本の指はすべて、Hand の子として階層に追加できる。

腕の完全なグラフ内を深度優先の順序 (単一のパスをできるだけ深く移動してから次のパスに移る) で移動する場合は、分断された一連のレンダリングを実行することになる。たとえば、手と指をレンダリングする場合は、次の手順を実行する。

  1. Hand 行列を行列スタックにプッシュする。
  2. 手を描画する。
  3. Thumb 行列を行列スタックにプッシュする。
  4. 親指を描画する。
  5. Thumb 行列をスタックからポップ オフする。
  6. Finger 1 行列を行列スタックにプッシュする。
  7. 最初の指を描画する。
  8. Finger 1 行列をスタックからポップ オフする。
  9. Finger 2 行列を行列スタックにプッシュする。すべての指がレンダリングされるまで、この手順を繰り返す。

指のレンダリングが終わったら、Hand 行列をスタックからポップ オフする。

次の例を使って、この基本的なプロセスをコード内で実行できる。ツリー データ構造の深度優先検索中にノードが見つかったら、行列を行列スタックの最上部にプッシュする。

MatrixStack->Push();
MatrixStack->MultMatrix(pNode->matrix);

ノードの操作が終了したら、行列を行列スタックの最上部からポップ オフする。

MatrixStack->Pop();

つまり、スタックの最上部にある行列は、常に現在のノードのワールド トランスフォームを表す。このため、各ノードの描画前に、Microsoft® Direct3D® 行列を設定する必要がある。

pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(0), *MatrixStack->GetTop());

Direct3DX 行列スタックで実行できる各種メソッドに関する詳細は、「ID3DXMatrixStack」を参照すること。