Microsoft DirectX 8.0 (C++) |
ほかのすべてのトランスフォームと同様、一連のトランスフォーム行列を、個々の効果をすべて含む単一の行列に連結することでワールド トランスフォームを作成する。簡単な例では、あるモデルがワールド原点にあり、そのローカル座標軸がワールド空間と同じ方向に定義されている場合、ワールド行列は単位行列である。さらに一般的には、ワールド行列はワールド空間への平行移動を組み合わせたものであり、必要に応じてモデルを 1 回または何度も回転することができる。
次の例は、C++ で記述された架空の 3D モデル クラスに関するものである。ここでは、Direct3DX ユーティリティ ライブラリに含まれるヘルパー関数を使用して、モデルを方向付ける回転を 3 回行い、さらにワールド空間での位置座標を基準にそのモデルを再配置する平行移動を行うワールド行列を作成する。
/* * この例では、次の変数は * 有効であり、初期化されていると仮定する。 * * 変数 m_xPos、m_yPos、m_zPos はモデルの * ワールド座標での位置を格納する。 * * 変数 m_fPitch、m_fYaw、および m_fRoll は浮動小数点数で、 * ピッチ、ヨー、およびロール (ラジアン単位) での * モデルの向きを格納する。 */ void C3DModel::MakeWorldMatrix( D3DXMATRIX* pMatWorld ) { D3DXMATRIX MatTemp; // 回転用の Temp 行列。 D3DXMATRIX MatRot; // 最終的な回転行列。 // pMatWorld に適用される。 // 左から右に行列を連結して、 // オブジェクトのワールド位置座標に平行移動を適用した後、 // 回転を適用する。 D3DXMatrixTranslation(pMatWorld, m_xPos, m_yPos, m_zPos); D3DXMatrixIdentity(&MatRot); // ここで、ワールド行列に向き変数を適用する。 if(m_fPitch || m_fYaw || m_fRoll) { // 回転行列を作成し、組み合わせる。 D3DXMatrixRotationX(&MatTemp, m_fPitch); // ピッチ。 D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp); D3DXMatrixRotationY(&MatTemp, m_fYaw); // ヨー。 D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp); D3DXMatrixRotationZ(&MatTemp, m_fRoll); // ロール。 D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp); // 回転行列を適用し、ワールド行列を完成する。 D3DXMatrixMultiply(pMatWorld, &MatRot, pMatWorld); } }
ワールド トランスフォーム行列が準備できたら、この行列を設定するために IDirect3DDevice8::SetTransform メソッドを呼び出して、第 1 パラメータに D3DTS_WORLD マクロを指定する。詳細については、「トランスフォームの設定」を参照すること。
注 Microsoft® Direct3D® では、設定されたワールド行列およびビュー行列を使用して、いくつかの内部データ構造を構築する。新しいワールド行列またはビュー行列を設定するたびに、関係する内部構造が再計算される。これらの行列をフレームごとに数千回も設定するなど頻繁に設定すると、多大な計算負荷が発生する。必要な計算を最小限に抑えるには、ワールド行列として設定するワールドビュー行列にワールド行列およびビュー行列を連結した後、ビュー行列を単位行列に設定する。必要に応じてワールド行列を修正、連結、およびリセットできるように、ワールド行列およびビュー行列の各キャッシュ コピーは保持しておくこと。このドキュメントの Direct3D のサンプルでは、簡潔であることを優先して、この最適化はほとんど用いていない。