Microsoft DirectX 8.0 (C++) |
D3DXMatrixLookAtLH および D3DXMatrixLookAtRH ヘルパー関数は、カメラ位置座標および注視点に基づいてビュー行列を作成する。これらの関数は、D3DXVec3Cross、D3DXVec3Dot、D3DXVec3Normalize、および D3DXVec3Subtract ヘルパー関数を使用する。
次のコードは、D3DXMatrixLookAtLH 関数を示している。
D3DXMATRIX* WINAPI D3DXMatrixLookAtLH ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt, const D3DXVECTOR3 *pUp ) { #if DBG if(!pOut || !pEye || !pAt || !pUp) return NULL; #endif D3DXVECTOR3 XAxis, YAxis, ZAxis; // 奥行きを示す z 軸ベクトルを取得する。 // 視点から注視点までの差である。これは // 注視する方向 (+z) である。 D3DXVec3Subtract(&ZAxis, pAt, pEye); // z 軸ベクトルを正規化する。 D3DXVec3Normalize(&ZAxis, &ZAxis); // 注視する方向と pUp ベクトルの外積から // 直交軸を計算する。 D3DXVec3Cross(&XAxis, pUp, &ZAxis); D3DXVec3Normalize(&XAxis, &XAxis); D3DXVec3Cross(&YAxis, &ZAxis, &XAxis); // 行列の構築を開始する。最初の 3 つの行には、 // ビューを回転して注視点に向けるためのベクトルが含まれる。 // point.// 4 番目の行には平行移動の値が含まれる。 // 視点を中心とした回転が行われる。 pOut->_11 = XAxis.x; pOut->_21 = XAxis.y; pOut->_31 = XAxis.z; pOut->_41 = -D3DXVec3Dot(&XAxis, pEye); pOut->_12 = YAxis.x; pOut->_22 = YAxis.y; pOut->_32 = YAxis.z; pOut->_42 = -D3DXVec3Dot(&YAxis, pEye); pOut->_13 = ZAxis.x; pOut->_23 = ZAxis.y; pOut->_33 = ZAxis.z; pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye); pOut->_14 = 0.0f; pOut->_24 = 0.0f; pOut->_34 = 0.0f; pOut->_44 = 1.0f; return pOut; }
ワールド トランスフォームの場合と同様、IDirect3DDevice8::SetTransform メソッドを呼び出してビュー トランスフォームを設定し、第 1 パラメータに D3DTS_VIEW フラグを指定する。詳細については、「トランスフォームの設定」を参照すること。
パフォーマンスの最適化に関する注 Microsoft® Direct3D® では、設定されたワールド行列およびビュー行列を使用して、いくつかの内部データ構造を構築する。新しいワールド行列またはビュー行列を設定するたびに、関係する内部構造が再計算される。これらの行列をフレームごとに 20,000 回も設定するなど頻繁に設定すると、多大な計算負荷が発生する。必要な計算を最小限に抑えるには、ワールド行列として設定するワールドビュー行列にワールド行列およびビュー行列を連結した後、ビュー行列を単位行列に設定する。ワールド行列およびビュー行列の各キャッシュ コピーは保持しておくこと。必要に応じてワールド行列を修正、連結、およびリセットできる。Direct3D のサンプルでは、簡潔であることを優先して、この最適化はほとんど用いていない。