第一人称视角变换主要是view transformation matrix的变换。其实就是不断变动eye point和camera look-at target的坐标。具备基本的三维数学和矩阵运算技巧就可以了。
要弄清视角移动和转动的原理,有必要先看看DX文档的Matrices和View Transformation章节。文档的相关3D数学原理和距阵计算以及接口方法搞清楚了。下面的工作就相当简单。
首先定义D3DXVECTOR3 VDot,VAtPoint,VUp;
视景的移动
前后移动和左右移动
其实就是同时移动VDot和VAtPoint,即同时移动眼睛的位置和眼睛所看到的点的位置。代码比较简单。udragon在他的主页上有一段代码很清楚。可以参考:http:/www.udragon.net/ZHZX/3d-5.htm
视角的转动
原理就是绕通过VDot的矢量VUp旋转VDot。即相当于站在原地旋转Camera。udragon在他的主页上关于视角旋转的代码写得思路比较晦涩难懂,主要是他的思路比较特殊,几乎在程序里把某点绕轴旋转的公式按数学证明推导了一遍。其实如果数学运算得当以及合理运用D3D接口方法,这段代码可以简化许多:
可能用到的变量
D3DXVECTOR3 pOut;
D3DXVECTOR3 pOut2;
D3DXVECTOR3 ab;
D3DXVECTOR3 ac;
D3DXVECTOR4 Vtemp;
D3DXMATRIX R,RT,R2;
//左右移动
D3DXVec3Normalize(&pOut,&ac);
`
RT = D3DXMATRIX(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
-VDot.x, -VDot.y, -VDot.z, 1);
D3DXMatrixRotationAxis( &R2, &pOut, u);
R = RT * R2;
RT = D3DXMATRIX(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
VDot.x, VDot.y, VDot.z, 1);
R = R * RT;
D3DXVec3Transform(&Vtemp, &VAtPoint, &R);
VAtPoint.x = Vtemp.x;
VAtPoint.y = Vtemp.y;
VAtPoint.z = Vtemp.z;
//上下移动
s1 = D3DXVec3Length(&ab)*D3DXVec3Length(&VUp);
s2 = (float)acos(D3DXVec3Dot(&ab, &VUp)/s1);
if(u0)
{
if(s2
break;
}//一度
else
if(s2=3.124)
break;
D3DXVec3Cross(&pOut,&ab,&ac);
D3DXVec3Normalize(&pOut2,&pOut);
RT = D3DXMATRIX(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
-VDot.x, -VDot.y, -VDot.z, 1);
D3DXMatrixRotationAxis( &R2, &pOut2, u);
R = RT * R2;
RT = D3DXMATRIX(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
VDot.x, VDot.y, VDot.z, 1);
R = R * RT;
D3DXVec3Transform(&Vtemp, &VAtPoint, &R);
VAtPoint.x = Vtemp.x;
VAtPoint.y = Vtemp.y;
VAtPoint.z = Vtemp.z;