struts Object{D3DMATRIX matLocal;}
D3DXVec3Normalize(&vLook,&vLook);D3DXVec3Cross(&vRight,&vUp,&vLook);D3DXVec3Normalize(&vRight,&vRight);D3DXVec3Cross(&vUp,&vLook,&vRight);D3DXVec3Normalize(&vUp,&vUp);
m_pObjects[0].matLocal._11 = vRight.x;m_pObjects[0].matLocal._12 = vRight.y;m_pObjects[0].matLocal._13 = vRight.z;m_pObjects[0].matLocal._21 = vUp.x;m_pObjects[0].matLocal._22 = vUp.y;m_pObjects[0].matLocal._23 = vUp.z;m_pObjects[0].matLocal._31 = vLook.x;m_pObjects[0].matLocal._32 = vLook.y;m_pObjects[0].matLocal._33 = vLook.z;m_pObjects[0].matLocal._41 = vPos.x;m_pObjects[0].matLocal._42 = vPos.y;m_pObjects[0].matLocal._43 = vPos.z;
- 确定旋转角度和旋转轴。
- 取出当前的vRight,vLook,vUp,vPos向量;
- 对三个向量进行归一化;
- 利用D3DMatrixRotationAxis(D3DXMatrix* mat,D3DXVector* vAxis,FLOAT fRad)产生旋转矩阵;
- 利用D3DXVectorTransformCoord(D3DXVector* vNew,D3DXVector* vOld,D3DXMatrix* mat)对当前的vRight,vLook,vUp向量进行变换,得到新的vRight,vLook,vUp向量。
- 移动位置,获得新的vPos;
- 将新的vRight,vLook,vUp,vPos向量设置到matLocal中。
----------------------------
上边的表示方法我们看到要7个过程,这略微有些复杂,那么下面我们来看另外一种简洁的计算方法-四元数(Quaternion)。
我们先对比一下实现的差别,然后再具体解释API的含义。
- 确定旋转角度和旋转轴。
- 利用D3DXQuaternionRotationYawPitchRoll(D3DXMatrix* mat,Float fYaw,FLOAT fPitch,FLOAT fRoll)的到变换矩阵。
- 把上述得到的矩阵同matLocal相乘得到新的matLocal;
- 做位置的变换。
四元数的原理有点复杂,由于速成关系我也没有怎么看,只是知道可以简单想象成一个向量加上一次旋转,具体的运算推导有机会再研究吧。但这个东西用途的确很广泛,因此被作为一种专门的方法被D3D介绍。
上边只用到了一个API,那就是D3DXQuaternionRotationYawPitchRoll(D3DXMatrix* mat,Float fYaw,FLOAT fPitch,FLOAT fRoll),给定绕三个轴的旋转角度,返回一个变换矩阵。
-----------------------------
下边看一下观察变换,观察矩阵同物体定位矩阵唯一不同的就是其存储方式,它采取列向量的存储方式。相机的各种变换同物体的变换没有任何不同,最后也是得到一个矩阵,只是D3D提供了一个根据视点位置,相机朝向和向上方向构造矩阵的函数:D3DXMatrixLookAtLH(D3DXMatrix* mat,D3DXVECTOR3* pEye,D3DXVECTOR3* pAt,D3DXVECTOR3* pUp),省着自己算了。最后用m_pd3Device->SetTransform(D3DTS_VIEW,&mat)设置一下就可以了。
这里需要注意的是D3DXMatrixLookAtLH()只适合于简单的头罩式显示或者视点跟随,对于具有复杂旋转的飞行模拟器这类相机最好还是自己来算。计算的方式同前边介绍的物体变换的方式一样,也有两种方式,一种是复杂的7步变换,一种是简单的四元数变换。最后将得到的向量按照列向量的形式赋给视矩阵,再利用SetTransform()设置一下就好了。这实际上是一种自己维护相机的方式。
------------------------------
下面看一下投影变换。提到投影就会想到视锥,就会有视域角(FOV-field of view)、宽高比(aspect)和远近裁减面这四个参数。在D3D里边可以利用D3DXMatrixPerspectiveFoVLH(D3DXMATRIX* pOut,FLOAT fovY,FLOAT Aspect,FLOAT zn,FLOAT zf),通过给定的四个参数获得投影矩阵,然后用m_pd3Device->SetTranform(D3DTS_PROJECTION,&pOut)来设置投影矩阵即可。