I have a basic question, but I could not find the answer.
I noticed that the following code:
const p = new THREE.Vector3();
const q = new THREE.Quaternion();
const s = new THREE.Vector3();
function setPositionAndRotation(o) {
o.position.set(1, 1, -1);
o.lookAt(0, 0, 0);
o.updateMatrix();
o.matrix.decompose(p, q, s);
console.log(JSON.stringify(q));
}
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, .01, 1000);
var mesh = new THREE.Mesh(new THREE.Geometry(), new THREE.MeshBasicMaterial());
setPositionAndRotation(camera);
setPositionAndRotation(mesh);
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js"></script>
produces different quaternions for Camera and Object3D:
{"_x":-0.11591689595929515,"_y":0.8804762392171493,"_z":0.27984814233312133,"_w":0.36470519963100095}
{"_x":0.27984814233312133,"_y":-0.3647051996310009,"_z":0.11591689595929516,"_w":
(These are two quaternions pointing into opposite directions on Z axis.)
The problems lies in the bahavior of the lookAt
function. I dug into source code of Object3d and I found this if
https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js#L331
if ( this.isCamera ) {
m1.lookAt( position, target, this.up );
} else {
m1.lookAt( target, position, this.up );
}
As you can see Object3D
is handled differently than Camera
. target
and position
are swapped.
Object3D's documentation says:
lookAt ( x : Float, y : Float, z : Float ) : null
Rotates the object to face a point in world space.
but the code does the opposite. It uses Matrix4's lookAt function
lookAt ( eye : Vector3, center : Vector3, up : Vector3, ) : this
Constructs a rotation matrix, looking from eye towards center oriented by the up vector.
putting target
into eye
, and position
into center
.
I can deal with that, but it is weird. Is there anybody able to explain why it is so?
r.97
LookAt
I just addobject3d.isCamera = true
– pery mimon