分享
 
 
 

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

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

这两天做了第一人称视角控制,就像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(u0)

{

if(s1

return;

}//1度

else if(s1=3.124)

return;//179度

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有