0

Ray intersect を使用して、2 つの collada オブジェクトが衝突するかどうかを調べようとしています。しかし、これまでのところ成功していません:(

私のコードhttp://jsfiddle.net/XqQzF/

        object.updateMatrix();

        // ray
        var f_vector = new THREE.Vector3( 0, 0, -1 );
        var b_vector = new THREE.Vector3( 0, 0, 1 );
        var l_vector = new THREE.Vector3( -1, 0, 0 );
        var r_vector = new THREE.Vector3( 1, 0, 0 );

最新の three.js リビジョンから削除されたものを使用するたびに。途中で手伝ってくれませんか?

4

2 に答える 2

0

最近、three.jsのexamplesコレクションを最新バージョン(執筆時点ではv56)と互換性があるように更新しました。これには、衝突検出の例が含まれています。http://stemkoski.github.com/Three.js/Collision-Detection.htmlを確認してください(手順については、 http://stemkoski.github.com/Three.js/#collision-detectionを参照してください)。

この場合の主な違いは、モデルの中心点を光線の原点として選択することと、光線が衝突検出に使用されるため、光線の終点として使用するモデルの頂点のセットを選択することです。

お役に立てれば!

于 2013-03-12T21:52:58.883 に答える
0

collada データを使用しない場合、@Lee Stemkoski の回答は問題ありません。最初に私が知っているのは、最小が必要だということです。2 メッシュ オブジェクト。そこで、すべてのメッシュ オブジェクトを collada オブジェクトから取得しました。私は 2 つのスクリプトを書きました。最初に 2 つの collada オブジェクトを衝突させてみました。次に、collada オブジェクトを壁 (単純なメッシュ) に衝突させようとしました。どちらの場合も、スクリプトは衝突を認識しません。では、どのように書けばよいのでしょうか。最後に、collada オブジェクトでマウスを検出しようとしました。本題ではありませんが、似たような問題なのでここに書きます。Dae ファイルは、SketchUp によって生成されました。

2 つの collada オブジェクトのコード:

 var container;
 var meshs = [];
 var camera, scene, renderer, raycaster;
 var controls;
 var mouse = new THREE.Vector2();
 var dae, dae2;
 var collidableMeshList = [];
 var clock = new THREE.Clock();
 var keyboard = new THREEx.KeyboardState();

 $(document).ready(function() {
     init();
     animate();
 });

 function init() {

     container = document.createElement('div');
     $('.container').append(container);

     camera = new THREE.PerspectiveCamera(45, 500 / 500, 1, 1000);
     group = new THREE.Group();

     scene = new THREE.Scene();

     scene.add(camera);

     camera.position.set(10 * 10, 12 * 10, 16 * 10);

     camera.lookAt(scene.position);

     // Lights

     group.add(new THREE.AmbientLight(0x777777));

     var light = new THREE.DirectionalLight(0xdfebff, 1.25);
     light.position.set(300, 400, 50);
     light.position.multiplyScalar(1.3);

     light.castShadow = true;

     group.add(light);

     renderer = new THREE.WebGLRenderer({
         antialias: true
     });

     renderer.setClearColor(0xcccccc, 1);

     renderer.setSize(500, 500);

     container.appendChild(renderer.domElement);

     controls = new THREE.OrbitControls(camera, renderer.domElement);

     var loader = new THREE.ColladaLoader();
     loader.options.convertUpAxis = true;
     loader.load('./sample.dae', loadDae);

     function loadDae(collada) {
         dae = collada.scene;

         dae.scale.x = 0.5;
         dae.scale.y = 0.3;
         dae.scale.z = 0.3;
         dae.updateMatrix();

         group.add(dae);
     }

     var wallGeometry = new THREE.CubeGeometry(10, 10, 20, 1, 1, 1);
     var wallMaterial = new THREE.MeshBasicMaterial({
         color: 0x8888ff
     });
     var wireMaterial = new THREE.MeshBasicMaterial({
         color: 0x000000,
         wireframe: true
     });

     loader = new THREE.ColladaLoader();
     loader.options.convertUpAxis = true;
     loader.load('./sample.dae', loadDae2);

     function loadDae2(collada) {
         dae2 = collada.scene;

         dae2.scale.x = 0.5;
         dae2.scale.y = 0.3;
         dae2.scale.z = 0.3;
         dae2.updateMatrix();

         dae2.position.set(-40, 0, 0);

         dae2.traverse(function(child) {
             if (child instanceof THREE.Mesh) {
                 collidableMeshList.push(child);
             }
         });
         group.add(dae2);
     }

     group.translateX(-20);
     scene.add(group);

     raycaster = new THREE.Raycaster();

     window.addEventListener('resize', onWindowResize, false);
     window.addEventListener('mousemove', onDocumentMouseMove, false);
 }

 function onDocumentMouseMove(event) {

     event.preventDefault();

     mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
     mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

 }

 function onWindowResize() {

     camera.aspect = 500 / 500;
     camera.updateProjectionMatrix();

     renderer.setSize(500, 500);
 }

 function update() {
     var delta = clock.getDelta();
     var moveDistance = 200 * delta;
     var rotateAngle = Math.PI / 2 * delta;

     if (keyboard.pressed("A"))
         dae.rotation.y += rotateAngle;
     if (keyboard.pressed("D"))
         dae.rotation.y -= rotateAngle;

     if (keyboard.pressed("left"))
         dae.translateX(-moveDistance);
     if (keyboard.pressed("right"))
         dae.translateX(moveDistance);
     if (keyboard.pressed("up"))
         dae.translateZ(-moveDistance);
     if (keyboard.pressed("down"))
         dae.translateZ(moveDistance);

     meshs = [];
     if (typeof dae !== 'undefined') {
         dae.traverse(function(child) {
             if (child instanceof THREE.Mesh) {
                 meshs.push(child);
             }
         });
         $.each(meshs, function(number_mesh, mesh) {
             var originPoint = mesh.position.clone();

             for (var vertexIndex = 0; vertexIndex < mesh.geometry.vertices.length; vertexIndex++) {
                 var localVertex = mesh.geometry.vertices[vertexIndex].clone();
                 var globalVertex = localVertex.applyMatrix4(mesh.matrix);
                 var directionVector = globalVertex.sub(mesh.position);

                 var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
                 var collisionResults = ray.intersectObjects(collidableMeshList);
                 if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
                     console.log(" Hit ");
                 }
             }
         });
     }
     controls.update();
 }

 function animate() {

     requestAnimationFrame(animate);
     render();
     update();

 }

 function render() {

     renderer.render(scene, camera);

 }

