Question

I am trying to use Ray intersect to find out if 2 collada object collide. But so far no success :(

my code 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 );

everytime i use something its removed from the newest three.js revision. Can you help me on the way ?

Was it helpful?

Solution

I recently update my three.js examples collection to be compatible with the latest version (v56 at time of writing), and this includes an example of collision detection. Check out http://stemkoski.github.com/Three.js/Collision-Detection.html (see http://stemkoski.github.com/Three.js/#collision-detection for instructions).

The main difference in your case will be choosing a central point of your model as an origin point for the rays, and choosing a set of vertices of your model to use as endpoints for the rays, as rays are what is used for collision detection.

Hope this helps!

OTHER TIPS

@Lee Stemkoski answer is ok, when we doesn't use collada data. First what I know is that we need min. 2 Mesh objects. So I took all Mesh objects from collada object. I wrote two scripts - first tried colliding 2 collada objects. Second tried to collide collada object with wall(simple Mesh). In both cases script it doesn't recognize colliding 😕. So how i should write it? At last I tried to detect mouse on collada object. It's not about this topic but it's similar problem so I write it here. Dae file was generated by SketchUp.

Code for two collada objects:

 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);

 }

Code for collada + wall(Mesh):

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);

}

Detect mouse on collada object. Short code version:

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);
}
...

General - yes, it works, but throw errors with some $meshs 😕.

TypeError: undefined is not an object (evaluating 'O')

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

Why and how to recognize which mesh is correct for intersectObjects and which not?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top