Microsoft DirectX 8.0 (C++)

ビュー行列の設定

D3DXMatrixLookAtLH および D3DXMatrixLookAtRH ヘルパー関数は、カメラ位置座標および注視点に基づいてビュー行列を作成する。これらの関数は、D3DXVec3CrossD3DXVec3DotD3DXVec3Normalize、および 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 のサンプルでは、簡潔であることを優先して、この最適化はほとんど用いていない。