游戏碰撞测试总结

游戏碰撞检测总结(VER 1.0)

0.从BSP算法说起(不重要,可跳过)

它的本质是二叉树,也就是用一个面把空间分割成两部分,分割出的空间则继续用面分割,以此类推,直到到达特定递归深度,或者空间中不再有物体或只剩下一个物体(得到凸包/凸多面体)。最终,叶结点对应场景中的物体,内部结点存储分割面。物体被“收纳”到各个包围盒中。
用于游戏中的场景管理,尤其是室内场景的管理。对于大的游戏场景,首先对物体建立包围体结构,然后以包围体为单位建立场景的BSP树,用以加速BSP树的构建。从剖分面的选择上看,BSP树的类型有3种,一是均匀剖分,二是平行坐标轴剖分,三是任意平面剖分。室内场景中通常选择平行坐标轴的剖分,因为墙壁是完美的剖分面。
BSP树的遍历是使用BSP的一个基本技术。碰撞检测本质上减少了树的遍历或搜索。这种方法很有用因为它能在早期排除大量的多边形,所以在最后我们仅仅是对少数面进行碰撞检测。正如我前面所说的,用找出两个物体间的分隔面的方法适合于判断两个物体是否相交。如果分隔面存在,就没有发生碰撞。因此我们递归地遍历world树并判断分割面是否和包围球或包围盒相交。我们还可以通过检测每一个物体的多边形来提高精确度。进行这种检测最简单的一个方法是测试看看物体的所有部分是否都在分割面的一侧。这种运算真的很简单,我们用迪卡尔平面等式 ax + by + cz + d = 0 去判断点位于平面的哪一侧。如果满足等式,点在平面上;如果ax + by + cz + d > 0那么点在平面的正面;如果ax + by + cz + d < 0点在平面的背面。
BSP除用于碰撞检测外,还可以确定物体的遮挡关系,可视化处理。
老技术了 暂时了解即可

1.包围盒以及AABB树算法(AABB和OBB包围盒)

1.1.1包围盒

包围盒算法是一种求解离散点集最优包围空间的方法。基本思想是用体积稍大且特性简单的几何体(称为包围盒)来近似地代替复杂的几何对象。用于进行碰撞干涉初步检测。

属性:
碰撞检测技术中所用的包围盒有两个属性:简单性和紧密性。
简单:计算简单
紧密:包围紧密
简单性是指包围盒间进行相交测试时需要的计算量,这不但要求几何形状简单容易计算,而且要求相交测试算法简单快速;
紧密性要求包围盒尽可能的贴近被包围的对象,这一属性直接关系到需要进行相交测试的包围盒的数目,紧密性越好,参与相交测试的包围盒数目就越少。

分类:
1.AABB包围盒。
应用最早的包围盒。它被定义为包含该对象,且边平行于坐标轴的最小六面体。故描述一个AABB,仅需六个标量。AABB构造比较简单,存储空间小,但紧密性差,尤其对不规则几何形体,冗余空间很大,当对象旋转时,无法对其进行相应的旋转。处理对象是刚性并且是凸的,不适合包含软体变形的复杂的虚拟环境情况。AABB也是比较简单的一类包围盒。但对于沿斜对角方向放置的瘦长形对象,其紧密性较差。由于AABB相交测试的简单性及较好的紧密性,因此得到了广泛的应用,还可以用于软体对象的碰撞检测。
2.包围球:
包含该对象的最小的球体
确定包围球算法:首先需分别计算组成对象的基本几何元素集合中所有元素的顶点的x,y,z坐标的均值以确定包围球的球心,再由球心与三个最大值坐标所确定的点间的距离确定半径r。包围球的碰撞检测主要是比较两球间半径和与球心距离的大小。
3.OBB包围盒:
OBB是较为常用的包围盒类型。它是包含该对象且相对于坐标轴方向任意的最小的长方体。OBB最大特点是它的方向的任意性,这使得它可以根据被包围对象的形状特点尽可能紧密的包围对象,但同时也使得它的相交测试变得复杂。OBB包围盒比AABB包围盒和包围球更加紧密地逼近物体,能比较显著地减少包围体的个数,从而避免了大量包围体之间的相交检测。但OBB之间的相交检测比AABB或包围球体之间的相交检测更费时。
包围紧密,但是相交计算复杂。

包围盒的详细介绍:https://blog.csdn.net/windgs_yf/article/details/87884884
碰撞检测的代码:https://blog.csdn.net/huang9012/article/details/42172983?utm_source=blogxgwz3&utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-3&spm=1001.2101.3001.4242

1.2.1 AABB树算法

说人话的AABB盒算法ref:https://segmentfault.com/a/1190000006802081
2D和3D场景AABB碰撞技术干货:https://blog.csdn.net/u012419410/article/details/41911025/?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-3&spm=1001.2101.3001.4242
cocos2d:https://blog.csdn.net/jxw167/article/details/54574459

