World Transform (Direct3D 9)
ワールド変換の説明では、基本的な概念を紹介し、ワールド変換を設定する方法の詳細を示します。
ワールド変換とは
ワールド変換は、モデルのローカル原点に対して頂点が定義されるモデル空間から、シーン内のすべてのオブジェクトに共通する原点に対して頂点が定義されるワールド空間に座標を変更します。 基本的に、ワールド変換はモデルをワールド空間に配置します。そのため、このように呼ばれます。 次の図は、ワールド座標系とモデルのローカル座標系の関係を示しています。
ワールド変換には、平行移動、回転、スケーリングを任意に組み合わせて含めることができます。
ワールド行列の設定
ワールド変換を作成するには、他の変換と同様に、複数の行列を組み合わせて、それらの効果をすべて含む 1 つの行列に連結します。 最も単純な例として、モデルがワールド原点に位置し、そのローカル座標軸がワールド空間と同じ方向であるとすると、ワールド行列は単位行列になります。 より一般的な例でのワールド行列は、ワールド空間への平行移動と、必要に応じてモデルを回転させる 1 つ以上の回転の組み合わせになります。
次の例では、C++ で記述された架空の 3D モデル クラスから、D3DX ユーティリティ ライブラリに含まれるヘルパー関数を使用して、モデルの向きを示す 3 つの回転と、ワールド空間内の位置を基準にして再配置する変換を含むワールド マトリックスを作成します。
/*
* For the purposes of this example, the following variables
* are assumed to be valid and initialized.
*
* The m_xPos, m_yPos, m_zPos variables contain the model's
* location in world coordinates.
*
* The m_fPitch, m_fYaw, and m_fRoll variables are floats that
* contain the model's orientation in terms of pitch, yaw, and roll
* angles, in radians.
*/
void C3DModel::MakeWorldMatrix( D3DXMATRIX* pMatWorld )
{
D3DXMATRIX MatTemp; // Temp matrix for rotations.
D3DXMATRIX MatRot; // Final rotation matrix, applied to
// pMatWorld.
// Using the left-to-right order of matrix concatenation,
// apply the translation to the object's world position
// before applying the rotations.
D3DXMatrixTranslation(pMatWorld, m_xPos, m_yPos, m_zPos);
D3DXMatrixIdentity(&MatRot);
// Now, apply the orientation variables to the world matrix
if(m_fPitch || m_fYaw || m_fRoll) {
// Produce and combine the rotation matrices.
D3DXMatrixRotationX(&MatTemp, m_fPitch); // Pitch
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
D3DXMatrixRotationY(&MatTemp, m_fYaw); // Yaw
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
D3DXMatrixRotationZ(&MatTemp, m_fRoll); // Roll
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
// Apply the rotation matrices to complete the world matrix.
D3DXMatrixMultiply(pMatWorld, &MatRot, pMatWorld);
}
}
ワールド マトリックスを準備したら、 IDirect3DDevice9::SetTransform メソッドを呼び出して設定し、最初のパラメーター にD3DTS_WORLD マクロを指定します。
注意
Direct3D は、ユーザーが設定したワールド行列とビュー行列を使って、いくつかの内部データ構造を構成します。 新しいワールド行列またはビュー行列を設定するたびに、関連付けられた内部構造がシステムによって再計算されます。 これらの行列を頻繁に、たとえばフレーム当たりに数千回という頻度で設定すると、計算に時間を要することになります。 必要な計算回数を最小限に抑えるには、ワールド行列とビュー行列を連結して 1 つのワールド ビュー行列を作成し、それをワールド行列として設定した後、ビュー行列を単位元に設定します。 このとき、必要に応じてワールド行列を変更、連結、リセットできるように、個々のワールド行列とビュー行列のキャッシュ コピーを保持しておくことをお勧めします。 わかりやすくするために、このドキュメントの Direct3D サンプルでは、この最適化を採用することはめったにありません。
関連トピック