3

I'm trying to detect when the user has clicked on a specific cube in my 3d scene I've seen a few similar questions but none seem to have quite the same problem as me.

I have a 3D Array of cubes which populates and displays fine but when my mouse down function is called, the intersect array is always empty - I can't see what's wrong and would appreciate any help.

My renderer is set up like so:

function setupRenderer()
{
    renderer = new THREE.WebGLRenderer({antialias: true});
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColorHex( 0xEEEEEE, 1 );
    renderer.domElement.addEventListener( 'mousedown', onDocumentMouseMove, false );
    $('body').append(renderer.domElement);
}

and the event handler is:

function onDocumentMouseDown(event)
{
    console.log("mouse clicked!");
    event.preventDefault();
    if(event.target == renderer.domElement)
    {
        var mouseX = (event.clientX / window.innerWidth)*2-1;
        var mouseY = -(event.clientY /window.innerHeight)*2+1;

        var vector = new THREE.Vector3(mouseX, mouseY, 0.5);
        projector.unprojectVector(vector, camera);

        var raycaster = new THREE.Raycaster(camera.position, vector.subSelf(camera.position).normalize());
        var intersects = raycaster.intersectObjects(cubes);
        console.log("intersects.length: " + intersects.length);
        if ( intersects.length > 0 ) {
            console.log("intersected objects");
            /* do stuff */
        }
    }
}

You can see the current project in action at http://kev-adsett.co.uk/experiments/three.js/experiment1/

WestLangley
  • 102,557
  • 10
  • 276
  • 276
kevatron400
  • 65
  • 1
  • 6

1 Answers1

9

You need to pass in a single array of objects into

var intersects = raycaster.intersectObjects( objects );

If the objects array is hierarchal (i.e., one of the objects has a child), then you need to specify it this way:

var intersects = raycaster.intersectObjects( objects, true );

You can also pass in scene.children.

This function will not work with your "cubes" data structure.

three.js r.54

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • 1
    Ahh ok I didn't realise arrays passed into the intersectObjects function had to be single arrays. That's really helpful, thanks for your quick response @WestLangley. Perhaps if I refactor my array to be two different single arrays, one of cube meshes, and one of Vector3 objects storing their positions, then I could pass the mesh array in to the intersectObjects function. I'll try this at lunch and report back! – kevatron400 Jan 03 '13 at 10:05
  • Woo! That solution of two arrays worked fantastically thanks. (Actually the position array is kind of unneeded at the moment, but I think it will be required when I start changing the positions of the cubes later on). – kevatron400 Jan 03 '13 at 11:03
  • 1
    I have constant moving element on the scene, at that time this is not working... so is there any way to intersects the moving elements ? – Smit Aug 01 '13 at 09:05
  • @Smit You need to make a new post to ask a question. – WestLangley Aug 01 '13 at 10:49
  • give them indexed names and you can easy detect what you want. if intersects is not empty you have click detected object if ( intersects[ 0 ].object.name == "CUBE66" ) { .... } Important put all this in click event . In mousemove event setup mouse vector 2d if you wanna use raycaster.setFromCamera( mouse, camera ); – Nikola Lukic Mar 09 '16 at 12:19