상세 컨텐츠

본문 제목

[WebGL] Three.js - 마우스 위치, 이벤트 관련

WEB/WebGL

by AlrepondTech 2017. 11. 14. 01:15

본문

반응형

 

 

=================================

=================================

=================================

 

 

 

출처: https://stackoverflow.com/questions/55677/how-do-i-get-the-coordinates-of-a-mouse-click-on-a-canvas-element

 

ThreeJS r77

var x = event.offsetX == undefined ? event.layerX : event.offsetX; var y = event.offsetY == undefined ? event.layerY : event.offsetY;  mouse2D.x = ( x / renderer.domElement.width ) * 2 - 1; mouse2D.y = - ( y / renderer.domElement.height ) * 2 + 1;

After trying many solutions. This worked for me. Might help someone else hence posting. Got it from here

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: https://threejs.org/docs/#api/core/Raycaster

 

Raycaster

This class is designed to assist with raycasting. Raycasting is used for mouse picking (working out what objects in the 3d space the mouse is over) amongst other things.

Example

var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); function onMouseMove( event ) { // calculate mouse position in normalized device coordinates // (-1 to +1) for both components mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; } function render() { // update the picking ray with the camera and mouse position raycaster.setFromCamera( mouse, camera ); // calculate objects intersecting the picking ray var intersects = raycaster.intersectObjects( scene.children ); for ( var i = 0; i < intersects.length; i++ ) { intersects[ i ].object.material.color.set( 0xff0000 ); } renderer.render( scene, camera ); } window.addEventListener( 'mousemove', onMouseMove, false ); window.requestAnimationFrame(render);

 

Constructor

Raycaster( origindirectionnearfar ) {

origin — The origin vector where the ray casts from.
direction — The direction vector that gives direction to the ray. Should be normalized.
near — All results returned are further away than near. Near can't be negative. Default value is 0.
far — All results returned are closer then far. Far can't be lower then near . Default value is Infinity.
This creates a new raycaster object.

Properties

.far

The far factor of the raycaster. This value indicates which objects can be discarded based on the distance.
This value shouldn't be negative and should be larger than the near property.

.linePrecision

The precision factor of the raycaster when intersecting Line objects.

.near

The near factor of the raycaster. This value indicates which objects can be discarded based on the distance.
This value shouldn't be negative and should be smaller than the far property.

.params

An object with the following properties:{ Mesh: {}, Line: {}, LOD: {}, Points: { threshold: 1 }, Sprite: {} }

.ray

The Ray used for the raycasting.

Methods

.set ( origindirection )

origin — The origin vector where the ray casts from.
direction — The normalized direction vector that gives direction to the ray.
Updates the ray with a new origin and direction.

.setFromCamera ( coordscamera )

coords — 2D coordinates of the mouse, in normalized device coordinates (NDC)---X and Y components should be between -1 and 1.
camera — camera from which the ray should originate
Updates the ray with a new origin and direction.

.intersectObject ( objectrecursive )

object — The object to check for intersection with the ray.
recursive — If true, it also checks all descendants. Otherwise it only checks intersecton with the object. Default is false.

Checks all intersection between the ray and the object with or without the descendants. Intersections are returned sorted by distance, closest first. An array of intersections is returned...[ { distance, point, face, faceIndex, indices, object }, ... ]

distance – distance between the origin of the ray and the intersection
point – point of intersection, in world coordinates
face – intersected face
faceIndex – index of the intersected face
indices – indices of vertices comprising the intersected face
object – the intersected object
uv - U,V coordinates at point of intersection

When intersecting a Mesh with a BufferGeometry, the faceIndex will be undefined, and indices will be set; when intersecting a Mesh with a Geometryindices will be undefined.

Raycaster delegates to the raycast method of the passed object, when evaluating whether the ray intersects the object or not. This allows meshesto respond differently to ray casting than lines and pointclouds.

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.

.intersectObjects ( objectsrecursive )

objects — The objects to check for intersection with the ray.
recursive — If true, it also checks all descendants of the objects. Otherwise it only checks intersecton with the objects. Default is false.
Checks all intersection between the ray and the objects with or without the descendants. Intersections are returned sorted by distance, closest first. Intersections are of the same form as those returned by .intersectObject.

Source

src/core/Raycaster.js

 

 

 

=================================

=================================

=================================

 

 

 

So I'm able to get the current object (this case a plane) under the mouse using a raycaster, but I'd like get an accurate X and Y for the mouse position INSIDE the plane.

var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1,     0.5 );  projector.unprojectVector( vector, camera );  var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );  var intersects = raycaster.intersectObject(plane, true);  if (intersects.length > 0) {     console.log(intersects[0].point); }

