Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three.js - how do up vectors work with lookAt()?

I'm trying to understand how up vectors and lookAt() work together in three.js. I'm setting the up vector of this axisHelper, so that the Y axis always points at the target geo, which marks the position of the up vector. It works as expected for X and Y, rotating the axes around the Z axis; and when I try to adjust the Z value of the up vector I would expect the axes to rotate around the X axis, but nothing happens.

http://jsfiddle.net/68p5r/4/ [Edit: I've added geo to show the up target position.]

I have a dat.gui interface manipulating the up vector to demonstrate, but the problem exists when I set the vector manually as well.

I suspect the problem is around line 74:

zControl.onChange(function(value) {
  axes.up.set(this.object.x, this.object.y, value);
  axes.lookAt(new THREE.Vector3(0, 0, 1));
});

When I update the up vector, I instruct the axisHelper to update its orientation onscreen by redoing its lookAt() down its Z axis. Changing the X and Y works as expected, why not the Z?

(This is also the case if I use geo instead of an axisHelper: http://jsfiddle.net/68p5r/5/)

rotated axisHelper

like image 730
meetar Avatar asked Dec 10 '13 22:12

meetar


2 Answers

When you call Object.lookAt( vector ), the object is rotated so that its internal z-axis points toward the target vector.

But that is not sufficient to specify the object's orientation, because the object itself can still be "spun" on its z-axis.

So the object is then "spun" so that its internal y-axis is in the plane of its internal z-axis and the up vector.

The target vector and the up vector are, together, sufficient to uniquely specify the object's orientation.

three.js r.63


Tip: An axis in three.js should always have unit length; be sure to call axis.normalize() in your code.

like image 81
WestLangley Avatar answered Oct 19 '22 11:10

WestLangley


I assume your title meant rotate on Z instead of X?

Anyways, the culprit seems to be axes.lookAt(new THREE.Vector3(0, 0, 1)); if you change that to axes.lookAt(new THREE.Vector3(0, 1, 0)); for all methods then Y doesn't rotate as expected. You are telling the axis helper to look down a specific axis (in your case Z). Hence why Z value isn't working.

Is there an example of what your trying to accomplish that might help us?

Maybe someone else can give a bit more in depth explanation of what's happening. Hopefully my answer will push you in the right direction.

like image 41
Grant Avatar answered Oct 19 '22 11:10

Grant