ThreeJS camera facing point - javascript

In ThreeJS, if the camera is rotated at any given angle, how can I determine the coordinate of the point exactly 1 unit in the direction that the camera is facing.
If you are unfamiliar with ThreeJS camera rotation angles, the rotations are very very weird.
For example, if all of my rotation variable are 0, then the function would return (0, 0, -1).
If the rotation x is Pi / 2 (90 degrees), then the function would return (1, 0, 0)
How could I create a function to do this? I don't need everything, primarily just the math.

You want to get the world position of a point that is one unit in front of the camera.
One way to do that is to add an object in front of, and as a child of, the camera. Then you just need to query the world position of the object.
By default, when a camera's rotation is ( 0, 0, 0 ), the camera is looking down its negative z-axis. So here is the pattern to follow:
var object = new THREE.Object3D();
object.position.set( 0, 0, - 1 );
scene.add( camera ); // this is required when the camera has children
camera.add( object );
Now, you can get the point you need like so:
var worldPos = new THREE.Vector3(); // create once and reuse it
...
camera.updateMatrixWorld(); // this is called in the render loop, so you may not have to call it again. Experiment.
worldPos.setFromMatrixPosition( object.matrixWorld );
three.js r.71

Related

Three.js - Distance from camera to the origin plane

In the process of developing my own zoom system besides the ones provided by the Three.js controls, I need to find the current distance from camera to the plane that contains the (0, 0, 0) origin point and is perpendicular on the camera direction (let's call that value opdistance), so I can use it to translate the camera along its direction according to a zoomfactor value and a -1 or 1 bias value given by the mouse wheel, like so:
camera.translateZ(opdistance * zoomfactor ** bias - opdistance);
In a 2D triangle's mathematical terms, that distance is the camera .distanceTo the (0, 0, 0) origin point multiplied by the cosine of the angle between the camera direction and the camera to origin direction vectors and that can be calculated like:
var cameradirection = new THREE.Vector3();
camera.getWorldDirection(cameradirection);
var distancedirection = new THREE.Vector3();
camera.getWorldPosition(distancedirection).negate();
var positionangle = cameradirection.angleTo(distancedirection);
var opdistance = camera.position.distanceTo(new THREE.Vector3(0, 0, 0)) * Math.cos(positionangle);
camera.translateZ(opdistance * zoomfactor ** bias - opdistance);
but I'm interested in a simpler way using Three.js' standard methods, which I'm sure it exists.
The reason for asking is that I initially used the camera.position.z value as the opdistance, but that only works if the camera is instantiated with the (0, 0, 0) point "in front" of it along the Z axis, and it's otherwise changing to other values, depending on the camera position and direction (for example, the opdistance becomes the camera.position.y if the camera is placed "above" the (0, 0, 0) point and looking at it, and so on).
P.S. I could also achieve this via camera.position.setLength(finaldistance) but that produces some unwanted side effects as the camera jumps to other positions on resuming actions via other controls (probably some missing matrix update issue), so alternative ideas are welcomed.

Get the mouse position on an object or GridHelper object

I need to be able to find the mouse position if the mouse is on a Cube/Sphere Geometry, or if it is on the ground (using a GridHelper)
I'm trying to make shapes where a users mouse is, I have all the code needed to make the shapes, but I'm having trouble getting the position right
This is the code that gave me the best results
var vec = new THREE.Vector3(); // create once and reuse
var pos = new THREE.Vector3(); // create once and reuse
vec.set(
( container.offsetWidth / window.innerWidth ) * 2 - 1,
- ( container.offsetHeight / 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 ) );
Althoough this seems to relate more to where the camera is and even then, it's not exactly where the camera is, I've also tried re-using other code, say from the interactive cubes example that uses a Raycaster from three js and but it also seemed a bit random for when it would detect an intersection.
What should happen if the user puts their mouse on the grid, I should get the coordinates (i.e. 2.4, -5, 0, of course much more precise than that) and say the user puts their mouse on a shape, the coordinates of here the mouse is in the scene (touching the shape) (i.e. 2.4, -5, 3)

THREE.JS - Vector3.project returns weird result

I'm writing a program in THREE.JS and I need to project a Vector3. When I try to project the Vector3 (0,0,0), which should be in the center of the screen in my camera, I get NaN. Other Vector3s that are all visible (though visibility shouldn't make a difference, right?) return stuff like NaN, 0, Infinity, and random numbers between -1 and 0 (usually). Here's some code:
camera.position.x=32;
camera.position.y=32;
camera.position.z=32;
camera.lookAt(new THREE.Vector3(0,0,0));
for(var x=0;x<=16;x++)
{
for(var z=0;z<=16;z++)
{
var p=new THREE.Vector3(x,0,z).project(camera);
alert(p.x+" "+p.y+" "+p.z);
//HELP!!!
}
}
Thanks :D
I ran into this problem when using a PerspectiveCamera to calculate the projected coordinates of Vector3s without using a Scene or WebGLRenderer.
In my case, I simply had to call camera.getWorldPosition(), which updated the cameras world matrix and point.project(camera) started working as expected.
To set the camera position you need to use setters (this changed since r67? if I am not mistaken). So like this:
camera.position.setX( 32 );
camera.position.setY( 32 );
camera.position.setZ( 32 );
or
camera.position.set( 32, 32, 32 );
Because you didn't use setters the position of your camera is most likely also (0, 0, 0).
It is not possible to project a Vector from itself to itself. A solution to prevent this in the future might be to add a clause that checks equality of camera position with the vector:
vector = new THREE.Vector3( x, 0, z );
if( ! camera.position.equals( vector ) ){
var p = vector.project(camera);
}

