Search code examples
three.jscollisionintersectionraycasting

Three.js ray object intersection


friends. Here is my code. It should find intersection of ray and cube. But it does not work and makes me mad. This code is quite simple, but it is hard for me to find the error. Please, help.

jsFiddle

    <script>
        var container;
        var camera, controls, scene, renderer;
        init();
        animate();

        function init() {

            camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.z = 1000;

            controls = new THREE.TrackballControls( camera );

            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 1.2;
            controls.panSpeed = 0.8;

            controls.noZoom = false;
            controls.noPan = false;

            controls.staticMoving = true;
            controls.dynamicDampingFactor = 0.3;

            controls.keys = [ 65, 83, 68 ];

            controls.addEventListener( 'change', render );

            // world

            scene = new THREE.Scene();

            var testObject_G = new THREE.CubeGeometry(100, 100, 100);
            var testObject_M = new THREE.MeshBasicMaterial({ color: 0xBBBBBB });
            var testObject_Mesh = new THREE.Mesh(testObject_G, testObject_M);

    testObject_Mesh.position.x = 300;
    scene.add(testObject_Mesh);

    scene2 = new THREE.Object3D();

    // rays

    var direction = new THREE.Vector3(1, 0, 0);
    direction.normalize();
    var startPoint = new THREE.Vector3(0, 0, 0);

    var ray = new THREE.Raycaster(startPoint, direction); 
    var rayIntersects = ray.intersectObjects(scene.children, true); 
    if (rayIntersects[0]) {
    console.log(rayIntersects[0]);

    var geometry = new THREE.CubeGeometry(10, 10, 10);
    var material = new THREE.MeshBasicMaterial({color: 0xff0000});
    var cube = new THREE.Mesh(geometry, material);
    cube.position = rayIntersects[0].point;
    scene2.add(cube);
    }

    var ray_G = new THREE.Geometry();
      ray_G.vertices.push(new THREE.Vector3(0, 0, 0));
      ray_G.vertices.push(direction.multiplyScalar(1000));
    var ray_M = new THREE.LineBasicMaterial({ color: 0x000000 });
    var ray_Mesh = new THREE.Line(ray_G, ray_M);
    scene2.add(ray_Mesh);

    scene.add(scene2);



            // renderer

            renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setClearColor(0xffffff, 1);
            container = document.getElementById( 'container' );
            container.appendChild( renderer.domElement );



            //

            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth, window.innerHeight );

            controls.handleResize();

            render();

        }

        function animate() {

            requestAnimationFrame( animate );
            controls.update();

        }

        function render() {

            renderer.render( scene, camera );


        }


    </script>

</body>

Thank you very much for replies.


Solution

  • During the render loop, three.js updates each object's transform matrix for you, based on your specified object.position, object.rotation/quaternion, and object.scale.

    Since you are calling Raycaster.intersectObjects() before the first render call, you have to update the object matrices yourself prior to raycasting.

    scene.updateMatrixWorld();
    

    fiddle: http://jsfiddle.net/mzRtJ/5/

    three.js r.64