THREE.JS Raycasting to a child of the camera - three.js

I have a object (plane) that is a child of the camera so its 'fixed to the screen'.
plane = new THREE.Mesh(new THREE.PlaneGeometry(10, 10, 10, 10), material);
plane.position.set(0,0,-5);
camera.add(plane);
On this plane I have another object which I want to move, to I am sending raycasts to the plane.
if(INTERSECTED){
handleEvent();
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObject( plane);
if(intersects.length>0){
//what is happening here?
//these points are definitely not on the plane!
var x = intersects[0].point.x;
var y = intersects[0].point.y;
var z = intersects[0].point.z;
INTERSECTED.position.set(x,y,z);
console.log(x,y,z);
}
}
The positions on which the rays hit the plane doesn't make any sense for me!
Please help me out, I'm stuck!
Thanks!
Here is the fiddle:
jsfiddle.net/74jLjz6q/2
PS: I found this post, with a similar problem, where the camera was a child of another object.. I couldn't find any help for my problem there..
THREE.js Raycasting from a child camera to the scene

Okey, I got it by trail and error:
It had to be the other way around (world to local).
I'm not sure if I really understood this..
So, the points are provided in world space. (..Because THREE.Raycaster always does?)
And it has to be in local space because the plane is a child of the camera.
Is that right?
(AND I had to substract the distance between the camera and the plane manually.)
plane.worldToLocal( intersects[0].point );
INTERSECTED.position.set(intersects[0].point.x,intersects[0].point.y,intersects[0].point.z-5);
The updated and working fiddle (The cube finally stays on the plane! :) ):
http://jsfiddle.net/74jLjz6q/9/

Related

How do I calculate a perimeter of a flattened mesh?

I'm trying to calculate the perimeter of a custom shaped 3d object but I'm totally in a black room :(
Actually I've managed to get the EdgeHelper of the mesh by doing this:
var helper = new THREE.EdgesHelper( mesh, 0x00ff00 );
helper.material.linewidth = 2;
helper.scale.x = 0.001;
But now... what can I do to have the perimeter?
May you please point me to the right direction? Any tip would be more than appreciated :)

Rotate around World Axis

I tried to rotate an object arount the Worlds-Y-Axis, with
myObject.rotateOnWorldAxis(new THREE.Vector3(0,1,0),THREE.Math.degToRad(1));
but the result was, that the object is only rotated in object space.
To be sure that I used the correct method I looked into the documentation and found that there are three methods to rotate an object:
.RotateY(rad) // rotate in Local Space
.rotateOnAxis(axis,rad) // rotation in Object Space
.rotateOnWorldAxis(axis,rad) // rotation in World Space
It seems that I used the correct method.
Is this a bug or an understanding problem on my side?
Here is a JSFiddle which illustrates my problem (the blue cube should rotate around the world axis).
Here is a second Fiddle where thy cyan cube is a child of another object.
It looks to me like your real question isn't regarding world space or object space rotations, cause those are working as expected in your examples.
You probably meant, how to change the point of rotation of an object. If that is the case, you have two options, you can either translate all your geometry vertices in respect to a pivot point of rotation. That way, your pivot will be centered at (0,0,0) and your vertices will rotate in respect to that.
mesh.geometry.translate( x, y, z );
Or you can make your object a child of a different Object3D (pivot), position your original mesh similarly to what was described above and rotate your pivot mesh.
var cube = new THREE.Mesh( geometry, material );
var pivot = new THREE.Object3D();
cube.position.set( 0, 12, 30 ); // offset from center
pivot.add( cube );
scene.add( pivot );
//...
pivot.rotation.y += Math.PI/2;
JSFiddle

Three.js - change camera POV on click

