第10讲摄像机漫游_第1页
第10讲摄像机漫游_第2页
第10讲摄像机漫游_第3页
第10讲摄像机漫游_第4页
第10讲摄像机漫游_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、摄像机漫游设置观察矩阵代码:/建立并设置观察矩阵D3DXVECTOR3 vEyePt( 0.0f,0.0f,-15.0f );D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );D3DXMATRIX matView;D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );g_pd3dDevice-SetTransform( D3DTS_VIEW, &matView );观察变换-摄像机属性通常用四个分量来确定一个摄像机相

2、对于世界坐标系的位置和朝向:左分量、上分量、观察分量和位置分量。在世界坐标系中,这几个分量都通过向量表示,并且实际上它们为摄像机定义了一个局部坐标系,需要将世界坐标系中的物体随着摄像机一起进行变换,以便让摄像机的坐标系与世界坐标系完全重合摄像机变换 1沿各分量平移由于摄像机包含向右、向上、观察三个分量,因此可以控制摄像机分别沿这三个分量进行平移。其中,沿右分量的平移称作扫视,沿上分量的平移称作升降,而沿观察分量的平移称作平动,如图所示 2绕各分量旋转摄像机的另一种变换是分别绕上分量、右分量和观察分量进行旋转。其中,绕上分量的旋转称作偏航,绕右分量的旋转称作俯仰,而绕观察分量的旋转称作滚动,如图

3、所示 3绕观察点旋转摄像机的平移和旋转已经能够满足简单的应用,但是有时候还需要将观察点固定,并控制摄像机围绕该点做圆周运动,以便能够从不同角度观察同一物体。因此,还需要让摄像机绕某个点进行旋转,如图所示以摄像机在y方向上绕点l=(lx,ly,lz)旋转为例,假设当前摄像机位于p点(观察点l与p点同在y平面内),那么当摄像机按逆时针方向旋转a 角度后应该位于p点,如图所示。/摄像机绕Y轴旋转fAngle角度VOID CCamera:CircleRotationY(FLOAT fAngle) D3DXMATRIX R; D3DXMatrixRotationAxis(&R, &m_vUpVec, f

4、Angle); D3DXVec3TransformCoord(&m_vRightVec, &m_vRightVec, &R); D3DXVec3TransformCoord(&m_vLookVec, &m_vLookVec, &R); float dx = m_vPosition.x - m_vLookat.x; float dz = m_vPosition.z - m_vLookat.z; m_vPosition.x = m_vLookat.x + dx * cosf(fAngle) - dz * sinf(fAngle); m_vPosition.z = m_vLookat.z + dx

5、* sinf(fAngle) + dz * cosf(fAngle); ResetLookatPos(&m_vLookat);根据上面介绍的内容,可以定义一个具有九个自由度的摄像机CCamera类,其中可以沿三个分量平移、绕三个分量旋转,以及在三个坐标方向上绕观察点旋转。4CCamera类定义#pragma once#include #include /-/ Name: class CCamera/ Desc: 虚拟摄像机平移、旋转/-class CCameraprivate: D3DXVECTOR3 m_vRightVec; / 摄像机右侧向量 D3DXVECTOR3 m_vUpVec; /

6、 摄像机上方向量 D3DXVECTOR3 m_vLookVec; /摄像机视线方向 D3DXVECTOR3 m_vPosition; / 摄像机当前位置 D3DXMATRIX m_matView; / 摄像机矩阵 D3DXMATRIX m_matProj; / 投影矩阵 D3DXVECTOR3 m_vLookat; /摄像机视线位置 LPDIRECT3DDEVICE9 m_pd3dDevice;public: CCamera(IDirect3DDevice9 *pd3dDevice); virtual CCamera(void);public: VOID GetViewMatrix(D3DXM

7、ATRIX *pMatrix);/获取摄像机矩阵 VOID GetProjMatrix(D3DXMATRIX *pMatrix) *pMatrix = m_matProj; VOID GetCameraPos(D3DXVECTOR3 *pVector) *pVector = m_vPosition; VOID GetLookVector(D3DXVECTOR3 *pVector) *pVector = m_vLookVec; VOID ResetLookatPos(D3DXVECTOR3 *pLookat = NULL);/设置视线位置 VOID ResetCameraPos(D3DXVECT

8、OR3 *pVector = NULL);/设置摄像机位置 VOID ResetViewMatrix(D3DXMATRIX *pMatrix = NULL);/设置摄像机(观察)矩阵 VOID ResetProjMatrix(D3DXMATRIX *pMatrix = NULL);/设置投影矩阵public: / 沿各分量平移 VOID MoveAlongRightVec(FLOAT fUnits); / 沿right向量移动 VOID MoveAlongUpVec(FLOAT fUnits); / 沿up向量移动 VOID MoveAlongLookVec(FLOAT fUnits); /

