ワールド トランスフォーム

ワールド トランスフォーム

ここでは、ワールド トランスフォームについての基本的な概念を紹介し、Microsoft® Direct3D® アプリケーションでワールド トランスフォーム行列を設定する方法について詳しく説明する。

ワールド トランスフォームとは

ワールド トランスフォームでは、頂点がモデルのローカル原点に対して定義されたモデル空間から、頂点がシーン内のすべてのオブジェクトに共通する原点に対して定義されたワールド空間に座標をトランスフォームする。基本的には、ワールド トランスフォームによってモデルがワールドに配置されることから、このような名前が付いている。次の図は、ワールド座標系とモデルのローカル座標系の関係を示している。

ワールド座標

ワールド トランスフォームでは、平行移動、回転、およびスケーリングをどのように組み合わせても使える。トランスフォームの数学上の説明については、「3D トランスフォーム」を参照すること。

ワールド行列の設定

他のすべてのトランスフォームと同様、一連のトランスフォーム行列を、個々の効果をすべて含む単一の行列に連結することでワールド トランスフォームを作成する。簡単な例では、あるモデルがワールド原点にあり、そのローカル座標軸がワールド空間と同じ方向に定義されている場合、ワールド行列は単位行列である。一般的なワールド行列は、ワールド空間への平行移動に、必要に応じてモデルの回転をいくつか組み合わせたものである。

次の例は、C++ で記述された架空の 3D モデル クラスに関するものである。ここでは、Direct3D エクステンション (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 メソッドを呼び出して、第 1 引数に D3DTS_WORLD マクロを指定する。

  Direct3D では、設定されたワールド行列およびビュー行列を使って、いくつかの内部データ構造を構築する。新しいワールド行列またはビュー行列を設定するたびに、関係する内部構造が再計算される。これらの行列を、フレームごとに何千回も設定するなど、頻繁に設定すると、計算に非常に時間がかかる。必要な計算を最小限に抑えるには、ワールド行列とビュー行列を連結してワールドビュー行列を作成し、それをワールド行列として設定した後で、ビュー行列を単位行列に設定する。必要に応じてワールド行列を修正、連結、およびリセットできるように、ワールド行列およびビュー行列の各キャッシュ コピーは保持しておくこと。このドキュメントの Direct3D のサンプルでは、簡潔さを優先して、この最適化はほとんど用いていない。