3d碰撞检测技术15页文档资料.docx
- 文档编号:652674
- 上传时间:2022-10-11
- 格式:DOCX
- 页数:16
- 大小:56.75KB
3d碰撞检测技术15页文档资料.docx
《3d碰撞检测技术15页文档资料.docx》由会员分享,可在线阅读,更多相关《3d碰撞检测技术15页文档资料.docx(16页珍藏版)》请在冰豆网上搜索。
3d碰撞检测技术15页文档资料
核心提示:
10.3碰撞检测技术到目前为止,构造的各种对象都是相互独立的,在场景中漫游各种物体,墙壁、树木对玩家(视点)好像是虚设,可以任意从其中穿越。
为了使场景人物更加完善,还需要使用碰撞检测技术。
10.3.1碰撞检测技术简介无论是PC游戏,还是移动应用,
“师”之概念,大体是从先秦时期的“师长、师傅、先生”而来。
其中“师傅”更早则意指春秋时国君的老师。
《说文解字》中有注曰:
“师教人以道者之称也”。
“师”之含义,现在泛指从事教育工作或是传授知识技术也或是某方面有特长值得学习者。
“老师”的原意并非由“老”而形容“师”。
“老”在旧语义中也是一种尊称,隐喻年长且学识渊博者。
“老”“师”连用最初见于《史记》,有“荀卿最为老师”之说法。
慢慢“老师”之说也不再有年龄的限制,老少皆可适用。
只是司马迁笔下的“老师”当然不是今日意义上的“教师”,其只是“老”和“师”的复合构词,所表达的含义多指对知识渊博者的一种尊称,虽能从其身上学以“道”,但其不一定是知识的传播者。
今天看来,“教师”的必要条件不光是拥有知识,更重于传播知识。
10.3 碰撞检测技术
教师范读的是阅读教学中不可缺少的部分,我常采用范读,让幼儿学习、模仿。
如领读,我读一句,让幼儿读一句,边读边记;第二通读,我大声读,我大声读,幼儿小声读,边学边仿;第三赏读,我借用录好配朗读磁带,一边放录音,一边幼儿反复倾听,在反复倾听中体验、品味。
到目前为止,构造的各种对象都是相互独立的,在场景中漫游各种物体,墙壁、树木对玩家(视点)好像是虚设,可以任意从其中穿越。
为了使场景人物更加完善,还需要使用碰撞检测技术。
死记硬背是一种传统的教学方式,在我国有悠久的历史。
但随着素质教育的开展,死记硬背被作为一种僵化的、阻碍学生能力发展的教学方式,渐渐为人们所摒弃;而另一方面,老师们又为提高学生的语文素养煞费苦心。
其实,只要应用得当,“死记硬背”与提高学生素质并不矛盾。
相反,它恰是提高学生语文水平的重要前提和基础。
10.3.1 碰撞检测技术简介
无论是PC游戏,还是移动应用,碰撞检测始终是程序开发的难点,甚至可以用碰撞检测作为衡量游戏引擎是否完善的标准。
好的碰撞检测要求人物在场景中可以平滑移动,遇到一定高度的台阶可以自动上去,而过高的台阶则把人物挡住,遇到斜率较小的斜坡可以上去,斜率过大则会把人物挡住,在各种前进方向被挡住的情况下都要尽可能地让人物沿合理的方向滑动而不是被迫停下。
在满足这些要求的同时还要做到足够精确和稳定,防止人物在特殊情况下穿墙而掉出场景。
做碰撞检测时,该技术的重要性容易被人忽视,因为这符合日常生活中的常识。
如果出现Bug,很容易被人发现,例如人物无缘无故被卡住不能前进或者人物穿越了障碍。
所以,碰撞检测是让很多程序员头疼的算法,算法复杂,容易出错。
对于移动终端有限的运算能力,几乎不可能检测每个物体的多边形和顶点的穿透,那样的运算量对手机等设备来讲是不可完成的,所以移动游戏上使用的碰撞检测不可能使用太精确的检测,而且对于3D碰撞检测问题,还没有几乎完美的解决方案。
目前只能根据需要来取舍运算速度和精确性。
目前成功商业3D游戏普遍采用的碰撞检测是BSP树及AABB(axiallyalignedboundingbox)包装盒(球)方式。
简单地讲,AABB检测法就是采用一个描述用的立方体或者球形体包裹住3D物体对象的整体(或者是主要部分),之后根据包装盒的距离、位置等信息来计算是否发生碰撞,如图10-24所示。
除了球体和正方体以外,其他形状也可以作包装盒,但是相比计算量和方便性来讲还是立方体和球体更方便些,所以其他形状的包装只用在一些特殊场合使用。
BSP树是用来控制检测顺序和方向的数据描述。
在一个游戏场景中可能存在很多物体,它们之间大多属于较远位置或者相对无关的状态,一个物体的碰撞运算没必要遍历这些物体,同时还可以节省重要的时间。
如果使用单步碰撞检测,需要注意当时间步长较大时会发生两个物体完全穿透而算法却未检测出来的问题,如图10-25所示。
其解决方案是产生一个4D空间,在物体运动的开始和结束时间之间产生一个4D超多面体,用于穿透测试。
图10-24 AABB包装盒 图10-25 碰撞检测的单步失控和4D测试
读者在程序开发初期有必要对碰撞检测有一个初步的估计,以免最后把大量精力消耗在碰撞检测问题上,从而降低了在基础的图形编程之上的注意力。
10.3.2 球体碰撞检测
真实的物理模拟系统需要非常精确的碰撞检测算法,但是游戏中常常只需要较为简单的碰撞检测,因为只需要知道物体什么时候发生碰撞,而不用知道模型的哪个多边形发生了碰撞,因此可以将不规则的物体投影成较规则的物体进行碰撞检测。
球体只有一个自由度,其碰撞检测是最简单的数学模型,我们只需要知道两个球体的球心和半径就能进行检测。
那么球体碰撞是如何工作的?
主要过程如下。
n 计算两个物体中心之间的距离,并且将其与两个球体的半径和进行比较。
n 如果距离大于半径和,则没有发生碰撞。
n 否则,如果距离小于半径和,则发生了物体碰撞。
考虑由球心c1、c2和半径r1、r2定义的两个球,如图10-26所示。
设d为球心间的距离。
很明显,当d<r1+r2时相交,在实践中通过比较d2<(r1+r2)2,可以避免包括计算d在内的平方根运算。
对两个运动的球进行碰撞检测要麻烦一些,假设两个球的运动向量为d1和d2,球与位移向量是一一对应的,它们描述了所讨论时间段中的运动方式。
事实上,物体的运动是相对的,例如两列在两条平行轨道上相向行驶的火车,在其中一列中观察,对方的速度是两车速度之和。
同样,也可以从第一个球的角度来简化问题,假设第一个球是“静止”的,另一个是“运动”的,那么该运动向量等于原向量d1和d2之差,如图10-27所示。
图10-27 动态球的检测过程
球体碰撞的优点是非常适用于需要快速检测的游戏,因为它不需要精确的碰撞检测算法。
执行速度相对较快,不会给CPU带来过大的计算负担。
球体碰撞的另一个劣势是只适用于近似球形物体,如果物体非常窄或者非常宽,该碰撞检测算法将会失效,因为会在物体实际发生碰撞之前,碰撞检测系统就发出碰撞信号,如图10-28所示是球体碰撞检测中可能出现的坏情况,其解决方法是缩小检测半径,或者使用其他检测模型,如图10-29所示。
图10-28 球体碰撞的坏情况 图10-29 缩小检测半径
为了解决包容球精确度不高的问题,人们又提出了球体树的方法。
球体树实际上是一种表达3D物体的层次结构。
对一个形状复杂的3D物体,先用一个大球体包容整个物体,然后对物体的各个主要部分用小一点的球体来表示,然后对更小的细节用更小的包容球体,这些球体和它们之间的层次关系就形成了一个球体树。
举例来说,对一个游戏中的人物角色,可以用一个大球来表示整个人,然后用中等大小的球体来表示四肢和躯干,然后用更小的球体来表示手脚等。
这样在对两个物体进行碰撞检测时,先比较两个最大的球体。
如果有重叠,则沿树结构向下遍历,对小一点的球体进行比较,直到没有任何球体重叠,或者到了最小的球体,这个最小的球体所包含的部分就是碰撞的部分,如图10-30所示。
10.3.3 AABB立方体边界框检测
用球体去近似地代表物体运算量很小,但在游戏中的大多数物体是方的或者长条形的,应该用方盒来代表物体。
另一种常见的检测模型是立方体边界框,如图10-31展示了一个AABB检测盒和它里面的物体。
坐标轴平行(Axially-aligned)不仅指盒体与世界坐标轴平行,同时也指盒体的每个面都和一条坐标轴垂直,这样一个基本信息就能减少转换盒体时操作的次数。
AABB技术在当今的许多游戏中都得到了应用,开发者经常用它们作为模型的检测模型,再次指出,提高精度的同时也会降低速度。
因为AABB总是与坐标轴平行,不能在旋转物体时简单地旋转AABB,而是应该在每一帧都重新计算。
如果知道每个对象的内容,这个计算就不算困难,也不会降低游戏的速度。
然而,还面临着精度的问题。
假如有一个3D的细长刚性直棒,并且要在每一帧动画中都重建它的AABB。
可以看到每一帧中的包装盒都不一样而且精度也会随之改变,如图10-32所示。
图10-31 3D模型与AABB检测盒 图10-32 不同方向的AABB
可以注意到AABB对物体的方向很敏感,同一物体的不同方向,AABB也可能不同(由于球体只有一个自由度,所以检测球对物体方向不敏感)。
当物体在场景中移动时,它的AABB也需要随之移动,当物体发生旋转时,有两种选择:
用变换后的物体来重新计算AABB,或者对AABB做和物体同样的变换。
如果物体没有发生扭曲,可以通过“变换后的AABB”重新计算,因为该方法要比通过“变换后的物体”计算快得多,因为AABB只有8个顶点。
变换AABB得出新的AABB要比变换物体的运算量小,但是也会带来一定的误差,如图10-33所示。
比较图中原AABB(灰色部分)和新AABB(右边比较大的方框),它是通过旋转后的AABB计算得到的,新AABB几乎是原来AABB的两倍,注意,如果从旋转后的物体而不是旋转后的AABB来计算新AABB,它的大小将和原来的AABB相同。
先介绍AABB的表达方法,AABB内的点满足以下条件:
xmin≤x≤xmax
ymin≤y≤ymax
zmin≤z≤zmax
因此只需要知道两个特别重要的顶点(xmin,ymin,zmin)、(xmax,ymax,zmax),记作:
float[]min=newfloat[]{0.0f,0.0f,0.0f};
float[]max=newfloat[]{0.0f,0.0f,0.0f};
中心点是两个顶点的中点,代表了包装盒的质点。
float[]center=newfloat[]{0.0f,0.0f,0.0f};
中心点的计算方法如下:
float[]center(){
center[0]=(min[0]+max[0])*0.5f;
center[1]=(min[1]+max[1])*0.5f;
center[2]=(min[2]+max[2])*0.5f;
returncenter;
通过这两个顶点可以知道以下属性。
floatxSize(){return(max[0]-min[0]);}
floatySize(){return(max[1]-min[1]);}
floatzSize(){return(max[2]-min[2]);}
floatsize(){return(max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]);}
当添加一个顶点到包装盒时,需要先与这两个顶点进行比较。
voidadd(float[]p){
if(p[0] if(p[0]>max[0])max[0]=p[0]; if(p[1] if(p[1]>max[1])max[1]=p[1]; if(p[2] if(p[2]>max[2])max[2]=p[2]; 检测包装盒是否为空,可以将这两个顶点进行比较。 booleanisEmpty(){ return(min[0]>max[0])
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 碰撞 检测 技术 15 文档 资料