冲突检测
在现实生活中很少发生没有约束和障碍的身体运动,对于虚拟世界也是如此。为了正确描述身体遇到障碍物的情况,请使用碰撞检测。
碰撞检测算法,无论其实现方式如何,通常以不可见的简化形状运行,这些形状近似于碰撞对象的网格。这种近似称为碰撞器(或碰撞形状)。对撞机有几种类型,可以组合使用:盒子,球体,圆柱体,胶囊,凸包。
- 形状-形状碰撞:在分配了物理属性(即具有 body 和至少一个 shape ,都必须启用)。在这种情况下,可以找到形状之间的接触点。
- 形状-表面碰撞:已分配了物理属性的对象与非物理对象(即没有物理表示形式)之间。如果 surface 具有Collision标志set,它也可以被动地参与物理交互并阻止物理对象通过。在这种情况下,将计算形状和表面多边形之间的接触点。
为了使对象参与碰撞检测(即为collider),必须将其添加到表示物理场景的特定BSP树中。如果为对象分配了 body 或对象的至少一个表面设置了Collision标志,则自动为对象启用碰撞检测。启用/禁用碰撞检测的算法如下所示。
- 全局禁用物理模拟不会关闭碰撞检测。
- 如果对象具有已分配并启用的身体和形状,则碰撞检测算法将仅使用形状的参数,而将忽略其表面的参数。
也可以看看#
- getCollision() methods
- 物理视频教程
工艺管道#
整个过程分为以下几个阶段:
- 冲突检测 -在此阶段,我们发现与所有接触点的所有冲突并收集所有必要的信息。
碰撞响应 -这是碰撞的结果(例如,两个球相互弹起)。没有响应,两个对象的碰撞和相交就不会有任何区别。计算碰撞响应时会考虑摩擦力,恢复力和其他参数。
回调执行 -对某些与物理相关的事件执行的自定义用户定义操作。
检测碰撞#
检查所有成对的对象是否碰撞非常耗时,尤其是在场景较大的情况下。在进行更精确,更昂贵的计算之前,我们可以过滤掉放置太远而无法碰撞的对象对。因此,可以使用场景树在物理距离内找到所有具有物理物体的对象。
实际上,本身没有宽窄相,所以在下一步,所有碰撞( shape-shape 和 shape-surface )以及所有碰撞体的接触点,即它们是否相交或它们之间的距离小于穿透公差的值。接触点由它们的坐标,法线,形状穿透的深度,相对速度(两个物体之间),相对摩擦和恢复来表示。因此,这里我们收集了以后解决冲突所需的所有数据。
在受限的物理模拟中,某些对象会影响其他对象的运动,而其他对象则不会。因此,可以将这些对象分为岛,它们是独立的一组身体,可以通过约束力/冲力影响彼此在该组中的运动,但不影响属于其他对象的对象岛屿。因此,所有接触体以及具有连接它们的关节的接触体都合并在一个岛中。
如果启用了物理模拟的 Stable 模式,则在岛内对物体,形状和关节进行分类以确保以预定的顺序解决了接触问题,并且世界上的物理可视化是重复的(在一台计算机)。
碰撞检测使用某些优化方法来减少计算负荷并提高效率(例如,空间划分,岛屿,冻结等)。
碰撞反应#
因此,我们已经获得了有关碰撞的所有必要信息,现在必须对这些信息进行某些操作以提供切合实际的反应。碰撞响应代表模拟两个固体在碰撞后运动的变化。发生碰撞时,两个物体的动力学特性会瞬间变化。典型地,取决于它们的弹性和碰撞的构型,它们彼此反弹,滑动或沉降成静态接触。 Unigine使用基于基于脉冲的反应模型。在碰撞过程中,根据牛顿的作用和反作用原理,第一个物体在与第二个物体施加的冲击大小相等但方向相反的接触点上向第二个物体施加碰撞冲击。
#在此阶段,所有找到的联系人都与前一帧的联系人一起缓存-以确保正确的交互。根据收集的接触点数据,Unigine计算形状通过碰撞得到的脉冲。接触点以伪随机顺序求解,以实现仿真稳定性和可重复性。
关节在接触响应计算过程中得到解决。计算关节给予与之相连的物体的冲动:根据关节的当前状态,物体应如何响应以使关节保持不破裂(即,基于其质量,线速度和角速度,更改其运动方向和方向),以及该响应如何影响关节(过大的脉冲可能会破坏关节)。关节也以伪随机顺序求解。
累积了接触和联合求解的结果并将其应用于实体。物体的坐标根据其新的线性和角速度而变化。
Collison响应计算过程中考虑了两个材料参数,它们可以为 shape 和 surface 设置:
- Restitution-碰撞后保留的相对动能程度。它取决于碰撞体材料的弹性。
- 最小值 0 表示无弹性碰撞(一块软粘土撞击地板)
- 1 的最大值表示高度弹性的碰撞(橡胶球从墙壁上弹起)
- Friction-阻止两个接触表面相对运动的力。值越高,身体滑动的趋势越少。
回调执行#
在仿真阶段之后,将调用所有物理回调。这些回调主要用于创建,销毁或修改其他对象,此类操作只能在主线程中执行。
离散和连续碰撞检测#
关于时间刻度的考虑方式,使用了两种在发生碰撞时查找接触点的基本方法。这两种方法都是在Unigine中实现的。
- 离散冲突检测是在一定时间间隔内执行的,每个帧都与其他帧分开处理。通常,离散化可以提高性能。但是,当项目帧速已经很低时,一个小的快速移动物体很可能会从一个点传送到另一个点,而不是平稳地移动到那一点,并且不会检测到碰撞。
- 连续碰撞检测 不会遇到此问题,因为移动体沿其轨迹(在两个相邻帧之间)被挤压。如果有物体进入该体积并检测到碰撞,则及时收回车身以纠正碰撞反应。
离散检测的主要优点是,对于形状复杂或尺寸较大的对象,它往往会更快,更简单。连续碰撞检测需要对所有对象及其运动以及方程的求解系统进行数学描述,这在许多情况下可能是困难,缓慢甚至是不可能的。
防撞面罩#
为了使冲突检测灵活而有选择性,并降低计算成本,使用了位掩码机制。例如,我们有一个对象,它不参与与其他对象的交互,但是我们希望它位于地面上。使该对象的碰撞位掩码与地面匹配(掩码中的至少一位应匹配)可提供必要的效果。一个对象可以参加多个碰撞检查,因为只需要掩码中的一位即可匹配一对对象。
所有场景对象(如果未配置)都是使用默认的碰撞蒙版创建的,即所有物体都与所有物体碰撞。如果世界上的对象数量很多,这可能会降低性能。此处的最佳做法是确定应该与哪些碰撞。
静态和动态联系人#
基本上有两种类型的联系人:
- 静态,当尸体放在另一个尸体上时。在这种情况下,除非有外力影响物体,否则将其视为“ frozen ”。这样可以避免不必要的计算。
- 动态,当至少有一个正在移动的两个物体碰撞时。在这种情况下,我们必须计算两个碰撞对象的瞬时速度变化。
碰撞实例#
请参阅以下示例,说明冲突检测的几个方面: