虚拟驾驶环境搭建(三)
龙云尧个人博客,转载请注明出处。
CSDN地址:http://blog.csdn.net/michael753951/article/details/75073755
个人blog地址:http://yaoyl.cn/huan-jing-da-jian-san/
移动场景的环境搭建
需要移动的场景主要集中在公路,草坪,楼房和障碍物.下面我将逐一实现它们的移动.
公路以及草坪的移动
公路的移动较为简单,还记得我们在第一节中那个run_len变量么,在这里我们将使用它进行操作,已达到移动的效果.代码如下:
1 /* 开始进行场景移动 */
2 go_ahead_rate += go_ahead_ac;
3 /* 防止速度过快 */
4 if(go_ahead_rate >= run_len_max) go_ahead_rate = run_len_max;
5 if(go_ahead_rate <= run_len_min) go_ahead_rate = run_len_min;
6 run_len += go_ahead_rate;
7 // 小孩的速度恒定
8 //child_run_len += 0.1f;
9 if(run_len >= 4.0f){
10 run_len = 0.0f;
11 }
其中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 glBindTexture(GL_TEXTURE_2D, texture[3]);
4 int right_temp = building_right_flag;
5 for(int i = 0; i<12; ++i){
6 if(right_temp & 0b1 == 1) {
7 glLoadIdentity();
8 glTranslatef(2.0,-1.0f, ((12-i)*-4.0f)+run_len); // 移动绘点
9 glCallList(building2);
10 }
11 right_temp >>= 1;
12 }
然后对场景移动代码稍作修改,让楼栋移动一格.
1
2 /* 开始进行场景移动 */
3 go_ahead_rate += go_ahead_ac;
4 /* 防止速度过快 */
5 if(go_ahead_rate >= run_len_max) go_ahead_rate = run_len_max;
6 if(go_ahead_rate <= run_len_min) go_ahead_rate = run_len_min;
7 run_len += go_ahead_rate;
8 // 小孩的速度恒定
9 //child_run_len += 0.1f;
10 if(run_len >= 4.0f){
11 run_len = 0.0f;
12 // 提取12位
13 building_left_flag = (building_left_flag<<1) & 0b111111111111;
14 building_right_flag = (building_right_flag<<1) & 0b111111111111;
15 int rand_temp = rand();
16 // 左边有一定概率出现一栋楼房
17 if(rand_temp%4 == 0) building_left_flag |= 1;
18 // 右边同样有一定概率出现一栋楼房
19 if(rand_temp >> 2 & 1) building_right_flag |= 1;
20 //child_run_len = -3.0f;
21 }
障碍物的移动
障碍物的移动相比起来就很简单了,直接放代码:
1 // 绘制障碍物
2 int left_temp = building_left_flag;
3 if(left_temp >> 11 & 0b1 == 1) {
4 time(&appear);
5 if(appear - appear_tmp >= 5){
6 appear_tmp = appear;
7 bdw_appear = true;
8 }
9 if(bdw_appear) {
10 // 同时控制左边的障碍物
11 //printf("debug\n");
12 glBindTexture(GL_TEXTURE_2D, texture[4]);
13 glLoadIdentity();
14 glTranslatef(child_run_len, -1.0f, -7.0f);
15 glCallList(children);
16 if(child_run_len >= -0.5) {
17 child_run_len = -3.0f;
18 bdw_appear = false;
19 }else{
20 // 障碍物的速度恒定
21 child_run_len += 0.1f;
22 }
23 }
24 }
基本上到这里的时候,整个代码已经能够正常的运行起来,我们坐在一辆虚拟的车上不断的前进,偶尔会闪出一个障碍物挡在路中间.