=================================
=================================
=================================
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
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);
Raycasting to a Mesh in using an OrthographicCamera
Raycasting to a Mesh with BufferGeometry
Raycasting to a Line
Raycasting to Points
Terrain raycasting
Raycasting using an octree
Raycasting to paint voxels
Raycast to a Texture
Constructor
Raycaster( origin, direction, near, far ) {
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.
Properties
#.far
This value shouldn't be negative and should be larger than the near property.
#.linePrecision
#.near
This value shouldn't be negative and should be smaller than the far property.
#.params
{ Mesh: {}, Line: {}, LOD: {}, Points: { threshold: 1 }, Sprite: {} }
#.ray
Methods
#.set ( origin, direction )
direction — The normalized direction vector that gives direction to the ray.
#.setFromCamera ( coords, camera )
camera — camera from which the ray should originate
#.intersectObject ( object, recursive )
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.
[ { 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 Geometry, indices 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 ( objects, recursive )
recursive — If true, it also checks all descendants of the objects. Otherwise it only checks intersecton with the objects. Default is false.
Source
=================================
=================================
=================================
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
=================================
=================================
=================================
출처: 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);
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
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; }
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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) ...
=================================
=================================
=================================
출처: 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
How to do it
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 );
}
}
-( 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 );
}
How it works
-( event.clientY / window.innerHeight ) * 2 + 1, //y
0.5 ); //z
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 |
- 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.
mouse3D.normalize();
The Demo
The z coordinate
-( event.clientY / window.innerHeight ) * 2 + 1, //y
0.5 ); //z
Projection when the canvas is not full screen
- 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.
-( event.clientY / window.innerHeight ) * 2 + 1, //y
0.5 ); //z
-( event.clientY - offsetY ) / viewHeight * 2 + 1,
0.5 );
Done
=================================
=================================
=================================
'WEB > WebGL' 카테고리의 다른 글
[WebGL] Three.js - Three 사이트, 라이브러리 다운로드 (0) | 2017.12.21 |
---|---|
[WebGL] Three.js - GUI 관련 텍스트입력 TextEdit 슬라이드 등등(canvas, css3d 다른것들도 응용링크) (0) | 2017.12.13 |
[WebGL] Three.js - 선그리기 자유곡선 관련 (0) | 2017.11.14 |
[WebGL] WebGL FBO(Frame Buffer Object) 관련 (0) | 2017.11.13 |
[WebGL] Three.js - Three FBO(Frame Buffer Object) 관련 (0) | 2017.11.13 |
댓글 영역