1.2.2 OBB树

显然只用一个包围盒是不精确的,在我们建立OBB树的过程中,不断分割大包围盒,使其贴合物体,生成最近似的包围盒。

图左的树就是OBB树以及盒的创建过程
OBB树创建过程较为复杂,因此相对于AABB树更加精确而开销大,使用哪一个要根据业务的目标精度。对一个需要快速反应的3D射击游戏来说,我们可能用 AABB 来进行碰撞检测更好些――我们可以牺牲一些精度来换取速度和实现的简单化。

1.3 包围盒碰撞的判断

1.先检测最大的包围盒是否相交,如果相交了,他们可能发生了碰撞
2.接下来我们将进一步地递归处理它们(不断地递归用下一级进行处理)。如果我们沿着下一级,发现子树并没有发生相交,这时我们就可以停止并得出结论没有发生碰撞。
3.如果我们发现子树也相交了,那么要进一步处理它的子树直到到达叶子节点,并最终得出结论。
进行相交测试时,我们可以把包围盒投影到空间坐标轴上并检查它们是否线性相交。这种给定的坐标轴称为分离坐标轴(separating axis)

2.四叉树算法
BSP、四叉树、八叉树都服务与场景管理这项业务要求,
先讲基础的四叉树,我们对一个二维平面,把它划分为田字格,这样就有了四个子空间。那么整个田字格就是一个树。有根节点和叶子节点。如此递归。不断细分,保留有物体信息的空间。

长这样,白色正方形代表空间中存在物体,并且已经是不需继续划分的,或者已经到了最大深度而不再划分。白色正方形代表空间中存在物体,并且已经是不需继续划分的,或者已经到了最大深度而不再划分。
你可以这样描述这个数据结构
struct treeNode { treeNode* upLeft; //四个子树 treeNode* upRight; treeNode* downLeft; treeNode* downRight; int objectNum; //包含对象个数 Object* object; //包含的对象 Box box; //所在的包围盒 bool hasChild; //是否有孩子 }
struct treeNode{ treeNode# }

优点:可加速搜索,快速找到包含/不包含物体的地图,广泛应用于室外场景的管理。
与bsp树相比是动态的,因为可以动态载入或者删除物体并且更新树。而Bsp作为一棵二叉树却不能修改主要是因为它的切割面的选择是根据周围的物体来选择的。
缺点:划分出来的四叉树往往没有二叉树那么平衡。
应用:
(1)二维碰撞检测的广阶段
(2)地形渲染剔除机制
(3)根据四叉树只绘制玩家周围物体,或者用LoD技术
(4)动态载入游戏对象
四叉树最广泛应用于室外地形场景
优化:出现物体正好在分割线中间的问题,这时考虑使用松散四叉树,这里不细谈
详见:https://blog.csdn.net/zjq2008wd/article/details/79349342
在Unity中使用四叉树算法绘制地形:https://blog.csdn.net/jxw167/article/details/81869949?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-7&spm=1001.2101.3001.4242
3.八叉树算法
可视为三维的四叉树,用于快速定位和搜索,定位会定位到叶子结点(也是图中的小立方体)

4.一些常见的刚体碰撞库:CHIPMUNK2D
5.引申——消隐算法、Z缓冲区算法和画家算法以及向量叉积(CROSS PRODUCT)的几何意义及应用
向量叉积https://blog.csdn.net/minmindianzi/article/details/100056129
三种遮蔽算法的比较:https://blog.csdn.net/weiwangchao_/article/details/7031533?utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control

其他值得学习的ref
基本上总结的最好的的博客:
https://blog.csdn.net/qq826364410/article/details/88937586?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-7&spm=1001.2101.3001.4242
栅格算法:
https://blog.csdn.net/hookby/article/details/68203975?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&dist_request_id=0823a26a-1cb6-46fe-8179-751be0b5eba7&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control
a*算法
关于BSP算法值得学习的ref:1.https://blog.csdn.net/ZJU_fish1996/article/details/52554620?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control&dist_request_id=17164bdb-399f-4e16-9a8e-866edf28559b&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control
2.https://blog.csdn.net/pleasecallmewhy/article/details/8426183?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control&dist_request_id=9675996f-a7be-45ce-8d3e-dc410dfe6dc4&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control
3.https://blog.csdn.net/birdflyto206/article/details/51547716?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.control&dist_request_id=9675996f-a7be-45ce-8d3e-dc410dfe6dc4&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.control
4.https://blog.csdn.net/pleasecallmewhy/article/details/8426183?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242

posted @ 2021-09-26 16:05  Homuni_Sun  阅读(647)  评论(0)    收藏  举报