daniel
daniel

Reputation: 35703

THREE.BoxBufferGeometry get intersection with raycaster.intersectObjects

I want to get the intersection of the ray with the box. What's wrong with my code?

    const ggeo = new THREE.BoxBufferGeometry(100, 200, 60);
    const gmesh = new THREE.Mesh(ggeo, new THREE.MeshBasicMaterial({ color: 0x00ffff}));
    gmesh.position.set(-150, 0, -30);
    gmesh.visible = true;
    gmesh.updateMatrixWorld();
    scene.add(gmesh);

    // intersection
    var from = new THREE.Vector3(-10, 0, -10);
    var to = new THREE.Vector3(-1, 0, 0);
    var raycaster = new THREE.Raycaster();
    raycaster.set(from, to);
    var intersects = raycaster.intersectObjects(gmesh as any, true);
    if (intersects.length > 0) {
          // no interseection !
    }

here is a fiddle:

https://jsfiddle.net/jek75fLg/

Upvotes: 1

Views: 354

Answers (1)

Mugen87
Mugen87

Reputation: 31026

There are two issue in your fiddle:

  • You are not updating the world matrix of the mesh before raycasting.
  • The second parameter of Raycaster.set() expects a direction vector which has to have unit length.
  • You have to use intersectObject() not intersectObjects().

Here is a working example:

var camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;

var scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);

var raycaster = new THREE.Raycaster();

renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const ggeo = new THREE.BoxBufferGeometry(50, 300, 260);
const gmesh = new THREE.Mesh(ggeo, new THREE.MeshBasicMaterial({
  color: 0x00ffff
}));
gmesh.position.set(-150, 0, -10);
gmesh.updateMatrixWorld();
scene.add(gmesh);

var from = new THREE.Vector3(0, 0, -20);
var wallvec = new THREE.Vector3(-1, 0, 0);

var raycaster = new THREE.Raycaster();
raycaster.set(from, wallvec);

//

const lineGeometry = new THREE.BufferGeometry().setFromPoints( [from, new THREE.Vector3(-10000, 0 -20)] );
const line = new THREE.Line(lineGeometry, new THREE.LineBasicMaterial( {color: 0xff0000}));
scene.add(line);
//

var intersects = raycaster.intersectObject(gmesh);
if (intersects.length > 0) {
  console.log('INTERSECTED');
}


renderer.render(scene, camera);
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>

It also visualizes the ray so it's visible where ray is actually hitting the mesh.

BTW: Your code snippet in your post and the code in the fiddle differ in some ways. It's better for invesitgation to keep both in sync.

Upvotes: 1

Related Questions