If I have my 200x200 plane facing the camera head on, then intersects[0].point.x ranges from -100 to +100 as expected. But when I rotate the plane I get mixed results.

How can I get an x value of -100 to +100 regardless of where the plane is on the scene?

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

To get the intersected point in the object's local coordinate system when using Raycaster, do this:

var vector = new THREE.Vector3().copy( intersects[ 0 ].point );  intersects[ 0 ].object.worldToLocal( vector );  console.log( 'local point: ', vector );

three.js r.65

shareimprove this answer

 

 

=================================

=================================

=================================

 

 

 

출처: https://stackoverflow.com/questions/30860773/how-to-get-the-mouse-position-using-three-js

 

Hi I'm using IcosahedronGeometry. In that I'm adding CircleGeometry to each of its vertices. 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.

But I'm unable to get the mouse position. I'm using raycaster, is there any other alternative to find the position of the mouse?

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Raycaster is standard way for this:

mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; raycaster.setFromCamera( mouse.clone(), camera );     var objects = raycaster.intersectObjects(scene.children);

http://jsfiddle.net/nhvff8ra/6/

 

 

=================================

=================================

=================================

 

 

출처: https://stackoverflow.com/questions/43468588/three-js-multiple-elements-click-object

 

I'm using this as an base of my project

https://threejs.org/examples/#webgl_multiple_elements

There are multiple scenes on one renderer. I would like to add on click event on each scene. But as the div moves in canvas the click event is not changing its position.

I have tried Raycaster, THREEx, EventsControls but in each case I have noticed that the element position (coordinates) is always at the x: 0. When clicked in the middle of the page the click event is working, but not on the element it self.

Is there some option to update any of the above controls to match the mesh position?

Here is a basic example

var objects = []; var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2();

Creating the mesh

mesh.position.set(object.position.x, object.position.y, object.position.z); scene.add(mesh); objects.push(mesh);

Rendering

$.each(scenes, function(i, scene) {       // get the element that is a place holder for where we want to      // draw the scene      var element = scene.userData.element;       // get its position relative to the page's viewport      var rect = element.getBoundingClientRect();       // check if it's offscreen. If so skip it      if (rect.bottom < 0 || rect.top  > renderer.domElement.clientHeight ||          rect.right  < 0 || rect.left > renderer.domElement.clientWidth) {           return;  // it's off screen      }       // set the viewport      var width  = rect.right - rect.left;      var height = rect.bottom - rect.top;      var left   = rect.left;      var bottom = renderer.domElement.clientHeight - rect.bottom;       renderer.setViewport(left, bottom, width, height);      renderer.setScissor(left, bottom, width, height);       var camera = scene.userData.camera;       renderer.clearDepth();      renderer.render(scene, camera); });

On click event

document.addEventListener('mousedown', onClick, false); function onClick(event) {         event.preventDefault();          mouse.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1;         mouse.y = -(event.clientY / renderer.domElement.clientHeight) * 2 + 1;          raycaster.setFromCamera(mouse, scene.userData.camera);          var intersects = raycaster.intersectObjects(objects);         if (intersects.length > 0) {              console.log(intersects[0].object);          }         return false;     },

 

 

 

=================================

=================================

=================================

 

 

 

출처: https://stackoverflow.com/questions/13055214/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?

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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 vector = new THREE.Vector3();  vector.set(     ( event.clientX / window.innerWidth ) * 2 - 1,     - ( event.clientY / window.innerHeight ) * 2 + 1,     0.5 );  vector.unproject( camera );  var dir = vector.sub( camera.position ).normalize();  var distance = - camera.position.z / dir.z;  var pos = camera.position.clone().add( dir.multiplyScalar( distance ) ); 

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

EDIT: updated for three.js r.69

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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); 
shareimprove this answer
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
to get the mouse coordinates of a 3d object use projectVector:
var width = 640, height = 480; var widthHalf = width / 2, heightHalf = height / 2; var projector = new THREE.Projector(); var vector = projector.projectVector( object.matrixWorld.getPosition().clone(), camera ); vector.x = ( vector.x * widthHalf ) + widthHalf; vector.y = - ( vector.y * heightHalf ) + heightHalf;
to get the three.js 3D coordinates that relate to specific mouse coordinates, use the opposite, unprojectVector:
var elem = renderer.domElement, boundingRect = elem.getBoundingClientRect(), x = (event.clientX - boundingRect.left) * (elem.width / boundingRect.width), y = (event.clientY - boundingRect.top) * (elem.height / boundingRect.height); var vector = new THREE.Vector3( ( x / WIDTH ) * 2 - 1, - ( y / HEIGHT ) * 2 + 1, 0.5 ); projector.unprojectVector( vector, camera ); var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() ); var intersects = ray.intersectObjects( scene.children );
There is a great example here. However, to use project vector, there must be an object where the user clicked. intersects will be an array of all objects at the location of the mouse, regardless of their depth.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

