Platform SDK: DirectX

ステップ 2.2 : ビュー行列を作成および設定する

[Visual Basic]

ここでは、C および C++ でのアプリケーション開発について説明する。Visual Basic については、「Direct3D 直接モード Visual Basic チュートリアル」を参照すること。

[C++]

視点、注視点、上方向ベクトルを指定すると、アプリケーションに手動で 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 トランスフォームを実行する」で説明する。