2D物理エンジンで、オブジェクトが静止したときに不要な衝突解決を回避するにはどうすればよいですか?


9

love-2dを使用して(学習用に)開発している物理エンジンで、衝突解決を次のように実装しました。

FixedUpdate(dt)  // I use fixed timestep
 foreach collide c1 in allNotStaticColliders
   c1.integartePhysic // i.e. apply gravitational force..
   foreach collider c2 "near" c1 // "near"= I use spatial hashing 
      if collide(c1,c2)
        resolve collision (c1,c2)  // the heavy operation
        collison callbacks c1
        collison callbacks c2
        ...

落下して停止するオブジェクトのアニメーション

gifアニメーションの最後にあるように、すべてのコライダーが静的オブジェクトにほぼ固定されている場合は、FPSの減衰があります。

2 FPSの最終的な静的状態

これは、オブジェクトが落ち着くまでの接触時間を長くすると、衝突解決の数が増えるためです。ただし、オブジェクトはすでに互いに安定した位置に落ち着いているため、計算の多くは「役に立たない」ものです。

これらの「役に立たない」衝突検出を回避するためのベストプラクティスは何ですか(できれば物理学の学位を必要としないでしょう)。

編集:DMGregoryのヒントを受け入れ、この結果になります(まだ最適ではありません)

ここに画像の説明を入力してください

(赤=静的、青=アクティブ、緑=スリープ)


1
通常のアプローチは、静止したオブジェクトを「スリープ」し、スリープ/静的オブジェクト間の相互作用を考慮しないことです(ただし、スリープオブジェクトは、まだ起きていて動いている動的オブジェクトからの相互作用によって引き続き起こされます)。残念ながら、これはオブジェクトが完全に静止したときにのみ役立ちます。私があなたの例を正しく読んでいる場合、オブジェクトがまだ落ち着いて少し動いているときにパフォーマンスの問題が発生するようです。ここで私ができると思うことは、システムに摩擦/ダンピングを追加することです(おそらく速度しきい値を使用)。これにより、小さな動きがより速く本当の静止に減衰します。
DMGregory

@DMGregoryいい答えですね。追加しますか?
あんこ

回答:


9

OPがこのアプローチをすでに知っているのではないかと思ったので、コメントでそれを単なる出発点として述べましたが、もう少し具体化してみます...

ほとんどの物理エンジンは、動的オブジェクトを「覚醒」と「睡眠」の2つのグループに分けます。

オブジェクトは、休んでいるときに眠り、移動したり、外部の影響によって加速したりすると目を覚まします。

睡眠オブジェクトのほとんどの点で、静的オブジェクトのように振る舞う-その動きが(それは安静時だから、それは何の動きを持っていないので、)時間積分とエンジンが眠っているオブジェクトまたは静的間の衝突を無視されていません。

重力を含む睡眠オブジェクトのすべての動きの統合がスキップされるため、衝突応答がないにもかかわらず、静止床に座っている睡眠オブジェクトは、床を通り抜けません。

したがって、少なくとも1つのアウェイクダイナミックオブジェクトを含む衝突のみをチェックする必要があります。

Collisions    Static          Sleeping           Awake
          ------------------------------------------------
Awake     |    Check        Check & Wake         Check
Sleeping  |     No               No
Static    |     No

これにより、アクティブなシミュレーションを必要とするオブジェクトの数を劇的に減らすことができます。特に、質問に示されているように、相互の衝突が多く、ネットの動きがほとんどないか、まったくないかを確認する杭の場合です。

睡眠は、オブジェクトが実際安静に達したときにのみ役立ちます。

休息を早めるためにできること:

  • ゼロ以外の最小速度または運動量を持ち、それを下回るものはすべてゼロにクランプします。(これは基本的にイプシロンであり、フロートの比較で一般的に使用されます)

  • 摩擦、減衰、非弾性衝突を使用して、システムからエネルギーを吸収し、全体的により速く休息に到達できるようにします。

  • 動きの遅いオブジェクトに対して選択的に摩擦/ダンピング/非弾性を増やして、よりエネルギッシュなボディの動作に影響を与えずに、最終的なナッジをそれらに与えます。


いい答えです。あなたは良いアイデアの束を指摘します。睡眠/覚醒のチェックでは、2つの弱点があります。2)眠っているオブジェクトの下にある静的プラットフォームを削除しても、そのオブジェクトは(重力の下で)起こらない
dnk drone.vs.drones

1
@ dnkdrone.vs.drones良い観察。自分で物理エンジンを作成したことがないので、これが通常どのように処理されるかはわかりません。1つの可能性は、オブジェクトをスリープ状態に設定するときに、接触しているオブジェクトのリストを保存する(またはオブジェクトのローカルクラスタに追加する)ことです。眠っているオブジェクトを起こすと、そのリスト/クラスター内のすべても起こします。目覚めた瞬間(離れる前)に近くの連絡先をチェックするなど、よりエレガントなオプションがあるかもしれません。
DMGregory
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.