ThreeJS is slowly mowing away from Projector.(Un)ProjectVector and the solution with projector.pickingRay() doesn't work anymore, just finished updating my own code.. so the most recent working version should be as follow:

var rayVector = new THREE.Vector3(0, 0, 0.5); var camera = new THREE.PerspectiveCamera(fov,this.offsetWidth/this.offsetHeight,0.1,farFrustum); var raycaster = new THREE.Raycaster(); var scene = new THREE.Scene();  //...  function intersectObjects(x, y, planeOnly) {   rayVector.set(((x/this.offsetWidth)*2-1), (1-(y/this.offsetHeight)*2), 1).unproject(camera);   raycaster.set(camera.position, rayVector.sub(camera.position ).normalize());   var intersects = raycaster.intersectObjects(scene.children);   return intersects; } 
shareimprove this answer
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
 
Below is an ES6 class I wrote based on WestLangley's reply, which works perfectly for me in THREE.js r77.
Note that it assumes your render viewport takes up your entire browser viewport.
class CProjectMousePosToXYPlaneHelper { constructor() { this.m_vPos = new THREE.Vector3(); this.m_vDir = new THREE.Vector3(); } Compute( nMouseX, nMouseY, Camera, vOutPos ) { let vPos = this.m_vPos; let vDir = this.m_vDir; vPos.set( -1.0 + 2.0 * nMouseX / window.innerWidth, -1.0 + 2.0 * nMouseY / window.innerHeight, 0.5 ).unproject( Camera ); // Calculate a unit vector from the camera to the projected position vDir.copy( vPos ).sub( Camera.position ).normalize(); // Project onto z=0 let flDistance = -Camera.position.z / vDir.z; vOutPos.copy( Camera.position ).add( vDir.multiplyScalar( flDistance ) ); } }
You can use the class like this:
// Instantiate the helper and output pos once. let Helper = new CProjectMousePosToXYPlaneHelper(); let vProjectedMousePos = new THREE.Vector3(); ... // In your event handler/tick function, do the projection. Helper.Compute( e.clientX, e.clientY, Camera, vProjectedMousePos );
vProjectedMousePos now contains the projected mouse position on the z=0 plane.
 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Here is my take at creating an es6 class out of it. Working with Three.js r83. The method of using rayCaster comes from mrdoob here: Three.js Projector and Ray objects

    export default class RaycasterHelper     {       constructor (camera, scene) {         this.camera = camera         this.scene = scene         this.rayCaster = new THREE.Raycaster()         this.tapPos3D = new THREE.Vector3()         this.getIntersectsFromTap = this.getIntersectsFromTap.bind(this)       }       // objects arg below needs to be an array of Three objects in the scene        getIntersectsFromTap (tapX, tapY, objects) {         this.tapPos3D.set((tapX / window.innerWidth) * 2 - 1, -(tapY /          window.innerHeight) * 2 + 1, 0.5) // z = 0.5 important!         this.tapPos3D.unproject(this.camera)         this.rayCaster.set(this.camera.position,          this.tapPos3D.sub(this.camera.position).normalize())         return this.rayCaster.intersectObjects(objects, false)       }     } 

You would use it like this if you wanted to check against all your objects in the scene for hits. I made the recursive flag false above because for my uses I did not need it to be.

var helper = new RaycasterHelper(camera, scene) var intersects = helper.getIntersectsFromTap(tapX, tapY,  this.scene.children) ... 
shareimprove this answer

 

 

 

 

반응형

 

728x90

 

 

 

 

=================================

=================================

=================================

 

 

출처: http://barkofthebyte.azurewebsites.net/post/2014/05/05/three-js-projecting-mouse-clicks-to-a-3d-scene-how-to-do-it-and-how-it-works

 

Three.js projecting mouse clicks to a 3D scene - how to do it and how it works

 
 

Introduction

In Three.js, it is quite common to detect when a user clicks an object in 3D space. I have come across a few posts and answers describing how to do this, but I found that I needed to go a bit deeper under the surface. Without some knowledge of what is happening it can be tricky to work outside of the scope of the sample code (such as having a canvas that does not fill the screen or having additional effects). In this blog post, we will still only scratch the surface, but we should hopefully cover enough to deviate from the samples with some confidence. Note that in this blog post we will use PerspectiveCamera, not OrthographicCamera.

How to do it

Lets start with a simple scenario where an object changes colour when clicked. The code for the mouse down event would be something like:
 
