Three.js進級編の6-衝突検出


最近はThreeを使ってみました.jsは簡単なレーシングカーゲームをしています.中には、レーシングカーが障害物にぶつかったか、奨励品をもらったかなど、2つの物体が衝突したかどうかをどのように判断するかという問題があります.

いくつかの資料を探して、2つのサンプルプログラムを見つけました:第1の例、第2の例. 
以上の2つのプログラムはいずれもTHREE.Raycasterクラスで問題を解決した. 
Raycasterクラス
Raycasterは「光線投射」と訳すべきで、その名の通り、投射された光線である. 
Raycasterのコンストラクション関数は次のとおりです.
Raycaster( origin, direction, near, far ) {

origin —        。
direction —        ,     。
near —            near  。Near    ,    0。
far —            far  。Far      near,       。

Raycasterによる衝突検出
Raycasterを用いて衝突を検出する原理は簡単で,物体の中心を起点として各頂点(vertices)に放射線を発し,その後,放射線が他の物体と交差しているかどうかを調べる必要がある.交差が発生した場合、最も近い交点と放射線の始点間の距離をチェックします.この距離が放射線の始点から物体の頂点までの距離よりも小さい場合は、衝突が発生したことを示します.
この方法には,物体の中心が別の物体の内部にある場合に衝突を検出できないという欠点がある.また、2つの物体が互いに通過し、大きな部分が重なる場合、検出効果も望ましくない. 
もう一つ注意しなければならないのはjsで物体を作成する場合、その頂点(veritces)の数はそのセグメントの数に関連し、セグメントが多ければ多いほど頂点の数が多くなります.検出過程における精度を考慮するためには,物体のセグメントを適切に増やす必要がある. 
光が物体と交差するかどうかを検出するには、intersectObjectまたはintersectObjectsの方法が使用されます.
.intersectObject ( object, recursive )

object  
recursive —     ,           。

交差の結果は、要素が距離に従って並べ替えられた配列で返されます.近いほど前に並べられます.
[ { distance, point, face, faceIndex, indices, object }, ... ]

これにより配列中の要素を処理することで,所望の結果が得られる.intersectObjectsintersectObjectと同様であり、入力されたパラメータが配列である以外に大きな差はない. 
衝突を検出するコードクリップ
/**
 *    :   movingCube       collideMeshList          
 * 
 */
var originPoint = movingCube.position.clone();

for (var vertexIndex = 0; vertexIndex < movingCube.geometry.vertices.length; vertexIndex++) {
    //       
    var localVertex = movingCube.geometry.vertices[vertexIndex].clone();
    //           
    var globalVertex = localVertex.applyMatrix4(movingCube.matrix);
    //             
    var directionVector = globalVertex.sub(movingCube.position);
    
    //         
    var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
    //               
    var collisionResults = ray.intersectObjects(collideMeshList);
    //          ,                       ,      
    if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
        crash = true;   // crash        
    }
}

Three.jsではマトリクスを用いて3 D変換を記録し,各Object 3 Dの例にはマトリクスがあり,位置position,回転rotation,伸縮scaleが格納されている.
var globalVertex = localVertex.applyMatrix4(movingCube.matrix);

このコードは物体のローカル座標に変換行列を乗算し,この物体の世界座標系における値を得,処理後の値こそ我々が必要とする.
サンプルコード
GitHubサンプルコード
Online Demo方向キーを押してブロックを移動し、マウスの左ボタンをクリックしてドラッグして視点を変更します.
転載先:http://www.tuicool.com/articles/bUr2iu6