虚拟驾驶环境搭建(三)

龙云尧个人博客,转载请注明出处。

CSDN地址:http://blog.csdn.net/michael753951/article/details/75073755

个人blog地址:http://yaoyl.cn/huan-jing-da-jian-san/


移动场景的环境搭建

需要移动的场景主要集中在公路,草坪,楼房和障碍物.下面我将逐一实现它们的移动.

公路以及草坪的移动

公路的移动较为简单,还记得我们在第一节中那个run_len变量么,在这里我们将使用它进行操作,已达到移动的效果.代码如下:

1
2
3
4
5
6
7
8
9
10
11
/* 开始进行场景移动 */
go_ahead_rate += go_ahead_ac;
/* 防止速度过快 */
if(go_ahead_rate >= run_len_max) go_ahead_rate = run_len_max;
if(go_ahead_rate <= run_len_min) go_ahead_rate = run_len_min;
run_len += go_ahead_rate;
// 小孩的速度恒定
//child_run_len += 0.1f;
if(run_len >= 4.0f){
run_len = 0.0f;
}

其中go_ahead_rate是一个步进长度,go_ahead_ac是步进加速度,用来模拟车辆的加速减速过程,以免车辆的加减速太过突然而失真.run_len_max用来限制车速的上下界.最后的if判断是为了当车辆运行到一块道路的边界的时候,将run_len归0模拟到达一块新的道路上继续行驶,这样能通过比较少的资源达到比较仿真的驾驶环境.

到了这里,草地和楼房便能够正常的开始进行步进操作了.我们接下来开始移动楼房.

楼房的移动

楼房的移动相比较场景的一动就就没有那么简单了.因为我们在第一节已经简单分析过,道路和草地的出现都是重复的,恒定的.而楼栋的出现是随机的,恒定的.

使用run_len进行前进控制

道路和草地的移动中我们可以使用run_len在0.0~4.0之间不停的变换,所以道路和草地的真正移动距离是不会操作4.0的,而我们在设计场景的时候,又是使用12*12的方块填满的,为了让楼栋能够跨过这12个方块完成移动,我们就需要想一些特殊的办法.

为了简化场景建设,我们让视野内,每栋楼占据的设计面积和道路的方块一致,因此道路单侧最多也只能有12栋楼层,举个例子,就算左侧楼栋不停的出现的话,最多也只能出现12栋楼,再出现新的楼栋的时候,距离自己最近的楼栋也会消失在自己的视野,使用这种方法能够比较简单的同时控制道路和楼栋的运动,即使用len_run进行控制,让他们保持同样的速度运动.

好了我们已经设计成使用len_run对楼栋进行控制了,但是我们又知道run_len在0.0~4.0之间不停的变换,这也就意味着,如果我们没有进行什么特定操作,那么楼栋在移动一段距离(4.0)之后,又会回到起点(0.0)重新移动,这种画风并不是我们需要的结果,因此需要对其进行一定的控制.

添加标志让楼栋完成移动

前一步骤中我们已经完成了楼栋简单的移动,但是楼栋并不能够跨过一个格子的长度.为了实现跨过格子的操作,我们需要添加一些标志位,用来记录当前这栋楼栋运行到了第几格,同时,每当run_len到达4.0,进行归0操作的时候,将标志位进行更新,让所有楼栋的的起点移动到下一个格子,这样当run_len增长的时候,就是从新的起点开始运动的,我们视觉上就会觉得,这栋楼没有间断的不停的向前走.

这种格子移动操作和我们的位运算极其相似,因此我们可以使用一个int的后12位作为标志位,来标识楼栋的位置信息.这样能够让屏幕中同时显示多栋楼层,而且能够让所有楼层同时运动,并且不会显得很突兀.

下面展示部分代码,首先是绘制楼栋的代码:

1
2
3
4
5
6
7
8
9
10
11
12

// 绘制右边的楼栋
glBindTexture(GL_TEXTURE_2D, texture[3]);
int right_temp = building_right_flag;
for(int i = 0; i<12; ++i){
if(right_temp & 0b1 == 1) {
glLoadIdentity();
glTranslatef(2.0,-1.0f, ((12-i)*-4.0f)+run_len); // 移动绘点
glCallList(building2);
}
right_temp >>= 1;
}

然后对场景移动代码稍作修改,让楼栋移动一格.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

/* 开始进行场景移动 */
go_ahead_rate += go_ahead_ac;
/* 防止速度过快 */
if(go_ahead_rate >= run_len_max) go_ahead_rate = run_len_max;
if(go_ahead_rate <= run_len_min) go_ahead_rate = run_len_min;
run_len += go_ahead_rate;
// 小孩的速度恒定
//child_run_len += 0.1f;
if(run_len >= 4.0f){
run_len = 0.0f;
// 提取12位
building_left_flag = (building_left_flag<<1) & 0b111111111111;
building_right_flag = (building_right_flag<<1) & 0b111111111111;
int rand_temp = rand();
// 左边有一定概率出现一栋楼房
if(rand_temp%4 == 0) building_left_flag |= 1;
// 右边同样有一定概率出现一栋楼房
if(rand_temp >> 2 & 1) building_right_flag |= 1;
//child_run_len = -3.0f;
}

障碍物的移动

障碍物的移动相比起来就很简单了,直接放代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 绘制障碍物
int left_temp = building_left_flag;
if(left_temp >> 11 & 0b1 == 1) {
time(&appear);
if(appear - appear_tmp >= 5){
appear_tmp = appear;
bdw_appear = true;
}
if(bdw_appear) {
// 同时控制左边的障碍物
//printf("debug\n");
glBindTexture(GL_TEXTURE_2D, texture[4]);
glLoadIdentity();
glTranslatef(child_run_len, -1.0f, -7.0f);
glCallList(children);
if(child_run_len >= -0.5) {
child_run_len = -3.0f;
bdw_appear = false;
}else{
// 障碍物的速度恒定
child_run_len += 0.1f;
}
}
}

基本上到这里的时候,整个代码已经能够正常的运行起来,我们坐在一辆虚拟的车上不断的前进,偶尔会闪出一个障碍物挡在路中间.

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

请我喝杯咖啡吧~

支付宝
微信