Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection within Object3D

I have some objects added to an Object3D (for grouping elements) and I'm trying to detect clicks on it. My scene has a size of 600x400, my camera is within a three-object and my event handler code looks like below:

function onDocumentMouseDown( event ) {
   event.preventDefault();

   var mouse = {};
   mouse.x = ( event.clientX / 600 ) * 2 - 1;
   mouse.y = - ( event.clientY / 400 ) * 2 + 1;

   var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
   projector.unprojectVector( vector, three.camera );

   var ray = new THREE.Ray( three.camera.position, vector.subSelf( three.camera.position ).normalize() );

   var intersects = ray.intersectObjects( group.children );
   alert(intersects.length);
   [...]
}

Actually I'm alerting the count of intersected objects. But it stays zero. It couldn't find any intersected objects. I've already played a bit aroud with the x, y and z values of my projection vector - without success.

I've added a stripped down sample for demonstrating this issue on jsfiddle. Maybe someone has a short hint for me what goes wrong with it?

like image 267
AndreW. Avatar asked Sep 04 '12 10:09

AndreW.


2 Answers

In your fiddle, because you are calling THREE.SceneUtils.createMultiMaterialObject( ), which creates a hierarchical structure, you need to add the recursive flag to ray.intersectObjects().

var intersects = ray.intersectObjects( group.children, true );

EDiT: ray is now an instance of THREE.Raycaster -- not THREE.Ray.

three.js r.58

like image 200
WestLangley Avatar answered Oct 12 '22 02:10

WestLangley


I had the same problem and WestLangley's answer provides the answer. Great job! For anybody struggling with mouse selection of objects grouped in Object3D wrapper too, I am posting my own solution.

First, I created an array of objects that are selectable - I hope this also saves some performance, as RayCaster doesnt need to search all objects in the scene, but only those you wish to respond to selection. I also attached this array to scene object directly (solely for the fact that it is already accessible from most parts of my app)

scene.selectable = [];

Next step is to push all objects that you wish to make selectable into this array. You will insert only meshes/sprites/etc from your group, not the whole group. Only last line is important here:

var myWrapper = new THREE.Object3D();
var myObject = new THREE.Mesh( something );
myWrapper.add( myObject );
scene.add ( myWrapper );
scene.selectable.push( myObject );

And lastly in your mouse selection routine you will call raycaster like this:

var intersects = ray.intersectObjects( scene.selectable );
like image 35
lot Avatar answered Oct 12 '22 03:10

lot