物理引擎 - 阶段顺序和其他一般信息

时间:2014-10-25 09:33:09

标签: collision-detection game-engine physics game-physics physics-engine

我想建立自己的2D迷你物理引擎,包括(现在)僵硬的身体和约束(关节,接触,弹簧......)。 当我开始一个时间步时,我试图弄清楚阶段的正确顺序是什么, 当一般阶段是:宽相,窄相(碰撞检测和接触生成), 分辨率(约束求解器)和积分 - 希望你能告诉我正确的顺序。

我对每个阶段都有一般性问题:

狭窄阶段 - 当我发现碰撞时,我是否需要在发现碰撞后将尸体分开,或者只是在分辨阶段对它们的速度施加冲动?

如果我对某些身体使用CCD(连续碰撞检测),那么如果我发现快速移动的物体A与其他物体B发生碰撞(最早是物体A),那么我会发现在物体碰撞物体A之前,物体B将与其他物体C碰撞,在我找到他的第一次碰撞后,我是否需要回到物体A并寻找其他碰撞?

如果我在我的引擎中使用Contact Solver(在约束求解器中,我将为每次碰撞生成A Contact约束,然后我将解决所有分辨率阶段,或者我将解决每个联系人我发现它们处于狭窄的阶段之后呢?

分辨率 - 在解决阶段使用constaints Solver可以吗? 如果通过解决一个约束我将解决其他约束或制定更多约束怎么办? (如果解决了其他约束或者做出更多限制,我是否需要在解决每个约束后进行检查?

Intefration - 这是我收集所有信息(冲动,力......)并将它们融入速度而不是用我选择的积分方法定位的部分?

对于我的物理引擎来说,辛厄勒整合就足够了吗?

我在许多物理引擎中看到过,比如box2D,他们使用迭代让我选择像这里的频率(注意我可以改变迭代次数(10)和频率(60.0 Hz)):{{0} }

这些变量意味着什么?迭代是我在每一帧中回忆起物理更新(上面的所有阶段)的次数,或者它只是回想起一个阶段,如狭窄阶段或类似的东西? 而频率变量让我选择一秒钟内会有多少帧? 如果我想请你纠正我。

上面的所有问题让我从学习堆栈中学习,因为它的基础知识,而且我没有找到一个可以在干净利落的前沿中解释这些东西的地方

非常感谢能够阅读所有内容的人,尤其是那些也会帮助我解决所有问题的人:)

1 个答案:

答案 0 :(得分:-1)

阶段的顺序并不那么重要。是的,他们互相混乱,但任何失效都可以通过调整常数来纠正......

  1. 入门

    在任何模拟代码之前,您应该从对象表示和可视化开始。您需要能够可视化您的东西,以便您可以看到是否一切正常

  2. 对象类

    所以为你想要支持的所有对象类型创建类,并添加一些基本的接口函数(虚拟基类对于将来的实现是一个好主意),如:

    • load(file,ini,stream...),save(file,ini,stream...)
    • draw(screen or render context),update(dt),bool colide(object)等等......

    及时你会看到你需要添加的内容......现在它们将是空的(而不是你需要编写的绘图......)。您还可以准备一些常见的物理变量(也称为虚拟变量),如位置,速度,温度......

  3. 基类

    它应该是你的引擎的封装。它包含所有对象/东西的列表。主界面有 GUI / App。为了更深入地了解我的意思,现在看Drag&Drop editor in C++,你可以将它作为起点,只需添加物理迭代/更新即可。不要忘记将对象接口实现到这个主类中,如:

    • load(filename) ...加载所有对象
    • draw(...) ...绘制所有对象......
  4. <强>模拟

    仅在上述内容已经有效的情况下才开始。您需要考虑您想要达到的准确性和响应时间。对象/进程越快,您需要的仿真循环频率就越高。对于我的模拟,我通常每次迭代使用1-100 ms。对于非常快速的模拟,您可以在每次定时调用时进行N次迭代。这就是计数频率的含义。如果频率是定时器调用速度,则调用迭代循环并且count(N)是时间步dt除法,因此如果N=10f=60Hz则表示您迭代{{}每10秒{1}}次,因此它与1/60相同,但至少在Windows计时器分辨率为N=1 f=600Hz且不是非常精确的以太。因此,1 ms以上的频率是不可靠的。如果您想要更加精确,可以通过100 HzPerformanceCounter或者您可以使用的任何足够精确的 API 来衡量时间。

    您可以使用 D&#39; Alembert 原则(简单积分)来模拟其余运动的已知方程运动(不知道您要模拟的所有内容)。例如,请查看simple mass points gravity simulation in 3D (C++)

    如果您的代码写得很好,您可以并行化迭代循环,但您必须记住,它可以创建一些麻烦,如双重碰撞反应等

  5. <强>冲突

    SO / SE 上有很多关于此的内容,所以只需搜索它。我想你应该看一下:simulation of particle collisions以了解多次碰撞处理。

  6. 这里有想法是我的模拟之一的样子

    • simple mass points simulation

    它使用我在这里写的所有东西,另外它使用一个特殊的类来表示弹簧或关节等键。这就是它的样子:

    RDTSC

    我可以用这背后的东西覆盖整本书,但是我太懒了,而且这个网站也不适合这个,所以匆忙重要的是每个债券都有它的开始和结束对象指针(struct _bond { physics_point *pnt0,*pnt1; double l0,l1; int _beg0,_end0; int _beg1,_end1; List<int> depend0,depend1; int _computed; _bond() {} _bond(_bond& a) { *this=a; } ~_bond() {} _bond* operator = (const _bond *a) { *this=*a; return this; } //_bond* operator = (const _bond &a) { ...copy... return this; } }; List<_bond> bnds; )并在计算期间填充依赖项列表(pnt0,pnt1)。

    • depend0,depend1来自depend0
    • 的所有后续债券
    • pnt0来自depend1方的所有后续债券。

    然后在每次迭代期间递归更新所有债券以匹配债券/碰撞条件,只有当它们都这样做时,才会立即为所有债券更新头寸。

    • pnt1只是宣布这种关系是正常的(符合条件)。

    其余的只是临时变量,以减轻递归堆/堆栈废弃的负担