9、沿look向量移动 / 绕各分量旋转 VOID RotationRightVec(FLOAT fAngle); / 绕right向量选择 VOID RotationUpVec(FLOAT fAngle); / 绕up向量旋转 VOID RotationLookVec(FLOAT fAngle); / 绕look向量旋转 / 绕空间点旋转 VOID CircleRotationX(FLOAT fAngle); / 在X方向上绕观察点旋转 VOID CircleRotationY(FLOAT fAngle); / 在Y方向上绕观察点旋转 VOID CircleRotationZ(FLOAT fAn

10、gle); / 在Z方向上绕观察点旋转;5、摄像机类CCamera类的实现#include Camera.h#include CCamera:CCamera(IDirect3DDevice9 *pd3dDevice) m_pd3dDevice = pd3dDevice; m_vRightVec = D3DXVECTOR3(1.0f, 0.0f, 0.0f); / 默认右向量与X正半轴重合 m_vUpVec = D3DXVECTOR3(0.0f, 1.0f, 0.0f); / 默认上向量与Y正半轴重合 m_vLookVec = D3DXVECTOR3(0.0f, 0.0f, 1.0f); / 默

11、认观察向量与Z正半轴重合 m_vPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f); / 默认摄像机的位置为原点 m_vLookat = D3DXVECTOR3(0.0f, 0.0f, 0.0f); GetViewMatrix(&m_matView); / 取得取景变换矩阵 D3DXMatrixPerspectiveFovLH(&m_matProj, D3DX_PI / 4.0f, 1.0f, 1.0f, 2000.0f); / 投影变换矩阵CCamera:CCamera(void)VOID CCamera:GetViewMatrix(D3DXMATRIX *pM

12、atrix) / 使各分量相互垂直 D3DXVec3Normalize(&m_vLookVec, &m_vLookVec); D3DXVec3Cross(&m_vUpVec, &m_vLookVec, &m_vRightVec); / 上向量与观察向量垂直 D3DXVec3Normalize(&m_vUpVec, &m_vUpVec); / 规格化上向量 D3DXVec3Cross(&m_vRightVec, &m_vUpVec, &m_vLookVec); / 右向量与上向量垂直/你能通过左手法则确定叉积返回的向量。按照第一个向量指向第二个向量弯曲你的左手,/这时拇指所指的方向就是叉积向量所

13、指的方向。 D3DXVec3Normalize(&m_vRightVec, &m_vRightVec); / 规格化右向量 / 创建取景变换矩阵 pMatrix-_11 = m_vRightVec.x; / Rx pMatrix-_12 = m_vUpVec.x; / Ux pMatrix-_13 = m_vLookVec.x; / Lx pMatrix-_14 = 0.0f; pMatrix-_21 = m_vRightVec.y; / Ry pMatrix-_22 = m_vUpVec.y; / Uy pMatrix-_23 = m_vLookVec.y; / Ly pMatrix-_24

14、 = 0.0f; pMatrix-_31 = m_vRightVec.z; / Rz pMatrix-_32 = m_vUpVec.z; / Uz pMatrix-_33 = m_vLookVec.z; / Lz pMatrix-_34 = 0.0f; pMatrix-_41 = -D3DXVec3Dot(&m_vRightVec, &m_vPosition); / -P*R pMatrix-_42 = -D3DXVec3Dot(&m_vUpVec, &m_vPosition); / -P*U pMatrix-_43 = -D3DXVec3Dot(&m_vLookVec, &m_vPositi

15、on); / -P*L pMatrix-_44 = 1.0f;VOID CCamera:ResetLookatPos(D3DXVECTOR3 *pLookat) if (pLookat != NULL) m_vLookat = (*pLookat); else m_vLookat = D3DXVECTOR3(0.0f, 0.0f, 1.0f); m_vLookVec = m_vLookat - m_vPosition; D3DXVec3Normalize(&m_vLookVec, &m_vLookVec); D3DXVec3Cross(&m_vUpVec, &m_vLookVec, &m_vR

16、ightVec); D3DXVec3Normalize(&m_vUpVec, &m_vUpVec); D3DXVec3Cross(&m_vRightVec, &m_vUpVec, &m_vLookVec); D3DXVec3Normalize(&m_vRightVec, &m_vRightVec);VOID CCamera:ResetCameraPos(D3DXVECTOR3 *pVector) D3DXVECTOR3 V = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_vPosition = pVector ? (*pVector) : V;VOID CCamera:R

