Hrittik Chatterjee
Hrittik Chatterjee

Reputation: 91

Three.js raycasting when its not full screen

I've been having issues with three.js raycasting recently.

I have a div element for which the element is not the full screen and it should not be the full screen and I think this is causing issues with the positioning of the raycast which I don't know how to fix.

    let mouseVector = new THREE.Vector3()
let raycaster = new THREE.Raycaster()

Object.assign(mouseVector, {
  x: 2 * (e.clientX / canvas.width) - 1,
  y: 1 - 2 * (e.clientY / canvas.height)
})

raycaster.setFromCamera(mouseVector, camera)

let intersects = raycaster.intersectObject(scene.children)

for(const intersection of intersects) {
  console.log(intersection)
 }

   mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
   mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;

  raycaster.setFromCamera( mouse, camera );    
  intersects = raycaster.intersectObjects( scene.children, true );
  console.log(intersects);

  for(const ray of intersects) {
    if(ray.object.name !== "Grid") {
      if(smallestDist == undefined){
          smallestDist1 = ray;
        }else if(smallestDist > ray.distance){
          smallestDist1 = ray
        }
    }
  }
   mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
  mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;
  raycaster.setFromCamera( mouse, camera );    
  var intersects = raycaster.intersectObjects( scene.children );

  for ( var i = 0; i < intersects.length; i++ ) {
    if(intersects[i].object.name == "Grid"){
    }else{
      if(smallestDist == undefined){
        smallestDist = intersects[i];
      }else if(smallestDist > intersects[i].distance){
        smallestDist = intersects[i]
      }
    }
  }
  console.log(smallestDist1)
  if(smallestDist1){
    const geometry = new THREE.SphereGeometry( 0.5, 15, 15 );
    const material = new THREE.MeshBasicMaterial( {color: 0xFF0000} );
    const sphere = new THREE.Mesh( geometry, material );
    sphere.position.set(smallestDist1.point.x, smallestDist1.point.y, smallestDist1.point.z)
    sphere.name = "TestSphere"
    scene.add( sphere );
  }

Above is the code i've tried however as the element with the 3D object isn't full window sized I think it's bugging out. Any help is appreciated.

Upvotes: 2

Views: 1323

Answers (2)

Stephanie Gao
Stephanie Gao

Reputation: 41

The top-left point of the browser window is the origin of coordinate (0, 0) for MouseEvent, while the exact center point of canvas for threejs.

Click here to see coordinate details.

As shown the image above, four corner points of the canvas is equivalent to (-1, 1), (1, 1), (1, -1), (-1, -1) under threejs context.

Otherwise, the canvas might have offsets to the browser (0, 0), which can be accessed with canvas.offsetTop and cavas.offsetLeft.

With all above considered, any MouseEvent client coordinate (event.clientX, event.clientY) should be mapped to threejs coordinate as below:

mouse.x = ( (event.clientX - canvas.offsetLeft) / canvas.clientWidth ) * 2 - 1;
mouse.y = ( (event.clientY - canvas.offsetTop) / canvas.clientHeight ) * -2 + 1;

Upvotes: 1

Mugen87
Mugen87

Reputation: 31076

Try to compute mouse like so:

const rect = renderer.domElement.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;

mouse.x = ( x / canvas.clientWidth ) *  2 - 1;
mouse.y = ( y / canvas.clientHeight) * - 2 + 1

Upvotes: 4

Related Questions