Skip to main content

One post tagged with "engine"

View All Tags

· 3 min read
Swnb

最近遇到一个很奇怪的问题

我的物理引擎,总是在稳定下来之后一段时间内发生爆炸,效果如下

简单梳理下我的物理引擎的处理流程

  1. 通过GJK算法分析是否碰撞
  2. 通过EPA算法得到碰撞法线和碰撞深度
  3. 通过v_clip算法得到足够多的碰撞点对
  4. 约束

经过排查发现,是EPA 的过程出错了(EPA 算法解析),如果一个Minkowski边已经在原点上了, 那么理论上是无法expand

所以一开始想到的解决方案是,判断 Minkowski 边是否在原点上,或者非常靠近原点,但是无论怎么调整参数,都不行,原因是: 根本无法精准的判定Minkowski 边是否在原点上,计算偏差总是存在的

  1. 如果误判在原点上,那么最终结果肯定是错的
  2. 如果误判不在原点上,继续扩展,因为该边足够靠近原点,得到的指向原点的向量的方向很可能是相反的,该算法就会继续扩展,得到错误的结果

但是理性下来分析,为什么是稳定了一段时间后才会出现这个问题呢?

因为随着物理引擎的约束(持续冲量),系统会不断的逼近稳定的状态,一开始系统内物体之间的碰撞有很大的碰撞深度, 随着系统的持续约束,物体之间的碰撞深度不断的减少,最后逼近 0。这个时候,Minkowski最靠近原点的边就会落在原点上,然后导致计算的偏差, 要想解决这个问题,可以让物体之前保持一个最小的碰撞深度,比如 0.001, 这样就不会出现Minkowski最靠近原点的边落在原点上的情况了

代码如下


_10
let permeate = contact_info.depth - constraint_parameters.max_allow_permeate;

最后的效果如下(不考虑摩擦力)

现在系统就很稳定了