Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mouse / Canvas X, Y to Three.js World X, Y, Z

I've searched around for an example that matches my use case but cannot find one. I'm trying to convert screen mouse co-ordinates into 3D world co-ordinates taking into account the camera.

Solutions I've found all do ray intersection to achieve object picking.

What I am trying to do is position the center of a Three.js object at the co-ordinates that the mouse is currently "over".

My camera is at x:0, y:0, z:500 (although it will move during the simulation) and all my objects are at z = 0 with varying x and y values so I need to know the world X, Y based on assuming a z = 0 for the object that will follow the mouse position.

This question looks like a similar issue but doesn't have a solution: Getting coordinates of the mouse in relation to 3D space in THREE.js

Given the mouse position on screen with a range of "top-left = 0, 0 | bottom-right = window.innerWidth, window.innerHeight", can anyone provide a solution to move a Three.js object to the mouse co-ordinates along z = 0?

like image 832
Rob Evans Avatar asked Oct 24 '12 18:10

Rob Evans


People also ask

How do I get mouse position in 3 JS?

So now my requirement is when the mouse is moved towards the circle, the circle should sense the mousemove and it should move towards the mouse. So for that i have created a RingGeometry around the circle. So if the mouse move towards the ring, circle should sense the position of the mouse.

How do you get the mouse position on canvas?

To get real mouse position in canvas with JavaScript, we use the canvas getBoundingClientRect method. const getMousePos = (canvas, evt) => { const rect = canvas. getBoundingClientRect(); return { x: ((evt.


2 Answers

In r.58 this code works for me:

var planeZ = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0); var mv = new THREE.Vector3(     (event.clientX / window.innerWidth) * 2 - 1,     -(event.clientY / window.innerHeight) * 2 + 1,     0.5 ); var raycaster = projector.pickingRay(mv, camera); var pos = raycaster.ray.intersectPlane(planeZ); console.log("x: " + pos.x + ", y: " + pos.y); 
like image 37
lazymf Avatar answered Sep 21 '22 02:09

lazymf


You do not need to have any objects in your scene to do this.

You already know the camera position.

Using vector.unproject( camera ) you can get a ray pointing in the direction you want.

You just need to extend that ray, from the camera position, until the z-coordinate of the tip of the ray is zero.

You can do that like so:

var vec = new THREE.Vector3(); // create once and reuse var pos = new THREE.Vector3(); // create once and reuse  vec.set(     ( event.clientX / window.innerWidth ) * 2 - 1,     - ( event.clientY / window.innerHeight ) * 2 + 1,     0.5 );  vec.unproject( camera );  vec.sub( camera.position ).normalize();  var distance = - camera.position.z / vec.z;  pos.copy( camera.position ).add( vec.multiplyScalar( distance ) ); 

The variable pos is the position of the point in 3D space, "under the mouse", and in the plane z=0.


EDIT: If you need the point "under the mouse" and in the plane z = targetZ, replace the distance computation with:

var distance = ( targetZ - camera.position.z ) / vec.z; 

three.js r.98

like image 81
WestLangley Avatar answered Sep 23 '22 02:09

WestLangley