Create ArrowHelper with correct rotation - three.js

How do I create an ArrowHelper in Three.js (r58) with correct rotation?
var point1 = new THREE.Vector3(0, 0, 0);
var point2 = new THREE.Vector3(10, 10, 10);
var direction = new THREE.Vector3().subVectors(point1, point2);
var arrow = new THREE.ArrowHelper(direction.normalize(), point1);
console.log(arrow.rotation);
I always end up with with Object {x: 0, y: 0, z: 0} for the arrow rotation. What am I doing wrong?

ArrowHelper uses quaternions to specify it's orientation.
If you do this:
var rotation = new THREE.Euler().setFromQuaternion( arrow.quaternion );
you will see an equivalent orientation expressed in Euler angles, although in r.59, arrow.rotation is now automatically updated, so you will no longer see zeros.
EDIT: answer updated to three.js r.59

Related

Three.js InsatncedMesh rotation on each instance does not change

I am using instancedmesh to show tons of objects on scene.
How can I translate the rotation of each instance likes correct rectangle shape.Current condition is all of the instances are bending to the left side, I want to get red rectangle like below image.
Please check the image link: https://i.stack.imgur.com/jpAhb.png
I tried to set the Eucler and Quaternion on following code but not reflected.
var dummy = new THREE.Object3D();
let finalMatrix = new THREE.Matrix4();
child.geometry.computeBoundingBox();
let matrix = new THREE.Vector3();
let offset = child.geometry.boundingBox.getCenter(matrix);
finalMatrix.makeTranslation(-offset.x, -offset.y, -offset.z);
child.geometry.applyMatrix4(finalMatrix);
dummy.position.copy(offset);
dummy.updateMatrix();
INSTANCEMESH.setMatrixAt(i, dummy.matrix);
INSTANCEMESH.setColorAt(i, child.material.color);
Quaternion
{
"_x": 0,
"_y": 0,
"_z": 0,
"_w": 1
}
Eucler
{
"_x": 0,
"_y": 0,
"_z": 0,
"_order": "XYZ"
}
Do you know how to solve this problem?
Thanks.

Three js raycaster WITHOUT camera

I seem to find only examples to use the raycaster with the camera, but none that just have a raycaster from Point A to Point B.
I have a working raycaster, it retrieves my Helpers, Lines etc. but it seems it does not recognize my sphere.
My first thought was my points are off, so i decided to create a line from my pointA to my pointB with a direction like so:
var pointA = new Vector3( 50, 0, 0 );
var direction = new Vector3( 0, 1, 0 );
direction.normalize();
var distance = 100;
var pointB = new Vector3();
pointB.addVectors ( pointA, direction.multiplyScalar( distance ) );
var geometry = new Geometry();
geometry.vertices.push( pointA );
geometry.vertices.push( pointB );
var material = new LineBasicMaterial( { color : 0xff0000 } );
var line = new Line( geometry, material );
This will show a line from my point (50 0 0) to (50 100 0) right trough my sphere which is at point (50, 50, 0) so my pointA and direction values are correct.
Next i add a raycaster:
To avoid conflicts with any side effects i recreated my points here:
var raycaster = new Raycaster(new Vector3( 50, 0, 0 ), new Vector3( 0, 1, 0 ).normalize());
var intersects = raycaster.intersectObject(target);
console.log(intersects);
Seems pretty straight forward to me, i also tried to use raycaster.intersectObjects(scene.children) but it gives Lines, helpers etc. but not my sphere.
What am i doing wrong? I am surely missing something here.
IMG of the line and the sphere:
What you see is explained in the following github issue:
https://github.com/mrdoob/three.js/issues/11449
The problem is that the ray emitted from THREE.Raycaster does not directly hit a face but its vertex which results in no intersection.
There are several workarounds to solve this issue e.g. slightly shift the geometry or the ray. For your case:
var raycaster = new THREE.Raycaster( new THREE.Vector3( 50, 0, 0 ), new THREE.Vector3( 0, 1, 0.01 ).normalize() );
However, a better solution is to fix the engine and make the test more robust.
Demo: https://jsfiddle.net/kzwmoug2/3/
three.js R106

How to move an object in particular direction with specific distance in three.js

I need to move an object along directional vector through some distance. I fount translateOnAxis(vector, distance) of Object3D class. But I'm not able to understand how it works.
I've an object- sphere. I'm scaling it to look like ellipse. And setting position and direction. Now I need this object to move in the same direction which I'm setting it to, through some distance. When I apply it, I can't see the object. Can anybody suggest how it can be achieved?
var geometry = new THREE.SphereGeometry( radius, 64, 64, 0, -Math.PI );
geometry.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, zScale ); //scaling it to look like ellipse
var direction = new THREE.Vector3( xDir, yDir, zDir);
var ellipse = new THREE.Mesh( geometry, material );
ellipse.lookAt(direction);
ellipse.position.set( xPos, yPos, zPos);
ellipse.translateOnAxis(direction, distance);
Your pasted code is buggy.
You're missing a ) on your applyMatrix line.
Are you using a debugger and observing console errors/warnings?

How to rotate an object to make it face a certain direction?

If I know what direction an object is facing for example (0, 0, 1). What is the easiest way to rotate the object to face a direction vector of (1, 1, 1)?
Edit:
I've tried this, but something is wrong with this logic:
var newDir = new THREE.Vector3(1,1,1);
var objectDir= new THREE.Vector3(0, 0, 1);
objectDir.applyQuaternion(object.quaternion); // rotate this vector to object's facing direction
var pos = new THREE.Vector3();
pos.addVectors(newDir, object.position);
var axis = objectDir.cross(newDir).normalize();
var angle = objectDir.angleTo(pos);
object.rotateOnAxis(axis, angle);
Solved it with lookAt:
var newDir = new THREE.Vector3(1, 1, 1);
var pos = new THREE.Vector3();
pos.addVectors(newDir, object.position);
object.lookAt(pos);

Find the coordinates of the topleft of the canvas on the xy plane given a camera

I think this is an ok way to get the xyplane (if this is wrong or there is a better way, let me know):
xyplane = new THREE.Plane().setFromCoplanarPoints(
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(10, 15, 0),
new THREE.Vector3(100, -90, 0),
);
I have a camera which happens to be at (0, 0, 1000) looking at the origin. I can find a coordinate that is the exact top left of my viewing port:
projector = new THREE.Projector();
topleft = new THREE.Vector3(-1, 1, 0);
through = projector.unprojectVector(topleft, camera);
through is then THREE.Vector3 {x: -31.425217496422327, y: 22.169468302342334, z: 900.0000201165681} which is perfectly at the topleft of the canvas. However, I want to find the equivalent point where z = 0. I try to do this with a ray; but, I fail.
ray = new THREE.Ray(camera.position, through);
point = ray.intersectPlane(xyplane);
point is then {x: 34.91690754890442, y: -24.632742007573448, z: 0} which is not even close. I'm misunderstanding something basic. I will study Coordinates of intersection between Ray and Plane and others while I try to figure this out. Maybe someone can explain in plain language.
Right, thanks to #WestLangley for the comment. The through variable is not the correct second argument to the Ray constructor. We need a unit vector for direction. With the camera position and the through point, we can get a direction vector with:
direction = through.sub(camera.position).normalize();
Then the rest works as expected:
ray = new THREE.Ray(camera.position, direction);
p = ray.intersectPlane(xyplane);

Resources