web-dev-qa-db-ja.com

オブジェクト間の効率的な衝突検出に最適なアルゴリズム

よくわかりません。混乱しないでください。どのアルゴリズムが最適かを確認するために6つのテストプログラムを実行したくないのと同じくらいです。だから私はここSO=)で専門家の友達に彼らの経験の利点を与えるように頼むと思った.

シナリオは3Dシーンであり、その中にあるオブジェクトのサイズに比べてかなり大きな領域が潜在的に存在します。シーンには何千ものオブジェクトが存在する可能性があります。オブジェクトのサイズは、10分の1ユニットから最大で約10ユニットまでさまざまですが、大きくなる(または小さくなる)ことはありません。オブジェクトは一緒にクラスター化される傾向がありますが、それらのクラスターはシーン内の任意の場所に表示される可能性があります。すべてのオブジェクトは動的で動きます。クラスターは一緒に移動する傾向がありますが、それらが移動するとき、その速度は常に同じではない場合があります。考慮すべき静的なジオメトリもあります。動的オブジェクトは多数ありますが、シーンにはいくつかの静的オブジェクトもあります(静的オブジェクトは動的オブジェクトよりも1桁または2桁大きい傾向があります)。

ここで必要なのは、シーン内のすべてのアイテムの衝突検出を効率的に実行するための空間データ構造です。アルゴリズムがレンダリングパイプラインの可視性クエリもサポートしている場合は、すばらしいでしょう。簡単にするために、ここでの衝突検出はブロードフェーズであると想定します(つまり、すべての動的オブジェクトは完全な球体です)。

したがって、私の研究では、次のいずれかを使用できます。

(1)オクトリー(2)ルーズオクトリー(3)リニアオクトリー(+ルーズ)(4)KDツリー(5)BSPツリー(6)ハッシュ

これまでのところ(6)は私が試した唯一のものです。シーン内のオブジェクトが平均して均等に広がっている場合、実際には速度の点で完全に優れています(私のシステムでは8192アイテムの衝突が1ミリ秒未満でチェックインされています)。すべてのオブジェクトが小さな領域に結合される場合、これはそれほど良いアルゴリズムではありません。

誰がどれを使用するか、または私が物事をスピードアップするために採用できるトリックについて何か洞察がありますか?何が起こっても、静的なジオメトリに別のBSPツリーを使用できると思います。動的な「球」が、ここで私が最も懸念するものだと思います。注:CUDAはありません。これはCPUのみです:p。

ありがとう

編集:わかりました、フローリスのおかげで、AABBツリーに関する詳細情報を見つけました。 GameDevに関する古い議論があります: http://www.gamedev.net/topic/308665-aabb-tree---wheres-the-poly-o_o/ 。良い妥協のように見えます。

最終編集:ホイールを再発明しないことを決定しました。 Bullet Physics Libraryがこれをすべて実行してくれる可能性があります(AABBツリーが含まれており、おそらく非常によく最適化されています)。

42
Robinson

すばらしい質問です。

基本的に、次のような複雑なトレードオフがあります。

  1. 完全な衝突検出フェーズの速度
  2. オブジェクトの移動に伴うデータ構造の更新/維持のオーバーヘッド

悪い知らせは、このため「完全な」答えはないということです-それはあなたの状況に特有の多くの異なる要因に本当に依存します。たとえば、BSPは1の場合は非常に高速です。これは、多くの静的平面ジオメトリで事前計算されると、初期のFPSゲームで非常に普及していた理由を説明しています。

私の個人的な推測では、各最下位レベルのバウンディングボックスに妥当な数のオブジェクト(5〜10?)を含む緩いAABB(Axis Aligned Bounding Box)ツリーがおそらくあなたの場合に最もうまく機能すると思います。理由:

  • オブジェクトのクラスターを含む非常に大きな/疎な空間があります。 AABBツリーは、他の方法では必要となる多くのレベルを切り取ることができるため、これに適している傾向があります。
  • あなたは完璧な球を想定しています。球から球への衝突テストは非常に安価であるため、最下位レベルのノードごとに10-45テストを簡単に実行できます。基本的に、Nの小さな値にはN ^ 2で十分です:-)
  • Axisの配置により、ツリーの更新がはるかに簡単になり、交差テストはほとんどの代替案よりもはるかに安価になります。ほぼ球形のオブジェクトを想定しているので、方向付けされたバウンディングボックスから大きなメリットを得ることはないと思います(面白い角度で長い/細い形状がたくさんある場合にのみ利点があります)。
  • バウンディングボックスが緩くなり、適切な数のオブジェクトが含まれるようにすることで、個々のオブジェクトのモーションがAABB境界の外に出る可能性を減らします。これが発生しない限り、ツリーを更新する必要はありません。これにより、ツリーを更新する時間を大幅に節約できます。その場合は、境界を少しマージンを広げて、すぐに次のフレームを再度拡張する必要がないようにします。ほとんどのモーションは、数フレームの間同じ方向に継続する傾向があることに注意してください。

少し羊毛のような答えで申し訳ありませんが、これがあなたにいくつかの有用なアイデア/考慮すべき事柄を与えることを願っています!

19
mikera

多くの物理エンジンはAABBTree(軸に揃えられたバウンディングボックスツリー)を使用します。それはオブジェクトをより小さな断片に細分します。このアルゴリズムを使用すると、非常に優れた衝突検出を実現できます。この木はオクトリーのように見えます。

OOBBTree(Orientated Bounding Box)は、より良い対応物でしょう。

5
Floris