マトリックス スタック (Direct3D 9)

注意

D3DX ユーティリティ ライブラリは非推奨です。 代わりに、GitHub のこのヘッダーと共に DirectXMath を使用することをお勧めします。

D3DX ユーティリティ ライブラリには 、ID3DXMATRIXStack インターフェイスが用意されています。 マトリックスをマトリックス スタックにプッシュしてポップオフできるようにするメカニズムを提供します。 行列スタックの実装は、変換階層を走査しながら行列を追跡する効率的な方法です。

D3DX ユーティリティ ライブラリでは、行列スタックを使用して変換をマトリックスとして格納します。 ID3DXMATRIXStack インターフェイスのさまざまなメソッドは、現在の行列、またはスタックの上にある行列を扱います。 ID3DXMATRIXStack::LoadIdentity メソッドを使用して、現在の行列をクリアできます。 現在の変換行列として読み込む特定の行列を明示的に指定するには、 ID3DXMATRIXStack::LoadMatrix メソッドを 使用します。 次に、 ID3DXMATRIXStack::MultMatrix メソッドまたは ID3DXMATRIXStack::MultMatrixLocal メソッドを呼び出して、現在の行列に指定した行列を乗算できます。

ID3DXMATRIXStack::P op メソッドを使用すると、前の変換行列に戻り、ID3DXMATRIXStack::P ush メソッドによって変換行列がスタックに追加されます。

行列スタック上の個々の行列は、D3DX ユーティリティ ライブラリ D3DXMATRIX 構造体によって定義される 4 x 4 の同種行列として表されます。

D3DX ユーティリティ ライブラリは、コンポーネント オブジェクト モデル (COM) オブジェクトを介してマトリックス スタックを提供します。

シーン階層の実装

マトリックス スタックを使用すると、一連の単純なオブジェクトから複雑なオブジェクトが構築される階層モデルの構築が簡略化されます。

通常、シーン (変換) 階層はツリー データ構造で表されます。 ツリー データ構造内の各ノードには、マトリックスが含まれています。 特定の行列は、ノードの親からノードへの座標系の変更を表します。 たとえば、人間の腕をモデル化する場合は、次の図に示す階層を実装できます。

人間の腕の階層の図

この階層では、本文マトリックスによって、本文がワールドに配置されます。 UpperArm 行列には肩の回転が含まれており、LowerArm マトリックスにはエルボの回転が含まれており、Hand マトリックスには手首の回転が含まれます。 手が世界に対して相対的な位置を決定するには、Body から Hand までのすべての行列を一緒に乗算します。

各ノードには子が 1 つしかないため、前の階層は過度に単純です。 手をより詳細にモデル化し始めると、おそらく指と親指が追加されます。 次の図に示すように、各桁を Hand の子として階層に追加できます。

人間の手の階層の図

アームの完全なグラフを深さ優先の順序で走査し、次のパスに進む前にできるだけ 1 つのパスを走査してシーンを描画する場合は、セグメント化されたレンダリングのシーケンスを実行します。 たとえば、手と指をレンダリングするには、次のパターンを実装します。

  1. ハンド マトリックスをマトリックス スタックにプッシュします。
  2. 手を描きます。
  3. Thumb マトリックスをマトリックス スタックにプッシュします。
  4. サムを描画します。
  5. Thumb マトリックスをスタックからポップします。
  6. フィンガー 1 マトリックスをマトリックス スタックにプッシュします。
  7. 最初の指を描画します。
  8. スタックから指 1 行列をポップします。
  9. フィンガー 2 マトリックスをマトリックス スタックにプッシュします。 すべての指と親指がレンダリングされるまで、この方法で続行します。

指のレンダリングが完了したら、ハンド マトリックスをスタックからポップします。

次の例を使用して、コード内のこの基本的なプロセスに従うことができます。 ツリー データ構造の深さ優先検索中にノードが発生した場合は、マトリックスをマトリックス スタックの上部にプッシュします。

MatrixStack->Push();

MatrixStack->MultMatrix(pNode->matrix);

ノードの使用が完了したら、行列スタックの上部から行列をポップします。

MatrixStack->Pop();

このようにして、スタックの上部にある行列は常に現在のノードのワールド変換を表します。 したがって、各ノードを描画する前に、Direct3D マトリックスを設定する必要があります。

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

D3DX マトリックス スタックで実行できる特定のメソッドの詳細については、 ID3DXMATRIXStack リファレンス トピックを参照してください。

頂点パイプライン