I set up my scene as follows:
document.addEventListener('mousedown', onDocumentMouseDown, false);
var container = document.getElementById("myCanvas");
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth*0.99, window.innerHeight*0.99 );
container.appendChild( renderer.domElement );
room_material = new THREE.MeshBasicMaterial({color: 0x00ff00});
room_material.side = THREE.DoubleSide;
objects = [];
camera.position.z = 19;
camera.position.x = 5;
camera.position.y = 30;
I have an array of objects that i'm trying to detect if a click intersects with them, defined as follows:
var thing0 = new THREE.Shape();
thing0.moveTo(-12.1321728566, 35.3935535858);
thing0.lineTo(7.10021556487,35.3935535858);
thing0.lineTo(7.10021556487,19.7039735578);
thing0.lineTo(5.12636517425,19.7166264449);
thing0.lineTo(5.12636517425,33.6221493891);
thing0.lineTo(-12.1377356984,33.6439534769);
var thing0Geom = new THREE.ShapeGeometry(thing0);
var thing0Mesh = new THREE.Mesh( thing0Geom, room_material );
thing0Mesh.name = "abcd";
scene.add(thing0Mesh);
objects.push(thing0Mesh);
I then render the scene with the following code:
renderer.render(scene, camera);
requestAnimationFrame(render);
And lastly I use the following code for the mouse click event:
function onDocumentMouseDown(event) {
var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
vector = vector.unproject(camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects(objects, true);
alert("well, you clicked!");
if (intersects.length > 0) {
alert("wow, it worked");
}
}
However, no matter what I do the alert never gets called when it follows raycaster.intersectObjects(objects, true); However it does get called when it is placed anywhere before it. It seems that raycaster.intersectObjects(objects, true); is a bit of a black hole in this case?
I assume I simply have something wrong in my setup? Any help would be appreciated!
There are two things I tried that worked:
1) Make sure you're using Three.DoubleSide if your mesh face is not pointing towards origin of the ray. This is directly from the documentation:
"Note that for meshes, faces must be pointed towards the origin of the ray in order to be detected; intersections of the ray passing through the back of a face will not be detected. To raycast against both faces of an object, you'll want to set the material's side property to THREE.DoubleSide."
2) Use mesh.updateMatrixWorld() prior to raycasting. This comes from another stackoverflow post: threejs raycasting does not work
mesh.updateMatrixWorld(); // add this
raycaster.set(from, direction);
I think i have found the problem. I have to add the meshes to an extra array. An intersectObjects over the scene.children don't work, because there are other objects in there with the meshes.
So when i give the intersectObjects( mesh[] ) an mesh array than it works.
For more code detail see https://github.com/mrdoob/three.js/issues/8081
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With