4

I wrote the code below to get intersection point with a 3d shape. It works well but if there are two intersection point with shape, it returns me only the farest intersection while I need the nearest intersection with the shape. How can I do to get the nearest intersection?

  /*here I create a cube*/

            var geometry0 = new THREE.Geometry()
            geometry0.vertices = [new THREE.Vector3(0.5, -0.5, 0.5), new THREE.Vector3(-0.5, -0.5, 0.5), new THREE.Vector3(-0.5, -0.5, -0.5), new THREE.Vector3(0.5, -0.5, -0.5), new THREE.Vector3(0.5, 0.5, 0.5), new THREE.Vector3(-0.5, 0.5, 0.5), new THREE.Vector3(-0.5, 0.5, -0.5), new THREE.Vector3(0.5, 0.5, -0.5)];
            geometry0.faces = [new THREE.Face3(3, 2, 1), new THREE.Face3(3, 1, 0), new THREE.Face3(4, 5, 6), new THREE.Face3(4, 6, 7), new THREE.Face3(0, 1, 5), new THREE.Face3(0, 5, 4), new THREE.Face3(1, 2, 6), new THREE.Face3(1, 6, 5), new THREE.Face3(2, 3, 7), new THREE.Face3(2, 7, 6), new THREE.Face3(3, 0, 4), new THREE.Face3(3, 4, 7)];
            geometry0.computeFaceNormals();
            geometry0.computeVertexNormals();
            var material0 = new THREE.MeshBasicMaterial({color: 0x39d2dbe7fff39d2, transparent: true, opacity: 0});
            mesh0 = new THREE.Mesh(geometry0, material0);
            egh0 = new THREE.EdgesHelper(mesh0, 0x000);
            egh0.material.linewidth = 2;
            scene.add(egh0);


            objects.push(mesh0);
            projector = new THREE.Projector();
            console.log(objects);
            mouse2D = new THREE.Vector3(0, 10000, 0.5);//controllare i valori



    /* here I create the ray */


document.addEventListener('click', onDocumentMouseClick, false);


        function onDocumentMouseClick(event) {

            event.preventDefault();

            mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
             var vector = new THREE.Vector3( mouse2D.x, mouse2D.y, 0.5 );

            projector.unprojectVector( vector, camera );

            var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );


            var intersects = raycaster.intersectObjects( objects );

            if (intersects.length > 0) {
                console.log("ok");} 

If I check intersects[0].point I can only see the farest point face of cube intersected and not the first (for example,if you look at a cube in front of you and make a ray,this ray before intersect the first face and after intersect second face behind the first.) The goal of this code is to create an event only when you click on vertices. So after this I wrote code to calculate the euclidean distance from point of click and all vertices and return the vertice nearest to the point of click. If you have other idea to fire an event only when you click on vertices is welcome.

Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76
Stefano Maglione
  • 3,946
  • 11
  • 49
  • 96

2 Answers2

5

Yes, the basic idea of ray casting is that we project a ray perpendicular to the plane we find out the list of objects that the ray has intersected.

So all you have to do to access the first element is adding the following piece of code.

var intersects = raycaster.intersectObjects(objects);

if (intersects.length > 0) {
       var firstIntersectedObject  = intersects[0];
       // this will give you the first intersected Object if there are multiple.
    }

Here is one of my other SO post in which I have explained things in a bit more detailed way, you can refer it to better understand how raycasting functions.

Community
  • 1
  • 1
Shiva
  • 6,677
  • 4
  • 36
  • 61
  • I have already used intersects[0] but if I have for example a cube, a ray intersects first the cube face nearest to me and after intersect the farest face of cube and return me only the intersection point with the farest face. @Shiva – Stefano Maglione Oct 15 '14 at 09:53
  • @StefanoMaglione: Please include this part of code too in the question ... so we can find what is going wrong there. – Shiva Oct 15 '14 at 10:49
  • I tried to log the distance like this `console.log(intersects[0].distance);` seems to be working fine to me – Shiva Oct 15 '14 at 11:26
  • If you look at the point properties you can see that if you click on first face it will return you coordinates of face behind the first. I think I have to avoid this solution. Could I ask you some idea to fire an event only on clicking on vertices?Thanks. @Shiva – Stefano Maglione Oct 15 '14 at 11:34
0

Try to make through this example. Look at messages in the console.

<script src="js/controls/EventsControls.js"></script>

EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.draggable = false;

EventsControls.onclick = function() {

       console.log( this.focused.name );
       console.log( 'this.focusedPoint: (' + this.focusedPoint.x + ', ' +
                     this.focusedPoint.y + ', ' + this.focusedPoint.z + ')' );
       console.log( 'this.focusedDistance: ' + this.focusedDistance );

}

var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh ); 

EventsControls.attach( mesh );

// 

function render() {
       EventsControls.update();
       controls.update();
       renderer.render(scene, camera);
}
gevaraweb
  • 912
  • 7
  • 19