18

I want to know if my raycaster is looking at an OBJ that I've loaded. Due to the way exported from Cinema4D, I believe the OBJ is a THREE.Group with 3 children, instead of a THREE.Object. Can I just change my raycaster line of code to look for this group instead of an object?

raycaster.set(controls.getObject().position, controls.getDirection(), 0, 40)

var intersects = raycaster.intersectObjects(scene.children, true);

     if (intersects.length > 0) {
      //CURRENTLY INTERSECTING SOMETHING
      for (var i = 0; i < onOffCubes.length; i++) {
      //if the first thing the raycaster sees is a one of my cubes
        if (intersects[0].object == onOffCubes[i]) {
                ExperiencesData[i].userClose = true
            }
         }
       }

onOffCubes is an array of 6 OBJs/THREE.js Groups:

enter image description here

Console.log(onOffCubes[0]) is this: enter image description here

EJW
  • 604
  • 2
  • 10
  • 22

2 Answers2

14

So close. The intersect object is a mesh, the parent of that mesh is the group. You need to match the parent object of the intersect rather than the object of the intersect. That is:

intersects[ 0 ].object.parent === onOffCubes[ i ]

rather than:

intersects[ 0 ].object === onOffCubes[ i ]

TL;DR

To test with a similar structure, I generated six groups of three meshes each, with each group of meshes sharing the same material. Note that onOffCubes isn't a THREE.js group, it's an array of groups. This is like the original poster's onOffCubes:

var onOffCubes = []
for ( var i = 0; i < 6; i++ ) {
    var material = new THREE.MeshBasicMaterial({ color: 0xee55aa })
    var group = new THREE.Group()
    for ( var j = 0; j < 3; j++ ) {
        var mesh = new THREE.Mesh( geometry, material );
        mesh.position.x = Math.random() * 100 - 50;
        mesh.position.y = Math.random() * 100 - 50;
        mesh.position.z = Math.random() * 200 - 200;
        group.add( mesh );
    }
    onOffCubes.push( group )
    scene.add( group )
}

Check full scene

var intersects = raycaster.intersectObjects( scene.children, true );

or check just onOffCubes

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

Essentially the same code as original poster with the one fix:

if (intersects.length > 0) {
    for (var i = 0; i < onOffCubes.length; i++) { 
        if (intersects[ 0 ].object.parent === onOffCubes[ i ]) {
            // What I tested with
            //intersects[ 0 ].object.material.color.set( 0xff0000 )
            // Your code
            ExperiencesData[i].userClose = true
        }
    }
}
Chris Buck
  • 745
  • 5
  • 15
5

Try to look through the children of your group:

var intersects = raycaster.intersectObjects(YOUR_OBJECT.children, true);

THREE.Group inherits from THREE.Object3D, so it may works

leota
  • 1,636
  • 2
  • 13
  • 33
  • hmmm. because there are actually 6 groups I need to look inside, I tried: `for (i in experiences){ var intersects = raycaster.intersectObjects(onOffCubes[i].children, true);}` but got the error: cannot read property 'children' of undefined – EJW Apr 12 '16 at 18:40
  • Try to look just inside one group: var intersects = raycaster.intersectObjects(onOffCubes[0].children, true); Does it work?Any errors? – leota Apr 12 '16 at 19:04
  • could you do a: console.log( onOffCubes[0] ) and post the output? Or even better, a jsfiddle so I can test something – leota Apr 12 '16 at 19:45
  • I added the console.log to the original post – EJW Apr 12 '16 at 20:02
  • It's very strange. The THREE.Group is an actual Object3D with children, so it should work – leota Apr 12 '16 at 20:13
  • Actually the error you're getting is: cannot read property 'children' of undefined, which means that your onOffCubes[0] does not exist or has not been initialised. is it a global or local var? – leota Apr 12 '16 at 20:16