3
votes

I am trying to get collision detection from meshes i lay out on my Three.js scene. I am confused on how the Raycaster reallu works and if i get it right.

Here is a fiddle to descripe what i have problem with

//Add cuba at 40/40
geometry = new THREE.CubeGeometry(20, 20, 20);
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh(geometry, material);
mesh.position.setY(40)
scene.add(mesh);


//Add Ray    
var origin = new THREE.Vector3(50, 0, 0),
    direction = new THREE.Vector3(-1,0,0),
    ray = new THREE.Raycaster(origin, direction),
    collisionResults = ray.intersectObjects([mesh]);
if(collisionResults.length!==0){
   alert('Ray collides with mesh. Distance :' + collisionResults[0].distance)
}

//Add Arrow to show ray
scene.add( new THREE.ArrowHelper(direction, origin, 50, 0x000000));

Not working: http://jsfiddle.net/FredricBerling/LwfPL/1/

Working: http://jsfiddle.net/FredricBerling/LwfPL/3/

Basically the fiddle lays out a cube and the 50 points form that i shoot a ray in a "direction". Problem seems to be that it states a "hit" even if it shouldnt.

I lay out a Arrowhelper to show where i suspect the Raycaster shoots its ray.

From other tests it seems like the direction in Raycaster is different from the one in Arrowhelper. Raycaster seems to shoot the ray into the 0,0,0 of the scene. I am confused

EDIT!. Rob gave the answer. I needed to make sure the meshes was rendered so that worl matrixes was applied. Fiddle is updated with the correct code that works for testing Raycaster as expected.

1
You do not need to render first -- you can call mesh.updateMatrixWorld(); after setting the mesh position.WestLangley
Thanks. I noticed that. Re-rendering the world completely isn't very good on performance. :)Fredric Berling

1 Answers

3
votes

The apparent false positive you're seeing is due to the fact that even though you have set the box's position, it hasn't yet had its world transformation matrix updated. This normally only happens just before rendering.

If you move the raycast test to after the first render (or call updateWorld() manually), you won't get a hit.