While debugging three.js code, I see following member in a mesh instance(made from THREE.PlaneGeometry):
up
:
THREE.Vector3
x
:
0
y
:
1
z
:
0
What does 'up' signify?
And, if I rotate the mesh by:
rotation.set(Math.PI/2, 0, 0);
Would it impact 'up' too?
What does 'up' signify?
Just have a look at the official documentation. It is used by lookAt() in order to calculate an orientation of a 3D object.
Would it impact 'up' too?
No.
Related
I am currently trying to implement FPS controls And need to detect whether the player is on the ground or flying(or is jumping). So I learned that the Raycaster method from ThreeJs can be used for detecting this.
But how do I implement this approach?
My trial:
let DOWN_DIRECTION = new THREE.Vector3(0, -1, 0);
this._rayCaster = new THREE.Raycaster(this._player._mesh.position, DOWN_DIRECTION, 0, 10);
this._rayCaster.set(this._player._mesh.position, DOWN_DIRECTION);
const intersect = this._rayCaster.intersectObjects(this._player._scene.children, true);
After executing the above snippet, I consoled the intersect value and it returned an empty array.
Original Output: [] empty array
Expected Output: Ground (Plane mesh)
Model Used: Plane for ground, Cuboid for player.
Am I missing something in the code snippet for it to work?
I am trying to set an offset of x coordinates of inflated surfaces, left to 45 and right to -45. Now I have the following scene
I am tried to add and suppose it should solve problem for right and left pials:
if (object.label == 'Right') {
mesh.position.set( -2, 0, 0 );
}
for dataInfo Right and Left files, but it returns TypeError: undefined is not an object (evaluating 'geometry.mesh.center')
Here is the full code of loader:
The line geometry.mesh.center(45,0,0) is definitely wrong since a geometry does not have a mesh property. I'm not sure what the code is supposed to do here but if you want to offset the vertices you should use BufferGeometry.translate() instead:
geometry.translate( 45, 0, 0 );
three.js R111
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) );
I'm trying to have a plane face away from the camera with same orientation so it's aligned in the viewport.
I have a plane in front of the camera, perfectly aligned to the cameras viewport, and I want to flip it in front of the camera, along the objects Y axis, regardless of camera orientation.
The following will orient my plane to face at the camera and works for any orientation:
target.rotation.copy(camera.rotation);
The following will then flip the plane along the plane's Y axis:
target.rotation.y += Math.PI;
All good so far? Except when the camera rotation has a funky tilt to it, let's say it's looking up and to the left, tilted slightly to the right, the plane's flip is tilted, but not the same way as the camera, leaving me with a plane tilted either to the left or right...
I've tried several things such as:
target.rotation.z -= camera.rotation.z;
Nothing... Thanks for your help.
So the problem I was running into was when the camera was in negative z coordinates. This causes the flip on the Y axis to get messed up.
So basically you would do something like this:
var target = new THREE.Object3D();
//position
target.position.copy(s.camera.position);
target.position.add(THREE.Utils.cameraLookDir(s.camera).multiplyScalar(300));
//rotation
target.rotation.copy(s.camera.rotation);
target.rotation.y += PI;
target.rotation.z = -s.camera.rotation.z;
if (s.camera.position.z < 0) {
target.rotation.z = s.camera.rotation.z;
}
EDIT:
Add the following to appropriate spots in your program.
camera.rotation.eulerOrder = 'XZY';
target.rotation.eulerOrder = 'XZY';
Seems to solve previously encountered tilt issues! (see below)
RESOLVED:
Flipped planes tilted the wrong way in some instances, for example when in negative z coords and also the y rotation is not equal to 0, example: point in space hovering and looking at 0, 0, 0.
This is the solution I was looking for when I found this page (taken from this answer):
mesh.lookAt( camera.position );
The local z-axis of the mesh should then point toward the camera.
So, here is a vector, matrix, rotation, quaternion question for the three.js masters!
I have a parent object at position(0,0,275) with direction(0,0,-1), +y up and rotation(0,0,0).
Attached to the parent is a child object with relation:
rel_position(.5, 0, 0)
rel_rotation(0, 0, 0)
I also have a target in the scene:
position(0, 100, 0)
Consider a ship(parent) with pitch, yaw and roll. It has a turret(child) with pitch and yaw. The turret needs to track the target at a given rotational speed (rad/s).
I have spent 5 days trying to get a proper tracking algorithm. The best I can do is remove the matrixAutoUpdate feature on the parent and child updating the matrix manually. Then use the child.matrixWorld to create rotation matrices or quaternions for the current child rotation. Then I can create a secondary Object3D which looks at the target from the child position. I can take the difference between the child and the secondary Object3D and slerp the quaternion on a rad/s basis. However, when I add roll to the parent or the target is rotated outside of octant (+, +, +) the child rotation (or quaternion) calculations crash causing wild rotations.
Any direction on a tracking algorithm for a child Object3D would be immensely appreciated. Your efforts will be cited in my upcoming project.
Thank you for your time!
So here is the answer! #Stemkoski, thanks for the direction. I took a similar approach for a final solution that came to light yesterday. It is a bit a costly in computational power due to inverting a matrix, but it works well. First, create a new matrix as follows:
var m = new THREE.Matrix4().getInverse(parent.matrix).multiply(target.matrix);
This rotates the reference frame of the XYZ axis to new coordinates X'Y'Z' based on the rotation of the parent object. The result is an Object3D matrix of the target in the reference frame of X'Y'Z'. Now by creating a new Vector3 from the matrix 'm' we can get a relative position using:
var rel_pos = new THREE.Vector3().getPositionFromMatrix(m, 'XYZ');
Now create a Faux object to look directly at target from the position of the child(turret)
var child_faux = new THREE.Object3D(); //can be created outside the loop
child_faux.position.copy(child.position); //copy the child local position
child_faux.lookAt(rel_pos); //look at the target
child_faux.updateMatrix(); //Update the Matrix4 element for use in a second
Finally, by setting the child_fuax to lookAt an object we have automatically set the child_faux.rotation. We can obtain the relative rotation between the current child.rotation and the child_faux.rotation using the following:
var diff = turret_target.rotation.sub(turret.rotation);
From here we can set an easy algorithm to rotate the turret (+ or -)(x and y) until the diff (x and y) goes to 0.
var trackrate = .2 * delta;
var diff = turret_target.rotation.sub(turret.rotation);
turret.rotation.x += diff.x/Math.abs(diff.x) * trackrate;
turret.rotation.y += diff.y / Math.abs(diff.y) * trackrate;
turret.updateMatrix();
There we have it...A target tracking algorithm for a child object rotated in a parent group! Thanks for reading!
Perhaps some combination of the lookAt and worldToLocal methods would work? Since you need to convert the position of the target object into local coordinates for the turret, and then change the rotation of the turret accordingly, how about this:
turret.lookAt( turret.worldToLocal( target.position.clone() ) )