物理エンジンで同時衝突を処理する最良の方法は何ですか?


13

ビデオゲームの物理学についてさらに学ぶために、JavaScriptで2D物理エンジンを書いています。リジッドボディの衝突に対して正しく動作しますが、ボディが同時に2つ以上の他のボディと衝突する場合を除きます。

現在、衝突体の各ペア(A、B)について、衝突インパルスに基づいて速度と角速度を変更し、それらが互いに貫通しないように微調整します。ただし、Aを含む他の衝突の衝突検出とインパルス計算は間違っています。

互いに衝突する3つ以上のオブジェクトに対してエンジンを機能させるためにどのようなアプローチを検討できますか?


2
関連:gamedev.stackexchange.com/questions/15836/…gamedev.stackexchange.com/questions/26181/…そして、もっとあると確信しています。今すぐ見つけることができません。
マイケルハウス

回答:


11

私は次のアプローチを使用します(Tonge http://www.richardtonge.com/の質量分割アルゴリズムに似ています):

  • シーン/コンテキスト内のすべての衝突ペアを検出します。(A、B)をそのようなペアとします。ゴースト/質量分割のアイデアを適用します。AがM個のボディと接触し、BがN個の他のボディと接触している場合、Aの質量をBの質量に一時的に設定m_A/Mします。m_B/N
  • 各ペア(A、B)の反力/反発力の寄与を計算し、これらの寄与をAおよびBのアキュムレーターに保存します
  • インパルスから復元速度を計算し(あなたが述べたように)、それらを同じ方法で(各(A、B)ペアの独自のアキュムレータにdeltaV速度残として)保存します。
  • ペナルティ変位を計算します(再度、変位を蓄積し、それらを即座に適用しないでください!)
    • 衝突ペアのパーティとして以前に指定されたすべてのボディの質量をリセットします(m_A = m_A * Mおよびm_B = m_B * N

このアプローチは、Jacobi反復アルゴリズムが線形連立方程式でどのように機能するかに似ています。そして収束することは保証されていませんが、私のシミュレーターでは、3Dで非常にスムーズに仕事をします(はい、余分な次元は難易度を2倍追加します!)。

警告:衝突の検出/処理段階が終了した後にのみ、位置と速度を修正してください!そうすれば、衝突するアクタを同時に更新できます。また、次に位置と速度を統合するときに、反発力を考慮する必要があります。

編集:まあ、あなたはすでに悪用されているVerlet統合方法を使用していると思います(これはgamedev愛好家の中で一般的な名前になります)。この衝突処理と統合のスペクターでは、こちらをご覧ください

更新:衝突(および実際には自己衝突)に対処する方法に関する情報の一部は、これらのペーパーで見つけることができます。

私が提案したアプローチは、最初からの貢献ではなく、多くのゲームがそれをもっともらしい結果で使用しており、JakobsenのHitmanゲームエンジンで最もよく採用されていました。

やや実用的な経験から、ペナルティ力(貫通距離から入力を取得する線形または指数バネに類似)は、衝突する物体からの他の力がそれらよりも大きい場合、貫通を適切に解決しません。だからこそ、3つの(ほぼ冗長な)アプローチを組み合わせることを選択しました。ニュートン反力(壁を押す、壁を押し戻す)、インパルス由来の速度(スヌーカーボールの衝突)、および非自然な「身体を互いに幾何学的に離す」 " 解決。一緒に彼らはすべてを提供するようだ:ほとんどを取り除くinterい相互侵入アーティファクト、衝突する物体は、長期的には相互作用する傾向があります(反発速度と力により-少なくとも、衝突シナリオで物体を引きずる力は相殺され、物体は互いに跳ね返ります) 。最後に、これらの単純だが一般的な概念をさらに理解するために、これらのスライドを分析することをお勧めします

Verletの統合手順を説明する私の「虐待された方法」の言い回しは、これが統合方法の聖杯であるという一般的な文化の信念を対象としています。シンプレクティックオイラー(半陰的オイラーとも呼ばれます)のいとこよりもわずかに優れています。より複雑な統合方法が存在します(そして、それらすべてに暗黙の名前が付けられています)。強力なゲームエンジンはそれらを利用しますが、特定のシナリオに合わせてVerletが調整されたとき、インディー開発者はそれらを試してみる時間がありません。また、少しの不正行為を伴わずに硬い制約に対処できる統合方法はまったくありません(リンクは見つかりませんが、言及している論文は「X.Provot-"Deformation Constraints in a Mass」と呼ばれるべきです。リジッドクロスの動作を記述するスプリングモデル」


ありがとう(+1)!「反発速度」および「ペナルティ変位」とは何ですか?また、なぜverletの統合は「虐待された」と言うのですか?それは使用するのに悪い方法だと思いますか?
カム

反発速度は、インパルスから得られる速度とまったく同じです。唯一の違いは、それらを剰余として計算することです(つまり、インパルスベースの速度と現在の速度の差を保存し、さらに計算するために現在の速度をそのまま保持します)。ペナルティディスプレイスメントは、2つのオブジェクトが相互貫通する量によって決定される長さを持つベクトルであり、1つのオブジェクトを完全に他のオブジェクトの外に移動できる最小の長さのベクトルです。私は通常、長さを2で割って各オブジェクトにそのような変位を追加します。
テオドロン

1
素晴らしい答えです!しかし、別の質問があります。反発速度を累積すると、それらは非常に非現実的な数になりませんか?オブジェクトAとの各衝突を個別に処理し、各オブジェクトにエフェクトを加算するだけでは、Aのオブジェクト間でインパルスが広がりませんか?代わりに、完全に衝動がそれぞれに適用されますが、直感的には間違っているように思われます
カム

これは非常に良い質問です。ある観点から見ると、結果として生じる速度にインパルスが相加的に寄与していると考えられます。ここに私の(おそらく欠陥がある!)推論があります:3つのプール/スヌーカーボールが衝突することを想像してください。そのうちの1人は、この加算的な方法で他の2人から貢献を受け取る必要があります。最初は、これらの寄与を重み付けして最終速度の加重平均を計算することを考えましたが、迅速な結果を求めていたため、このアイデアをスキップしました。全体として、衝突するボールは残りの2つから速度の寄与を得なければなりません。おそらく、高校の教科書が役立ちます。
テオドロン

3
次の例はまだ私に関係しているので、おそらくあなたが説明したことを理解していないでしょう:水平に長い長方形がまっすぐに落ちて、床がギザギザであると仮定します(複数の隣り合った三角形で構成されている)。n個の三角形がある場合、累積的な方法を使用して、長方形は本来の速度のn倍で跳ね返ります!その状況はどのように修正できますか?
カム

1

速度を変える代わりに、物体に作用するを変えることをお勧めします。それらを「ナッジ」しないでください。むしろ、スムーズに行い、既存のコードを利用してください。これを行うことにより、体は即座に(そして急速に、私が思うに)速度を変えません。

:例えばBox2DJSをチェックしてくださいhttp://box2d-js.sourceforge.net/index2.html


-1

衝突する物体のグループのインパルス方程式を解析的に解きました。私が直面した唯一の問題は、グループ内の連絡先間の相対的な相互作用の強さを見つける変数の欠如でした。

グループの連絡先のソリューションは、単一の連絡先よりもそれほど難しくありません。残念なことに、私は計算で論文を失い、それをここで共有することができませんでした。

編集:おそらく私はこのようなものを思いついた/physics/296767/multiple-colliding-balls

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.