Some project background:
I have a Sprite particle field that is randomly generated. The camera is located at position 0, 0, 0. The particle field is all around the camera. I'm using Raycaster to be able to select the particle that is clicked on and change it's color. Once clicked I would like the camera to focus on this particle. I'm also attempting to use Tween to glide the particle into view.
I've attempted several different methods and none of them work. They are described here:
A traditional lookAt method that used Raycaster to pick up the intersect point from clicking.
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, this.camera);
var intersects = raycaster.intersectObjects( this.starfield.children );
this.camera.lookAt(intersects[0].object.position)
A distanceTo method where the distance between the camera and the intersect coordinates is used to move the camera. This only moves the camera along the z plane. It wont actually change its POV.
var cameraPosition = new THREE.Vector3(this.camera.position.x, this.camera.position.y, this.camera.position.z);
var intersectPosition = new THREE.Vector3(intersects[0].object.position.x, intersects[0].object.position.y , intersects[0].object.position.z );
var zoomPos = intersectPosition.distanceTo( cameraPosition );
const newCameraPosition = cameraPosition.addVectors(this.camera.position, vector.setLength(zoomPos));
I calculated the angle of rotation for each X, Y, and Z axis via tan and cos equations. I then attempted to rotate the camera by those degrees. I even tried converting them to radians to see if that would make a difference with the rotation method. It didnt :(
I don't know what else to do. At this stage I'm completely open to a different approach as long as I get this camera working. I'm very stuck,
any help would be greatly appreciated!
Instead of using
intersects[0].object.position
try using
intersects[0].point
.point is the world space position of the hit.
.objectis the object the triangle belongs to. .object.position is just the origin of that object, in this case the particle system. The particle positions themselves are relative to this origin.

THREE.js checking how close the camera is to a mesh

I have a mesh landscape in THREE.js that the camera points down at, I'd like to maintain a certain distance from that mesh (so if there's peaks in the terrain the camera moves further away).
I thought raycasting would be the correct way to start going about this (by getting the intersection distance) but all the examples I find relate to using mouse co-ordinates; when I try to set the origin as the camera position, and the direction co-ords to be the camera position but with a 0 on the Y axis (so camera up in the air facing down) the intersect results come up empty.
For example, on the render event I have:
t.o.ray.vector = new THREE.Vector3(t.o.camera.position.x, 0, t.o.camera.position.z );
t.o.ray.cast = new THREE.Raycaster(t.o.camera.position,t.o.ray.vector );
t.o.ray.intersect = t.o.ray.cast.intersectObject(object, true);
console.log(t.o.ray.intersect);
This results in an empty array, even when I'm moving the camera, the only way I can seem to get this to work is by using the examples that rely on mouse events.
Any ideas what I'm missing?
I realised it was because that setting 0 as the Y property was not enough. I had assumed that the vector co-ordinate simply helped calculate the direction in which the ray was pointing in, but this doesn't seem to be the case. i.e. -:
t.o.ray.vector = new THREE.Vector3(t.o.camera.position.x, -1000, t.o.camera.position.z );
t.o.ray.vector.normalize();
t.o.ray.cast = new THREE.Raycaster(t.o.camera.position,t.o.ray.vector );
t.o.ray.intersect = t.o.ray.cast.intersectObject(t.Terrain.terrain, true);
Produces the expected results.
What about this approach:
console.log( t.o.camera.position.distanceTo(t.o.vector.position) );

Ray intersection and child camera

I've been playing with three.js for few weeks now and got few inconsistencies on ray casting.
Here is a simplified version demonstrating one of the bug I encoutered :
http://jsfiddle.net/eMrhb/12/
The camera is added to the sphere mesh for further use of TrackBallControl for example.
scene.add(mesh);
mesh.add(camera);
Clicking a few times on the sphere and opening the console, show us none of the expected intersections between the ray and the mesh.
Adding the camera to the scene (http://jsfiddle.net/eMrhb/9/), solves the problem:
scene.add(mesh);
scene.add(camera);
But I could use a much more complex hierarchy between my scene objects and the camera to suit my needs.
Is this a limitation? If it is, is there any workarounds I could use?
Yes, this is fixable.
If the camera is a child of another object that is rotated and or translated, then your have to use a different pattern in ray casting.
Instead of this familiar pattern:
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
You have to use this pattern instead:
var position = camera.matrixWorld.getPosition().clone();
var ray = new THREE.Ray( position, vector.subSelf( position ).normalize() );
three.js r.53

Resources