处理物理引擎中的同时碰撞的最佳方法是什么?


13

我正在用JavaScript编写2D物理引擎,以便可以了解有关视频游戏中物理的更多信息。我可以使它在刚体碰撞中正常工作,除非任何物体同时与两个或多个其他物体碰撞。

目前,对于每对碰撞体(A,B),我会根据碰撞冲量来修改它们的速度和角速度,并将它们相互推开,以使它们不会穿透。但是,对于涉及A的其他碰撞,碰撞检测和脉冲计算将是错误的。

我可以探索什么方法来使我的引擎针对3个以上的对象相互碰撞而工作?


2
相关:gamedev.stackexchange.com/questions/15836/…gamedev.stackexchange.com/questions/26181/…而且我敢肯定还有更多,我只是现在找不到。
MichaelHouse

Answers:


11

我使用以下方法(类似于Tonge的质量拆分算法http://www.richardtonge.com/):

  • 检测场景/上下文中的所有碰撞对。令(A,B)为此类。应用重影/质量分裂的想法:如果A与M个物体接触,而B与N个其他物体接触,则将A的质量暂时设置m_A/M为B并将B 的质量暂时设置为m_B/N
  • 计算每对(A,B)的反作用力/恢复力贡献并将这些贡献存储在A和B自己的累加器中
  • 计算脉冲的恢复速度(如您所述),并以相同的方式存储它们(对于每对(A,B),将delV速度残差存储在自己的累加器中)
  • 计算惩罚位移(再次,累积位移,不要立即应用!)
    • 重设先前在碰撞对(m_A = m_A * Mm_B = m_B * N)中指定为当事方的所有物体的质量

这种方法类似于Jacobi迭代算法与线性联立方程组一起工作的方式。它并不能保证收敛,但是在我的模拟器中它可以非常顺利地完成工作。.在3D中(是的,额外的尺寸会增加两倍的难度!)。

注意:只有在碰撞检测/处理阶段结束后才能正确定位位置和速度!这样,您就可以同时更新碰撞的演员。此外,下次整合位置和速度时,必须考虑恢复原动力。

编辑:好吧,我想您正在使用已经滥用的Verlet集成方法(这已成为gamedev爱好者的家喻户晓的名字)。在这种冲突处理和集成的幽灵中,您可能想在这里看看。

更新:可以在以下论文中找到一些有关如何进行碰撞(实际上是自碰撞)的信息:

我提出的方法远不是最初的贡献,很多游戏使用它的效果似乎都是合理的,Jakobsen最好在他的Hitman游戏引擎中采用这种方法。

根据一些实际经验,当来自碰撞物体的其他力设法大于它们时,惩罚力(类似于线性或指数弹簧从穿透距离获取输入)不能正确解决穿透。这就是为什么我选择组合三种(几乎是多余的)方法的原因:牛顿反作用力(推壁,壁推回),脉冲推导的速度(斯诺克球碰撞)和非自然的“使几何体相互远离解决方案。他们在一起似乎可以提供一切:摆脱大多数从长远来看,相互穿透的物体很丑陋,碰撞的物体往往会相互影响(由于恢复速度和作用力-至少抵消了在碰撞情况下趋向于拖拽物体的力,并且物体彼此弹开了) 。最后,为了进一步理解这些简单但通用的概念,我建议分析这些幻灯片

我描述Verlet集成步骤的“滥用方法”的用语是针对一种普遍的文化信念,即这是集成方法的圣杯。它仅比其辛欧拉表亲(也被某些半隐式欧拉称呼)堂兄更好。存在更复杂的集成方法的方式(并且所有方法都具有隐式名称)。强大的游戏引擎可以使用它们,但是独立开发人员没有时间去尝试这些功能,因为Verlet在调整到特定场景后确实能带来奇迹。同样,绝对没有一种可以在没有一点作弊的情况下处理严格约束的集成方法(找不到链接,但是我要引用的论文应该称为“ X.Provot-”变形约束刚性布行为的弹簧模型”


谢谢(+1)!什么是“恢复速度”和“惩罚位移”?另外,为什么说Verlet集成被“滥用”?您是否认为使用方法不好?
凸轮

恢复速度恰好是您从脉冲中获得的速度,唯一的区别是我将它们计算为残差(即,我存储了基于脉冲的速度和当前速度之间的差异,同时保持当前速度不变以进行进一步的计算)。罚点位移是长度由两个对象互穿多少确定的向量,而最小长度向量可以将一个对象完全平移到另一个对象之外。我通常将这样的位移添加到每个对象的长度除以2)中。
teodron

1
辉煌的答案!我还有一个问题。说我积累了赔偿速度,难道它们加起来不是一个非常不现实的数字吗?如果我将与对象A的每次碰撞分开处理,然后将每个对象的效果加起来,A不会在对象之间散布其冲力吗?取而代之的是,将所有的冲动都施加到每个直觉上对我来说都是错的
凸轮

从一个角度来看,这是一个非常好的问题。从某种角度看,脉冲对速度的累加贡献似乎是合理的。这是我的(也许是错误的!)推理:想象三个撞球/斯诺克球碰撞。其中一个应以这种加法方式从其他两个中获得贡献。最初,我考虑过权衡这些贡献并计算最终速度的加权平均值,但是由于我想获得快速的结果,因此我跳过了这个想法。总而言之,碰撞的球必须从其余两个球中获得速度贡献。也许一本高中的课本可以帮上忙。
teodron

3
也许我不明白您的解释,因为以下示例仍然与我有关:考虑一个水平长的矩形笔直向下下落,并假设地板呈锯齿状(因此由多个并排的三角形组成)。如果有n个三角形,则使用您的累积方法,矩形将以应有的n倍的速度弹回!如何解决这种情况?
凸轮

1

我建议不要改变速度,而要改变作用在物体上的。不要“轻推”它们,而是要平稳地利用现有代码进行操作。通过这样做,身体不会立即(我想很快)改变它们的速度。

查看Box2DJS的示例:http ://box2d-js.sourceforge.net/index2.html 。


-1

我已经分析了一组碰撞体的脉冲方程。我面临的唯一问题是缺少变量来查找组中各个联系人之间的相对交互强度,而我已经充满了实体交点的深度。

组联系人的解决方案比单触点难得多。不幸的是,我丢失了一份包含计算结果的论文,因此无法在此处共享。

编辑:可能我想出了这样的东西/physics/296767/multiple-colliding-balls

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.