Platform SDK: DirectX |
ここでは、C および C++ でのアプリケーション開発について説明する。Visual Basic については、「Direct3D 直接モード Visual Basic チュートリアル」を参照すること。
視点、注視点、上方向ベクトルを指定すると、アプリケーションに手動で 4×4 ビュー行列を作成できる。まず、奥行きを示す z 軸ベクトルを取得する。
HRESULT SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, D3DVECTOR& vAt, D3DVECTOR& vWorldUp ) { // 奥行きを示す z 軸ベクトルを取得する。これは注視点に対する // 視点とは異なる。 D3DVECTOR vView = vAt - vFrom;
z 軸ベクトルは、注視点に対する視点とは異なる。z 軸ベクトルは、計算に使用する前に正規化する必要がある。
FLOAT fLength = Magnitude( vView ); if( fLength < 1e-6f ) return E_INVALIDARG; // z 軸ベクトルを正規化する。 vView /= fLength;
上記のコードでは、ビュー ベクトルの絶対値を返す Magnitude 関数を使用している。Magnitude 関数は、プロジェクトで D3D_OVERLOADS を定義するプログラマが使用する。D3D_OVERLOADS の C++ 拡張機能によって提供される。ヘルパー関数の詳細については、「D3D_OVERLOADS ヘルパー関数」を参照すること。
この時点で、内積を取得して z 軸ベクトルにおける上方向ベクトルへの射影を計算できる。最終的にこの射影は y 軸ベクトルになる。
FLOAT fDotProduct = DotProduct( vWorldUp, vView ); D3DVECTOR vUp = vWorldUp - fDotProduct * vView;
注 : DotProduct は D3D_OVERLOADS に定義される関数である。
次のコードは、y 軸ベクトルを正規化する。
vUp /= fLength;
x 軸ベクトルを検出するには、y 軸および z 軸ベクトルの外積を求める。
D3DVECTOR vRight = CrossProduct( vUp, vView );
注 : CrossProduct は D3D_OVERLOADS に定義される関数である。
この時点で、新しいビュー行列の作成を開始するための情報が揃っている。次のコードでは、最初の 3 つの行に、注視点を指すビューを回転させるための基底ベクトルを含める。
mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x; mat._14 = 0.0f; mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y; mat._24 = 0.0f; mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z; mat._34 = 0.0f;
次に平行移動値を設定する。ただし、視点の周りで回転することに注意する。
mat._41 = - DotProduct( vFrom, vRight ); mat._42 = - DotProduct( vFrom, vUp ); mat._43 = - DotProduct( vFrom, vView ); mat._44 = 1.0f;
平行移動値を設定すると、制御がアプリケーション定義関数 App_FrameMove の呼び出しに戻る。IDirect3DDevice7::SetTransform メソッドを呼び出して、新しいビュー行列を有効にする。
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );
立方体の頂点はプログラマ定義関数 TransformVertices によってトランスフォームされる。これについては、「ステップ 2.3 : 3D トランスフォームを実行する」で説明する。