コラーダ + 壁 (メッシュ) のコード:

var container;
var meshs = [];
var camera, scene, renderer, raycaster;
var controls;
var mouse = new THREE.Vector2();
var dae;
var collidableMeshList = [];
var clock = new THREE.Clock();
var keyboard = new THREEx.KeyboardState();

$(document).ready(function() {
    init();
    animate();
});

function init() {

    container = document.createElement('div');
    $('.container').append(container);

    camera = new THREE.PerspectiveCamera(45, 500 / 500, 1, 1000);
    group = new THREE.Group();

    scene = new THREE.Scene();

    scene.add(camera);

    camera.position.set(10 * 10, 12 * 10, 16 * 10);

    camera.lookAt(scene.position);

    // Lights

    group.add(new THREE.AmbientLight(0x777777));

    var light = new THREE.DirectionalLight(0xdfebff, 1.25);
    light.position.set(300, 400, 50);
    light.position.multiplyScalar(1.3);

    light.castShadow = true;

    group.add(light);

    renderer = new THREE.WebGLRenderer({
        antialias: true
    });

    renderer.setClearColor(0xcccccc, 1);

    renderer.setSize(500, 500);

    container.appendChild(renderer.domElement);

    controls = new THREE.OrbitControls(camera, renderer.domElement);

    var loader = new THREE.ColladaLoader();
    loader.options.convertUpAxis = true;
    loader.load('./sample.dae', loadDae);

    function loadDae(collada) {
        dae = collada.scene;

        dae.scale.x = 0.5;
        dae.scale.y = 0.3;
        dae.scale.z = 0.3;
        dae.updateMatrix();

        group.add(dae);
    }

    var wallGeometry = new THREE.CubeGeometry(10, 10, 20, 1, 1, 1);
    var wallMaterial = new THREE.MeshBasicMaterial({
        color: 0x8888ff
    });
    var wireMaterial = new THREE.MeshBasicMaterial({
        color: 0x000000,
        wireframe: true
    });

    var wall = new THREE.Mesh(wallGeometry, wallMaterial);
    wall.position.set(-40, 5, -10);
    group.add(wall);
    collidableMeshList.push(wall);
    var wall = new THREE.Mesh(wallGeometry, wireMaterial);
    wall.position.set(-40, 5, -10);
    group.add(wall);

    group.translateX(-20);
    scene.add(group);

    raycaster = new THREE.Raycaster();

    window.addEventListener('resize', onWindowResize, false);
    window.addEventListener('mousemove', onDocumentMouseMove, false);
}

