12.2.2圍繞任意軸旋轉(zhuǎn)
為了實現(xiàn)我們的攝像機旋轉(zhuǎn)方法,我們需要能夠繞著任意軸旋轉(zhuǎn),D3DX庫提供下面的函數(shù)來解決這個問題:
Builds a matrix that rotates around an arbitrary axis.
D3DXMATRIX * D3DXMatrixRotationAxis( D3DXMATRIX * pOut, CONST D3DXVECTOR3 * pV, FLOAT Angle);
Parameters
- pOut
- [in, out] Pointer to the D3DXMATRIX structure that is the result of the operation.
- pV
- [in] Pointer to the arbitrary axis. See D3DXVECTOR3.
- Angle
- [in] Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
Return Values
Pointer to a D3DXMATRIX structure rotated around the specified axis.
Remarks
The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXMatrixRotationAxis function can be used as a parameter for another function.

例如,假如我們想繞向量(0.707, 0.707, 0)軸旋轉(zhuǎn)π/2角度。我們可以這樣寫:
D3DXMATRIX R;
D3DXVECTOR3 axis(0.707f, 0.707f, 0.0f);
D3DXMatrixRotationAxis(&R, &axis, D3DX_PI / 2.0f);
|
12.2.3Pitch、Yaw和Roll
因為方向向量描述了攝像機相對于世界坐標(biāo)系的方向,我們必須考慮在使用傾斜(pitch)、偏航(yaw)和滾轉(zhuǎn)(roll)時及時更新方向向量。這其實也是非常簡單的。圖12.4,12.5,12.6分別顯示了攝像機的傾斜、偏航和滾轉(zhuǎn)操作。

當(dāng)傾斜(pitch)時,我們需要將up和look向量繞著right向量旋轉(zhuǎn)一定角度。同樣的,當(dāng)偏航(yaw)時,我們需要將look和right向量繞著up向量旋轉(zhuǎn)一定角度。最后,當(dāng)滾轉(zhuǎn)(roll)時,我們需要將up和right向量繞著look向量旋轉(zhuǎn)一定角度。
我們現(xiàn)在明白了為什么D3DXMatrixRotationAxis函數(shù)是非常必要的,因為這三個向量中的任何一個都可能圍繞世界坐標(biāo)系中的任意軸旋轉(zhuǎn)。
對于傾斜(pitch)、偏航(yaw)和滾轉(zhuǎn)(roll)的執(zhí)行我們已經(jīng)討論了。然而,對于LAND_OBJECT模式就有一些限制。我們在偏航(yaw)方法中只圍繞y軸旋轉(zhuǎn),我們完全屏蔽滾轉(zhuǎn)(roll)。當(dāng)然你可以根據(jù)你的程序需要來改變Camera類。我們這里只是一個示例而已。
傾斜(pitch)、偏航(yaw)和滾轉(zhuǎn)(roll)方法代碼的具體實現(xiàn)如下:
void cCamera::pitch(float angle)
{
D3DXMATRIX transform_matrix;
D3DXMatrixRotationAxis(&transform_matrix, &m_right, angle);
// rotate m_up and m_look around m_right vector
D3DXVec3TransformCoord(&m_up, &m_up, &transform_matrix);
D3DXVec3TransformCoord(&m_look, &m_look, &transform_matrix);
}
void cCamera::yaw(float angle)
{
D3DXMATRIX transform_matrix;
// rotate around world y-axis (0, 1, 0) always for land object
if(m_camera_type == LAND_OBJECT)
D3DXMatrixRotationY(&transform_matrix, angle);
else // rotate around own up vector for aircraft
D3DXMatrixRotationAxis(&transform_matrix, &m_up, angle);
// rotate m_right and m_look around m_up or y-axis
D3DXVec3TransformCoord(&m_right, &m_right, &transform_matrix);
D3DXVec3TransformCoord(&m_look, &m_look, &transform_matrix);
}
void cCamera::roll(float angle)
{
// only roll for aircraft type
if(m_camera_type == AIR_CRAFT)
{
D3DXMATRIX transform_matrix;
D3DXMatrixRotationAxis(&transform_matrix, &m_look, angle);
// rotate m_up and m_right around m_look vector
D3DXVec3TransformCoord(&m_up, &m_up, &transform_matrix);
D3DXVec3TransformCoord(&m_right, &m_right, &transform_matrix);
}
}
12.2.4Walking、Strafing和Flying
當(dāng)提到walking時,我們的意思是在我們觀察的方向上移動位置(也就是說,沿著look向量)。Strafing是說在我們觀察方向的左右移動,也就是沿著right向量移動。最后,我們說flying就是沿著up向量移動。為了沿著這些軸移動,我們只需要簡單地加一個向量就可以了(如圖12.7)。

就象旋轉(zhuǎn)一樣,我們需要對移動作一些限制。例如,LAND_OBJECT不允許飛起來。因此我們把移動限制在xz平面。然而,因為LAND_OBJECT能夠允許爬樓梯和登山,所以,我們設(shè)置cCamera::set_position方法,它允許你手動設(shè)置你的攝像機位置來達(dá)到你的高度和位置。
移動(walk)、平移(strafe)和飛行(fly)方法代碼的具體實現(xiàn)如下:
void cCamera::walk(float units)
{
// move only on xz plane for land object
if(m_camera_type == LAND_OBJECT)
m_pos += D3DXVECTOR3(m_look.x, 0.0f, m_look.z) * units;
else // AIR_CRAFT
m_pos += m_look * units;
}
void cCamera::strafe(float units)
{
// move only on xz plane for land object
if(m_camera_type == LAND_OBJECT)
m_pos += D3DXVECTOR3(m_right.x, 0.0f, m_right.z) * units;
else // AIR_CRAFT
m_pos += m_right * units;
}
void cCamera::fly(float units)
{
// move only on y_axis for land object
if(m_camera_type == LAND_OBJECT)
m_pos.y += units;
else
m_pos += m_up * units;
}