    function onDocumentMouseDown( event ) {                
        var mouse3D = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,   //x
                                        -( event.clientY / window.innerHeight ) * 2 + 1,  //y
                                        0.5 );                                            //z
        projector.unprojectVector( mouse3D, camera );   
        mouse3D.sub( camera.position );                
        mouse3D.normalize();
        var raycaster = new THREE.Raycaster( camera.position, mouse3D );
        var intersects = raycaster.intersectObjects( objects );
        // Change color if hit block
        if ( intersects.length > 0 ) {
            intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
        }
    }
 
With the more recent three.js releases (around r55 and later), you can use pickingRay which simplifies things even further so that the internals of the function are:
 
        var mouse3D = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,   //x
                                        -( event.clientY / window.innerHeight ) * 2 + 1,  //y
                                        0.5 );                                            //z
        var raycaster = projector.pickingRay( mouse3D.clone(), camera );
        var intersects = raycaster.intersectObjects( objects );
        // Change color if hit block
        if ( intersects.length > 0 ) {
            intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
        }
 
For this blog post we will stick with the old approach as it gives more insight into what is happening under the hood. You can see this working here, simply click on the cube to change its colour.

How it works

Now, let's look at what is happening step by step: 
 
        var mouse3D = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,   //x
                                        -( event.clientY / window.innerHeight ) * 2 + 1,  //y
                                        0.5 );                                            //z
 
I have seen a number of blogs that describe this step as `some kind of magic`, however this is actually a step that we can quite easily understand. event.clientX is the x coordinate of the click position. Dividing by window.innerWidth gives the position of the click in proportion of the full window width. The tables below show the corresponding result for the location of the mouse click:
 
event.clientX event.clientX / window.innerWidth*2-1
0 -1
window.innerWidth/2 0
window.innerWidth 1
 
event.clientY -event.clientY / window.innerHeight * 2 + 1
0 1
window.innerHeight/2 0
window.innerHeight -1
 
Basically, this is translating from screen coordinates that start at (0,0) at the top left through to (window.innerWidth,window.innerHeight) at the bottom right, to the cartesian coordinates with center (0,0) and ranging from (-1,-1) to (1,1) as shown below:
 

 


 
Note that  z has a value of 0.5. I won't go into too much detail about the z value at this point except to say that this is the depth of the point away from the camera that we are projecting into 3D space along the z axis. More on this later. 
 
OK, so we now understand the position of where the mouse was clicked in terms of the graph on the right (mouse3D contains this position). Next:
 
        projector.unprojectVector( mouse3D, camera );
 
This is actually the step where magic happens. If you look at the three.js code you will see that the camera projection onto the 3D world is applied to the vector. The way that I understand it is as follows: 
 
  • Forgetting about projecting from 2D to 3D, lets first think about the inverse - how the 3D world is projected onto your 2D screen. In order to get from 3D world coordinates to a projection on the screen, the 3D world needs to be projected onto the 2D surface of the camera (which is what you see on your screen).
  • So, to get from 2D coordinates on the screen to 3D space the opposite needs to be done.
  • Start with the camera screen as a 2D coordinate system with 0,0 at the center. Positioning mouse3D in this space will give you a position on this surface. Now, (0,0) might not be at the center so there is some additional translation to convert to the actual position. This means that you can move the camera around and have it look at different points in 3D space and the projection still works. Which is great.
The workings behind the above bullet points are a beyond the scope of this blog post, but hopefully they give some insight into what is happening behind the scenes. Note that mouse3D will now contain this unprojected value. This is the position of a point in 3D space along the ray/trajectory that we are interested in. The exact point depends on the zvalue (we will see this later).  
 
At this point, it may be useful to have a look at the following image: 
 

 


 
The point that we have just calculated (mouse3D) is shown by the green dot. Note that the size of the dots are purely illustrative, they have no bearing on the size of the camera or mouse3D point. We are more interested in the coordinates at the center of the dots. Also note that the points shown along the ray are just arbitrary points, the ray is a direction from the camera, not a set of points.
 
