碰撞检测

在任何一款3D游戏中,碰撞检测(Collision Detection)都是不可或缺的。碰撞检测是计算机动画、系统仿真、计算机图形学、计算几何、机器人学、CAD/CAM等研究领域的经典问题。

碰撞检测的概述

基于格子的碰撞检测,系统实现简单,精度不够,不属于严格意义的3D碰撞检测;

  • 按照数据结构不同,可以分为:
  1. 基于BSP数的碰撞检测算法
    基本成熟定性,但BSP树需要很长的预处理时间,不适合在加载时计算,所以BSP互粉经常会产生原多边形数三到四倍的多边形,数据量增加大,不太适合用于大型游戏。
  2. 基于BVTree
    对于任意复杂三角形几何的碰撞检测多(Bounding Volume Tree),具体的可以是AABB Tree、OBB Tree或者K-DOP Tree。
  • 按照检测方式不同,可以分为:
  1. 离散点的碰撞检测
    检测制定某一时刻T的两个静态碰撞体,看它们之间是否发生交跌,若没有交跌,则证明两个物体没有发生碰撞,这是返回它们最近点的举例;若发生交跌,则返回交跌深度,交跌方向等。离散点碰撞检测的缺点是:当检测到碰撞时,两个碰撞体其实已经发生了交跌。
  2. 连续碰撞检测
    分别指定T1、T2两个试可两个碰撞体的位置,看它们在由T1运动到T2时刻的过程中是否发生碰撞,如果碰撞,就返回第一碰撞点的位置和法线。连续碰撞检测是最自然的碰撞检测,可以大大方便碰撞相应逻辑的编写,很容易避免物体发生交跌或穿越。该方法的缺点是实现起来非常复杂,开销大。
    目前大部分引擎采用的是离散方式,通过采用小的模拟步长来避免物体交跌过深或者穿越。

常用的碰撞检测算法

距离跟踪法

通过寻找和跟踪两个多面体之间的最近点计算它们之间的距离。最近点计算是碰撞查询中强有力的工具,获取两物体之间的最近点后,即可得到它们之间的距离。如果两对象的合成最大位移量小于两者间的距离,对象就除与分离状态。当距离小于或等于零时,两个多面体发送碰撞,当物体的运动速度不快,相邻帧之间的运动位移变化小,可以用帧的连续性增量式计算物体间的距离。

基于图像空间的碰撞检测法

  1. Shinya算法:
    利用GPU中物体的深度信息,在绘制凸物体的时候保存每个像素的深度信息,并对深度信息进行排列找,然后检测物体在某一像素上的最大深度是否与其最小深度值相邻,来判断是否相交。
  2. Rossignac算法:
    利用深度缓存和模板缓存来减少深度信息的存储量,通过移动裁剪平面,判断平面上每个像素是否同时在两个实体之内,从而确定物体是否相交。
  3. Myszkowski算法:
    用模板缓存保存视口中每个像素所代表的射线进去一个物体前,已经进入和例开物体的次数,读这个数据来判断两个物体是否相交。
  4. Basiu算法:
    先用几何方法确定两个物体包围盒的相交区域,然后再相交区域中利用GPU加速进行相交检测,将相交情况按照深度值进行分类,用模板缓存值表示分类,然后通过检查模板缓存值判断两个物体之间是否碰撞。缺点是,仅能处理凸多面体。
  5. Govindaraju算法:
    利用硬件加速快速剔除明显不发生相交的物体,然后用几何快速相交检测算法得到碰撞结果。
  6. Heidelbeger算法:
    先将两个物体的相交区域按层次升读分解为层次深度图,然后通过图形硬件绘制过程判断两个物体在层次深度图的每个像素上是否有相交区间存在,来确定物体是否发生碰撞。

空间分解法

空间分解法是将整个虚拟空间划分成相等体积的单元格,只对占据同一单元格或相邻单元格的几何对象进行相交测试。常用的碰撞算法有BSP树、空间八叉树和空间四叉树。一般来说,空间分解算法在每次碰撞测试时都需要确定每个模型占有的空间单元,当有模型运动时,只需要重新计算运动模型所占有的空间即可。空间分解法使用于物体在空间中均匀分布的稀疏环境,通常被应用于类似物体在障碍之间运动的虚拟场景。
BSP算法,因为BSP的构建过程需要大量计算,一旦生成BSP树,就很难修改,所以不适用于实体形状发生改变的情况。对于传统的八叉树或四叉树不能保留物体的几何、物体属性,不利于进行交互式操作。

层次包围盒法

是使用较多的一种碰撞检测方法,用体积略大于几何特性简单的包围盒近似地描述复杂的几何对象,从而只需对包围盒重叠的对象进行进一步相交测试。通过构造书状层次结构可以越来月逼近对象的几何模型,知道几乎完全获得对象的几何特性。典型的层次结构树主要包括AABB层次书、包围球层次书、OBB层次树和k-DOP层次树等。
《Irrlicht 3D游戏引擎程序设计》阅读笔记

你可能感兴趣的:(碰撞检测)