分享
 
 
 

Inside out: Camera

王朝other·作者佚名  2006-02-01
窄屏简体版  字體: |||超大  

Inside out: Camera

丁欧南

Keyword:[OpenGL Camera][FPS 场景][第一人称射击场景]

我是一名OpenGL初学者,刚刚弄懂Camera的实作方法,愿与初学者共享,与高手探讨.如需要此文完整代码,或要转载,请发邮件给我.

A.约定

1. sin cos 等的引数全用弧度制

2. 使用OpenGL

右手定则

3. 矩阵(Matrix)书写规范:

平移(Translation)部分位于最后一行,你可以不加修改地把矩阵写入自己的OpenGL 代码

例:

[A11 A12 A13 A14]

[A21 A22 A23 A24]

[A31 A32 A33 A34]

[A41 A42 A43 A44]

float matrix[]={A11,A12,A13,A14,A21,A22,A23,A24,A31,A32,A33,A34,A41,A42,A43,A44};

4. *:点积(Dot

Product) ×:叉积(Cross

Product)

B.概念

大家都知道gluLookAt,它有三类(每类3个)共9个引数:

void gluLookAt(GLdouble eyex,GLdouble

eyey,GLdouble eyez,

GLdouble centerx,GLdouble

centery,GLdouble centerz,

GLdouble upx,GLdouble

upy,GLdouble upz);

你需要分别指定这三类引数,才能完成Camera变换.

1.视线:你不用在gluLookAt中指定视线(从眼到被视物体的向量),但在变换视点(尤其是旋转时),所作的许多 操作都是针对它进行的,

后面将给出如何计算视线向量的公式.

a.视点:即gluLookAt中eye*的那三个引数,视点指的是一条从原点到眼位置的向量.

从你的座位上站起来,这时你改变的就是视点.

b.视目标:即gluLookAt中center*的那三个引数,视目标指的是一条从原点到被视物体的向量.

水平转动你的脖子,这时你所作的就是改变视目标.

c.仰视向量:即gluLookAt中up*的那三个引数,仰视向量指的是头顶的朝向.

竖直抬起头(‘向上看’),这时改变的就是仰视向量.

[一般来讲,仰视向量用(0,1,0)就可以了,不用再仔细考虑它]

2.很明显,由向量减法 视线 view,视点 pos,视目标

tar

view=tar-pos;

3.Camera的变换也就是改变视线位置(前进或后退),方向(转头)

4.Camera变换Pipeline:

Ⅰ 由pos,tar

计算出 view

Ⅱ 变换view

Ⅲ 将view的x,y,z分量传回pos和tar

Ⅳ 将pos,tar,up传给gluLookAt

C.平移

平移是最简单的,它起的作用是游戏者的前进与后退,你会发现平移其实就是平行移动视线,方向不变.

如下图:

代码讲解:

void Move(float speed) { //speed:指定每按一下键前进多少,我取的是0.3

Vector view=tar-pos; //取得view,Vector不是std::vector

pos.x+=speed*view.x;

pos.z+=speed*view.z;

tar.x+=speed*view.x;

tar.z+=speed*view.z;

}

//我只希望在平面上移动,所以没有y分量的事.

D.旋转

旋转就是转头操作,比较复杂,一点一点来.

D1.绕任意轴旋转一条向量

Vup⊥Vperp |Vup|=|Vperp|=|Vaux| Vproj⊥Vperp n∥Vproj n为单位向量

绕n旋转V θ度到V’,

求V’

Vproj=|Vproj|/|n| n

n*V=|n||V|cosβ

cosβ=|Vproj|/|V| |Vproj|=|V|cosβ

n*V=|n||Vproj| |Vproj|=(n*V)/|n|

Vproj=(n*V)/|n|2

n 因为

n 为单位向量

所以

Vproj=n*V n

Vperp=V-Vproj=V-n*V

n

Vup=Vperp×n=(V-n*V n)×n=V×n-n*V(n×n)=V×n

Vaux=-sin(θ-90)Vperp+cos(θ-90)Vup=sin(90-θ)Vperp+cos(90-θ)Vup

=cosθVperp+sinθVup=cosθ(V-n*V n)+sinθ(V×n)

V’=Vperp+Vaux=n*v

n+cosθ(V-n*V n)+sinθ(V×n)

D2.水平转头

水平转头即在XZ平面上绕竖直方向旋转view向量

可看出pos无变化,y分量亦无变化.

XZ平面的旋转矩阵:

[ cosθ

0 -sinθ ]

[ 0 1

0 ]

[ sinθ 0

cosθ ]

取得view: view=tar-pos;

旋转view:

[cosθ

0 -sinθ ]

[view.x view.y view.z]

[0 1 0 ]

[sinθ

0 cosθ]

=[view.x*cosθ+view.z*sinθ

view.y -view.x*sinθ+view.z*cosθ]

传回tar值:

tar’=pos+view’;

D3.竖直转头

竖直转头即在YZ平面上以垂直于view的直线为轴旋转view向量

侧视示意图:

鸟瞰示意图:

取得view:

view=tar-pos;

取得

axis: 即旋转view (-π/2)

[0 0 1]

[view.x

view.y view.z] [0 1 0]

[-1 0 0]

=[-view.z view.y

view.x]

为了用上D1中求得的公式,把axis归一化(Normalize)

绕axis旋转view: (套用D1最后得出的公式)

view’=axis*view axis+cosθ(view-axis*view axis)+sinθ(view×axis);

更新tar值:

tar’=pos+view;

E.鼠标滑动角度计算

我们注意到进行旋转Camera时,需要向程序提供转过的角度(2个)

一个是水平转动角度(转头),一个是竖直转动角度(抬头或低头)

这样计算:

鼠标滑过的距离其实是view向量终点滑过的距离

用滑过的距离(s),view向量的长度(l),求得水平角(a),竖直角(b)

a=arc tan s.x/l b=arc tan s.y/l

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有