在我从零开始编写物理引擎时,理解连续碰撞检测并不是件容易的事,尤其是找到相关资源,因为关于这一主题的实际方面的资源很少。大部分资源都是高度学术化的,针对研究人员。经过几个日子的努力,我终于找到了以下几个关键点。
碰撞检测是一个检测问题,而不是解决问题。这听起来很明显,但是在第一天的最后,我意识到我已经错过了这一点,反而试图同时理解两个方面。所以不要忘记,你正在尝试检测“之间”离散时间步的碰撞,而不是如何应对它。解决问题是之后的事情。
核心思想是将某物投射并找到与另一个物体的交点时间。对于球-球的连续碰撞检测,你需要在时间步中找到碰撞预计发生的时间。可能第一个想到的就是投射一个动态球体到另一个动态球体并找到交点,但这很难解决。所以简化一下:计算两个球体之间的相对速度,将球体B视为静态,将球体A简化为一个点(一条射线)。然后使用Minkowski和,扩展球体B的半径为球体A的半径,得到一个球体C。现在的问题就是射线-球体的交点问题,这很直接。但是,数学给出了参数时间结果,如t = 0表示射线起点,t = 1表示射线距离点的最远点。如果你射出射线从A到B,那么在t = 0时它位于A,在t = 1时它位于B。如果它在某个中点与球体碰撞,则会返回一个t值在[0,1]范围内。这对于我们的物理引擎来说是完全无关紧要的,因为我们需要精确的时间,而不是某种比率来计算精确的碰撞点,并且还需要按时间排序碰撞以避免错误的碰撞解决或出现幽灵碰撞或意外碰撞。所以,我们将t1和t2的交点结果乘以dt。好,我们已经在两个分离的帧中找到了碰撞时间了,但如何管理这个分散的局面?我们使用时间切片!我们在一个帧中:
- 如常应用力或冲击。
- 测试接触。(我们知道到目前为止)
- 现在,我们需要一个接触数组来按时间排序接触。因此,将之前步骤中找到的接触添加到此数组中。
- 排序接触。
- 这里是困难的地方:我们有一些接触和它们将在下一帧发生但在本帧中没有发生的时间,我们需要处理。
- 开始一个时钟。
- 对于每个接触,将所有身体集成到“接触时间”中,并只解决当前接触。将经过的时间添加到时钟中。
- 如果剩余时间(dt - 时钟时间)大于 0,则更新所有身体以使用剩余时间。
嗯,没问题,我不是专家,但我希望这能帮助一点。如果你感兴趣,我正在记录我的3D物理引擎开发之旅在我的开发日志中。https://derkkek.github.io/posts/cacti3d-Physics-Engine/
评论 (0)