17、esetViewMatrix(D3DXMATRIX *pMatrix) if (pMatrix) m_matView = *pMatrix; else GetViewMatrix(&m_matView); m_pd3dDevice-SetTransform(D3DTS_VIEW, &m_matView); m_vRightVec = D3DXVECTOR3(m_matView._11, m_matView._12, m_matView._13); m_vUpVec = D3DXVECTOR3(m_matView._21, m_matView._22, m_matView._23); m_vLo

18、okVec = D3DXVECTOR3(m_matView._31, m_matView._32, m_matView._33);VOID CCamera:ResetProjMatrix(D3DXMATRIX *pMatrix) if (pMatrix != NULL) m_matProj = *pMatrix; else D3DXMatrixPerspectiveFovLH(&m_matProj, D3DX_PI / 4.0f, 1.0f, 1.0f, 1000.0f); m_pd3dDevice-SetTransform(D3DTS_PROJECTION, &m_matProj);/ 沿右

19、向量平移fUnits个单位VOID CCamera:MoveAlongRightVec(FLOAT fUnits) m_vPosition += m_vRightVec * fUnits; m_vLookat += m_vRightVec * fUnits;/ 沿上向量平移fUnits个单位VOID CCamera:MoveAlongUpVec(FLOAT fUnits) m_vPosition += m_vUpVec * fUnits; m_vLookat += m_vUpVec * fUnits;/ 沿观察向量平移fUnits个单位VOID CCamera:MoveAlongLookVec

20、(FLOAT fUnits) m_vPosition += m_vLookVec * fUnits; m_vLookat += m_vLookVec * fUnits;/旋转使用D3DXMatrixRotationAxis函数实现,绕rightuplook方向旋转的实现方法:VOID CCamera:RotationRightVec(FLOAT fAngle) D3DXMATRIX R; D3DXMatrixRotationAxis(&R, &m_vRightVec, fAngle); D3DXVec3TransformCoord(&m_vUpVec, &m_vPosition, &R); D

21、3DXVec3TransformCoord(&m_vLookVec, &m_vLookVec, &R); m_vLookat = m_vLookVec * D3DXVec3Length(&m_vPosition);/*D3DXVec3TransformCoord用矩阵变换3-D向量,并且用w = 1投影结果。定义:D3DXVECTOR3*WINAPID3DXVec3TransformCoord(D3DXVECTOR3*pOut,CONST D3DXVECTOR3*pV,CONST D3DXMATRIX*pM);ParameterspOut: in, out指向D3DXVECTOR3结构的操作结

22、果。pV: in指向D3DXVECTOR3结构的向量。pM: in指向D3DXMATRIX结构的变换矩阵。Return Value指向D3DXVECTOR3结构的变换后的向量。说明:这个函数用矩阵pM变换3-D向量pV(x, y, z, 1),并且用w = 1投影结果。函数返回值跟pOut 参数返回值是一样的。这样可以让函数D3DXVec3TransformCoord作为其它函数的参数使用。*/VOID CCamera:RotationUpVec(FLOAT fAngle) D3DXMATRIX R; D3DXMatrixRotationAxis(&R, &m_vUpVec, fAngle);

23、 D3DXVec3TransformCoord(&m_vRightVec, &m_vRightVec, &R); D3DXVec3TransformCoord(&m_vLookVec, &m_vLookVec, &R); m_vLookat = m_vLookVec * D3DXVec3Length(&m_vPosition); D3DXVECTOR3 vNormal; D3DXVec3Normalize(&vNormal, &m_vLookat);VOID CCamera:RotationLookVec(FLOAT fAngle) D3DXMATRIX R; D3DXMatrixRotati

24、onAxis(&R, &m_vLookVec, fAngle); D3DXVec3TransformCoord(&m_vRightVec, &m_vRightVec, &R); D3DXVec3TransformCoord(&m_vUpVec, &m_vUpVec, &R); m_vLookat = m_vLookVec * D3DXVec3Length(&m_vPosition);/摄像机绕X轴旋转fAngle角度VOID CCamera:CircleRotationX(FLOAT fAngle) D3DXMATRIX R; D3DXMatrixRotationAxis(&R, &m_vRi

25、ghtVec, fAngle); D3DXVec3TransformCoord(&m_vUpVec, &m_vUpVec, &R); D3DXVec3TransformCoord(&m_vLookVec, &m_vLookVec, &R); float dy = m_vPosition.y - m_vLookat.y; float dz = m_vPosition.z - m_vLookat.z; m_vPosition.y = m_vLookat.y + dy * cosf(fAngle) - dz * sinf(fAngle); m_vPosition.z = m_vLookat.z + dy * sinf(fAngle) + dz * cosf(fAngle); ResetLookatPos(&m_vLookat);/摄像机绕Y轴旋转fAngle角度VOID CCamera:CircleRotationY(FLOAT fAngle) D3DXMATRIX R; D3DXMatrix

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论