How to strech(scale) mesh on the world axis

There is an online 3d editor where you can edit individual meshes (move, scale, rotate). Ability to edit meshes implemented using custom transform controls which based on threejs's TransformControls code. This is fragment from mousemove event:
var intersect = intersectObjects(pointer, [xzPlane]); // intersect mouse's pointer with horizontal plane
var point = new THREE.Vector3();
point.copy(intersect.point);
point.sub(offset); // coords from mousedown event (from start stretching)
// some code for 'scale' value calculating base on 'point' variable
// var scale = ...;
//
mesh.scale.x = scale;
This code works well if the mesh does not rotate.
Requires scaling always happened to the world coordinate system. This is programming question
For example, from this:
To this:
P.S. I think that custom mesh matrix must be created, but I have very little experience with matrices
Thanks!
Instead of setting the rotation, like so:
mesh.rotation.set( Math.PI/4, 0, 0 );
apply the identical rotation to the geometry, instead:
var euler = new THREE.Euler( Math.PI / 4, 0, 0 );
mesh.geometry.applyMatrix( new THREE.Matrix4().makeRotationFromEuler( euler ) );
Now, you can set the scale and get the result you want.
mesh.scale.z = 2;
fiddle: http://jsfiddle.net/Tm7Ab/5/
three.js r.67

How to get Orientation of Camera in THREE.js

I am creating a 3d game using THREE.JS and the Web Audio API. One of the problems I am having is that I want to use the web audio Listener orientation, and define the listener to be the camera, whose position and direction are constantly being updated
My question, is there anyway to easily get the vector direction of a THREE camera?
I was trying to calculate it by using the old camera position, and using the velocity vectors to calculate which way it is facing, but this won't work when the camera is standing still...
Would it be feasible to create a unit vector by getting using camera.rotation.x, camera.rotation.y, camera.rotation.z ?
or is there an even easier way?
Thanks so much for your time!
You want to know the direction in world space in which the camera is looking.
In camera space, the camera is located at the origin and is looking down it's negative z-axis.
Pick a point in front of the camera in camera space:
var pLocal = new THREE.Vector3( 0, 0, -1 );
Now transform that point into world space:
var pWorld = pLocal.applyMatrix4( camera.matrixWorld );
You can now construct the desired direction vector:
var dir = pWorld.sub( camera.position ).normalize();
EDIT: Updated for three.js r.57
EDIT: Also see: three.js set and read camera look vector
In revision 69 (not sure in what revision it was introduced), you can call
camera.getWorldDirection()
to get the camera orientation vector.
if your camera is a child of the player object .e.g. in FPS game. Do the same calculation on the player (parent of camera) , and use this (the Bullit gets the right direction, in this case from obj)
Bullit.prototype.getDirection=function(obj){
this.position.add(obj.position);
var pLocal = new THREE.Vector3( 0, 0, -1 );
var pWorld = pLocal.applyMatrix4( obj.matrixWorld );
var dir = pWorld.sub( obj.position ).normalize();
this.direction=dir;
}

Categories

Resources