在D3D中实现第一人称视角控制(转)

在D3D中实现第一人称视角控制(转)[@more@]

  这两天做了第一人称视角控制,就像quake一样用鼠标控制方向,用键盘控制左右前后。鼠标和键盘用directinput控制输入。

  

  首先,我们可以知道d3d的view矩阵有三个组成部分,分别是三个向量:眼睛所在点、眼看着的点、向上的方向。

  

  所以,我们首先定义三个向量:

  

  D3DXVECTOR3 VDot,VAtPoint,VUp;

  

  赋予初值:

  

  VDot=D3DXVECTOR3( 2.0f, 0.0f, 2.0f );

  VAtPoint=D3DXVECTOR3( 0.0f, 0.0f, 0.0f );

  VUp=D3DXVECTOR3( 0.0f, 1.0f, 0.0f );

  

  输入到VIEW矩阵matView:

  

  void SetView()

  {

    D3DXMatrixLookAtLH( &matView,&VDot, &VAtPoint, &VUp );

  }

  

  下面就可以开始做键盘控制前进、后退、左移、右移了:我们可以看到在这些控制中,VUp向量是不可以变化的,否则就会有斜着看的效果,只要同时控制VDot和VAtPoint两点的位置就可以了。

  

  由上图,a点就是VDot,b点就是VPoint,ac就是VUp向量。首先,我们计算前进后退:前进后退实际上就是沿着ab的方向同时移动a点和b点:

  

  第一步,计算向量ab: D3DXVec3Subtract(&ab,&VAtPoint,&VDot);

  

  第二步,计算移动的方向和步长: D3DXVec3Normalize(&pOut2,&ab);

  pOut2.x*=u; pOut2.y*=u; pOut2.z*=u;

  

  第三步,将移动的位置加到a和b两点中去,就可得到新的前后位置。

  pOut=VDot;

  D3DXVec3Add(&VDot,&pOut,&pOut2);

  pOut=VAtPoint;

  D3DXVec3Add(&VAtPoint,&pOut,&pOut2);//*/

  SetView();

  

  接下来,我们计算左右移动,实际上就是沿着abc面的法线n同时移动a和b点:

  

  第一步,计算abc面的法线向量n:D3DXVec3Cross(&pOut,&ab,&ac);

  

  其它步骤同上:

  D3DXVec3Normalize(&pOut2,&pOut);

  pOut2.x*=u;pOut2.y*=u;pOut2.z*=u;

  pOut=VDot;

  D3DXVec3Add(&VDot,&pOut,&pOut2);

  pOut=VAtPoint;

  D3DXVec3Add(&VAtPoint,&pOut,&pOut2);

  SetView();

  

  接下来的鼠标控制方向就不是那么简单了,它涉及到围绕空间的轴旋转空间某点,简单来说这里就是固定a点,使b点绕经过a点的一条轴线旋转:

  

  我们把方向分为水平旋转和垂直旋转,其它的方向都是这两个方向的叠加。要绕任意轴旋转变换,我们要知道旋转轴在空间的一点(VDot)和其方向数(a,b,c)(注意这里的abc和上面的不同,这里是数值而不是点),就可以求出变换矩阵。

  

  首先,是水平方向旋转,这是VAtPoint绕VUp旋转的结果:

  

  方向数必须是标准化的,即是长度为1。 D3DXVec3Normalize(&pOut,&ac);

  a=pOut.x;b=pOut.y;c=pOut.z;

  v=(float)sqrt(c*c+b*b);

  

  把VDot点移至原点:

  R=D3DXMATRIX(1,0,0,0,

         0,1,0,0,

         0,0,1,0,

         -VDot.x,-VDot.y,-VDot.z,1);

  //D3DXMatrixMultiply(&R,&R2,&RT);

  R2=R;

  

  

  把现在的ab旋转至ZXO面,原来的变换矩阵是这样的:

  

  D3DXMATRIX(1,0,0,0,

        0,cos(j1),sin(j1),0,

        0,-sin(j1),cos(j1),0,

        0,0,0,1);

  

  但因为cos(j1)=c/v;sin(j1)=b/v;所以变为下面的矩阵

  

  RT=D3DXMATRIX(1,0,0,0,

         0,c/v,b/v,0,

         0,-b/v,c/v,0,

         0,0,0,1);

  D3DXMatrixMultiply(&R,&R2,&RT);R2=R;

  

  同理:

  

  

  cos(j2)=v/|OA|=v/1=v (OA已经标准化了) sin(j2)=-a/|OA|=a;所以得到下面的矩阵:

  

  RT=D3DXMATRIX(v,0,a,0,

         0,1,0,0,

         -a,0,v,0,

         0,0,0,1);

  D3DXMatrixMultiply(&R,&R2,&RT);R2=R;

  

  这时我们就可以使VAtPoint绕VUp旋转变为在新坐标系中绕Z轴转u角(弧度表示)

  RT=D3DXMATRIX((float)cos(u),(float)sin(u),0,0,

         -(float)sin(u),(float)cos(u),0,0,

         0,0,1,0,

         0,0,0,1);

  D3DXMatrixMultiply(&R,&R2,&RT);R2=R;

  

  接下来进行逆变换;

  RT=D3DXMATRIX(v,0,-a,0,

         0,1,0,0,

         a,0,v,0,

         0,0,0,1);

  D3DXMatrixMultiply(&R,&R2,&RT);R2=R;

  

  RT=D3DXMATRIX(1,0,0,0,

         0,c/v,-b/v,0,

         0,b/v,c/v,0,

         0,0,0,1);

  D3DXMatrixMultiply(&R,&R2,&RT);R2=R;

  

  RT=D3DXMATRIX(1,0,0,0,

         0,1,0,0,

         0,0,1,0,

         VDot.x,VDot.y,VDot.z,1);

  D3DXMatrixMultiply(&R,&R2,&RT);

  

  这时得到的R就是VAtPoint绕VUp旋转的变换矩阵

  D3DXVec3Transform(&Vtemp,&VAtPoint,&R);

  VAtPoint.x=Vtemp.x;VAtPoint.y=Vtemp.y;

  VAtPoint.z=Vtemp.z;

  SetView();

  

  而垂直方向的旋转原理上是一样的,但不是绕VUp旋转,而是绕abc面的法线旋转,所以开始应该先计算法线并标准化:

  

  D3DXVec3Cross(&pOut2,&ab,&VUp);

  D3DXVec3Normalize(&pOut,&pOut2);

  

  剩下的同上,但是为了限制向上和向下的范围(0  

  s1=D3DXVec3Length(&ab)*D3DXVec3Length(&VUp);

  s1=(float)acos(D3DXVec3Dot(&ab,&VUp)/s1);

  if(u>0)

  {

    if(s1<=0.018)

      return;

  }//1度

  else if(s1>=3.124)

    return;//179度

  

  这样,第一人称视角的矩阵控制就完成了。

  

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8225414/viewspace-951742/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8225414/viewspace-951742/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值