web-dev-qa-db-ja.com

three.jsで衝突を検出する方法は?

Three.jsを使用しています。

シーンに2つのメッシュジオメトリがあります。

これらのジオメトリが交差している場合(または交差する場合変換される場合)、これを衝突として検出したい。

Three.jsで衝突検出を実行するにはどうすればよいですか? three.jsに衝突検出機能がない場合、three.jsと組み合わせて使用​​できる他のライブラリはありますか?

41
eqiproo

Three.jsでは、ユーティリティCollisionUtils.jsおよびCollisions.jsはサポートされなくなったようです。mrdobb(three.jsの作成者)自身がthree.jsの最新バージョンに更新し、この目的でRayクラスを使用することをお勧めします。代わりに。以下は、そのための1つの方法です。

アイデアは次のとおりです。「Player」と呼ばれる特定のメッシュが、「collidableMeshList」と呼ばれる配列に含まれるメッシュと交差するかどうかを確認するとします。できることは、プレーヤーメッシュ(Player.position)の座標から始まり、プレーヤーメッシュのジオメトリの各頂点に向かって伸びる一連のレイを作成することです。各Rayには、「intersectObjects」と呼ばれるメソッドがあり、Rayが交差したオブジェクトの配列と、これらの各オブジェクトまでの距離(RayのOriginから測定)を返します。交差点までの距離がプレイヤーの位置とジオメトリの頂点の間の距離よりも小さい場合、プレイヤーのメッシュの内部で衝突が発生しました。これはおそらく「実際の」衝突と呼ばれます。

私は実際の例を投稿しました:

http://stemkoski.github.io/Three.js/Collision-Detection.html

赤いワイヤフレームキューブを矢印キーで移動し、W/A/S/Dで回転できます。青い立方体の1つと交差すると、上記のように、交差点ごとに「ヒット」という単語が画面の上部に1回表示されます。コードの重要な部分は次のとおりです。

for (var vertexIndex = 0; vertexIndex < Player.geometry.vertices.length; vertexIndex++)
{       
    var localVertex = Player.geometry.vertices[vertexIndex].clone();
    var globalVertex = Player.matrix.multiplyVector3(localVertex);
    var directionVector = globalVertex.subSelf( Player.position );

    var ray = new THREE.Ray( Player.position, directionVector.clone().normalize() );
    var collisionResults = ray.intersectObjects( collidableMeshList );
    if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) 
    {
        // a collision occurred... do something...
    }
}

この特定のアプローチには2つの潜在的な問題があります。

(1)光線の原点がメッシュM内にある場合、光線とMの間の衝突結果は返されません。

(2)(Playerメッシュに対して)小さいオブジェクトがさまざまなレイ間で「スリップ」する可能性があるため、衝突は登録されません。この問題の可能性を減らすための2つの可能なアプローチは、小さなオブジェクトが光線を作成し、それらの視点から衝突検出の努力をするか、メッシュ上のより多くの頂点を含むようにコードを書くことです(例:CubeGeometry(100、100、100、 20、20、20)CubeGeometry(100、100、100、1、1、1)ではなく。)後者のアプローチはおそらくパフォーマンスに影響を与えるため、控えめに使用することをお勧めします。

他の人がこの質問に対する彼らの解決策でこの質問に貢献することを願っています。ここで説明するソリューションを開発する前に、私はかなり苦労しました。

96
Lee Stemkoski

これは実際にはSOの質問でカバーするにはあまりにも広すぎるトピックですが、サイトのSEOに少し油をさすために、ここにいくつかの簡単な出発点があります。

完全な物理エンジンではなく、本当に簡単な衝突検出が必要な場合は、 Three.js:Simple Collision Detection をチェックしてください。

一方、「A and B bumpd」だけでなく、何らかの衝突応答が必要な場合は、 Physijs を見てください。これは、Ammo.jsラッパーが非常に使いやすく構築されていますThree.js

5
Toji