最近遇到一个很奇怪的问题
我的物理引擎,总是在稳定下来之后一段时间内发生爆炸,效果如下 
简单梳理下我的物理引擎的处理流程
- 通过
GJK算法分析是否碰撞 - 通过
EPA算法得到碰撞法线和碰撞深度 - 通过
v_clip算法得到足够多的碰撞点对 - 约束
经过排查发现,是EPA 的过程出错了(EPA 算法解析),如果一个Minkowski边已经在原点上了, 那么理论上是无法expand的
所以一开始想到的解决方案是,判断 Minkowski 边是否在原点上,或者非常靠近原点,但是无论怎么调整参数,都不行,原因是:
根本无法精准的判定Minkowski 边是否在原点上,计算偏差总是存在的
- 如果误判在原点上,那么最终结果肯定是错的
- 如果误判不在原点上,继续扩展,因为该边足够靠近原点,得到的指向原点的
向量的方向很可能是相反的,该算法就会继续扩展,得到错误的结果
但是理性下来分析,为什么是稳定了一段时间后才会出现这个问题呢?
因为随着物理引擎的约束(持续冲量),系统会不断的逼近稳定的状态,一开始系统内物体之间的碰撞有很大的碰撞深度,
随着系统的持续约束,物体之间的碰撞深度不断的减少,最后逼近 0。这个时候,Minkowski最靠近原点的边就会落在原点上,然后导致计算的偏差,
要想解决这个问题,可以让物体之前保持一个最小的碰撞深度,比如 0.001, 这样就不会出现Minkowski最靠近原点的边落在原点上的情况了
代码如下
_10let permeate = contact_info.depth - constraint_parameters.max_allow_permeate;
最后的效果如下(不考虑摩擦力)

现在系统就很稳定了