Now, we don't just want a single point in 3D space, but instead we want a ray/trajectory (shown by the black dots) so that we can determine whether an objects is positioned along this ray/trajectory. Fortunately, because we a have a point and we know that the trajectory must pass from the camera to this point, we can determine the direction of the ray. Therefore, the next step is to subtract the camera position from the mouse3D position, this will give a directional vector rather than just a single point:
 
        mouse3D.sub( camera.position );                
        mouse3D.normalize();
 
We now have a direction from the camera to this point in 3D space (mouse3D now contains this direction). This is then turned into a unit vector by normalizing it. You can read about unit vectors online (e.g. Wikipedia), for our purpose it is only really important to know that the unit vector has the same direction as the original). The next step is to create a ray (Raycaster) starting from the camera position and using the direction (mouse3D) to cast the ray. 
 
        var raycaster = new THREE.Raycaster( camera.position, mouse3D );
 
The rest of the code determines whether the objects in 3D space are intersected by the ray or not. This can be done by determining for each object whether the ray is within the x, y and z bounds of the object. Happily it is all taken care of us behind the scenes using intersectsObjects.

The Demo

OK, so let's look at a demo that shows these rays being cast in 3D space. When you click anywhere, the camera rotates around the object to show you how the ray is cast. Note that when the camera returns to its original position, you only see a single dot. This is because all the other dots are along the line of the projection and therefore blocked from view by the front dot. This is similar to when you look down the line of an arrow pointing directly away from you - all that you see is the base. Of course, the same applies when looking down the line of an arrow that is travelling directly towards you (you only see the head), which is generally a bad situation to be in.  OK, the demo:
 
 
 
The lines that you see are drawn by my function drawRayLine(rayCaster) that draws dots along the ray.

The z coordinate 

As promised, let's take another look at that z coordinate. Refer to this demo as you read through this section and experiment with different values for z.
 
OK, lets take another look at this function:
 
        var mouse3D = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,   //x
                                        -( event.clientY / window.innerHeight ) * 2 + 1,  //y
                                        0.5 );                                            //z
 
We chose 0.5 as the value. I mentioned earlier that the z coordinate dictates the depth of the projection into 3D. So, let's have a look at different values of z to see what effect it has. To do this, I have placed a blue dot where the camera is, and a line of green dots from the camera to the unprojected position. Then, after the intersections have been calculated, I move the camera back and to the side to show the ray. Best seen with a few examples.
 
First, a z value of 0.5:
 

 


 
Note the green line of dots from the camera (blue dot) to the unprojected value (the coordinate in 3D space). This is like the barrel of a gun, pointing in the direction that they ray should be cast. The green line essentially represents the direction that is calculated before being normalised.
 
OK, let's try a value of 0.9:
 

 


As you can see, the green line has now extended further into 3D space.  0.99 extends even further:
 
I do not know if there is any importance as to how big the value of z is. It seems that a bigger value would be more precise (like a longer gun barrel), but since we are calculating the direction, even a short distance should be pretty accurate. The examples that I have seen use 0.5, so that is what I will stick with unless told otherwise.
 

Projection when the canvas is not full screen

Now that we know a bit more about what is going on, we can figure out what the values should be when the canvas does not fill the window and is positioned on the page. Say, for example, that: -
  • the div containing the three.js canvas is offsetX from the left and offsetY from the top of the screen. 
  • the canvas has a width equal to viewWidth and height equal to viewHeight.
For full-window we had:
        var mouse3D = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,   //x
                                        -( event.clientY / window.innerHeight ) * 2 + 1,  //y
                                        0.5 );                                            //z
 
This will now become: 
 
        var mouse3D = new THREE.Vector3( ( event.clientX - offsetX ) / viewWidth * 2 - 1,
                                        -( event.clientY - offsetY ) / viewHeight * 2 + 1,
                                        0.5 );
 
Basically, what we are doing is calculating the position of the mouse click relative to the canvas (for x: event.clientX - offsetX). Then we determine proportionally where the click occurred (for x: / viewWidth) similar to when the canvas filled the window.

Done

That is it. We had a look at what is going on when mouse clicks magically select objects in 3D space using Three.js. I think the next steps for digging deeper would be to have a look at what projector.unprojectVector() does in more detail and especially have a look at how the camera projection matrix works. But, that is for another time.

 

 

 

=================================

=================================

=================================

 

 

 

반응형


관련글 더보기

댓글 영역