function onDocumentMouseMove(event) {

    event.preventDefault();

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

}

function onWindowResize() {

    camera.aspect = 500 / 500;
    camera.updateProjectionMatrix();

    renderer.setSize(500, 500);
}

function update() {
    var delta = clock.getDelta();
    var moveDistance = 200 * delta;
    var rotateAngle = Math.PI / 2 * delta;

    if (keyboard.pressed("A"))
        dae.rotation.y += rotateAngle;
    if (keyboard.pressed("D"))
        dae.rotation.y -= rotateAngle;

    if (keyboard.pressed("left"))
        dae.translateX(-moveDistance);
    if (keyboard.pressed("right"))
        dae.translateX(moveDistance);
    if (keyboard.pressed("up"))
        dae.translateZ(-moveDistance);
    if (keyboard.pressed("down"))
        dae.translateZ(moveDistance);

    meshs = [];
    if (typeof dae !== 'undefined') {
        dae.traverse(function(child) {
            if (child instanceof THREE.Mesh) {
                meshs.push(child);
            }
        });
        $.each(meshs, function(number_mesh, mesh) {
            var originPoint = mesh.position.clone();

            for (var vertexIndex = 0; vertexIndex < mesh.geometry.vertices.length; vertexIndex++) {
                var localVertex = mesh.geometry.vertices[vertexIndex].clone();
                var globalVertex = localVertex.applyMatrix4(mesh.matrix);
                var directionVector = globalVertex.sub(mesh.position);

                var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
                var collisionResults = ray.intersectObjects(collidableMeshList);
                if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
                    console.log(" Hit ");
                }
            }
        });
    }
    controls.update();
}

function animate() {

    requestAnimationFrame(animate);
    render();
    update();

}

function render() {

    renderer.render(scene, camera);

}

collada オブジェクト上のマウスを検出します。ショートコードバージョン:

var meshs = [],
    raycaster,
    mouse = new THREE.Vector2();
...
function init() {
    ...
    function loadDae(collada) {
        dae = collada.scene;
        dae.scale.x = 0.5;
        dae.scale.y = 0.3;
        dae.scale.z = 0.3;
        dae.updateMatrix();
        group.add(dae);
        dae.traverse(function(child) {
            if (child instanceof THREE.Mesh) {
                meshs.push(child);
            }
        });
    }

    var loader = new THREE.ColladaLoader();

    loader.options.convertUpAxis = true;
    loader.load('./sample.dae', loadDae);
    raycaster = new THREE.Raycaster();
    window.addEventListener('mousemove', onDocumentMouseMove, false);
    ...
}
...
function onDocumentMouseMove(event) {

    event.preventDefault();

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

}

function render() {
    raycaster.setFromCamera(mouse, camera);

    if (group.children.length === 5) {
        var intersects = raycaster.intersectObjects(meshs);

        if (intersects.length > 0) {
            console.log(" Hit ");
        }
    }
    renderer.render(scene, camera);
}
...

一般 - はい、動作しますが、一部の $meshs でエラーがスローされます。

TypeError: undefined はオブジェクトではありません ('O' を評価)

three.min.js:8304
cthree.min.js:3544
intersectObjectsthree.min.js:3609:144

intersectObjects に対して正しいメッシュとそうでないメッシュを認識する理由と方法

于 2016-02-04T18:06:00.580 に答える