Changing lookat producing non-intuitive (to me) results

I am still having trouble understanding the effects of changing a camera’s lookat point. If I merely move the camera without changing the lookat point, I understand the behavior, but if I then change the lookat point to rotate the camera to look back at the original point, I am seeing an unexpected rotation about the y-axis.

Below are three drawings. First is the initial drawing with camera at (297, -2323, 2031) and the camera’s lookat point set to (272, -644, 606), shown by the blue sphere.

image

Then I move the camera to the right by 800 units to (1097, -2323, 2031), resulting in the structure moving left and almost off screen but the lookat point remaining fixed because the camera angle has not changed, just the camera x position.

image

That makes sense to me. Now, if I reset the lookat point back to the original value, then the structure moves back into view, as desired and expected, but also produces a rotation about what appears to be (pretty close to) the y-axis, which is not what I expected. Can someone convince me that this non-intuitive (to me, anyway) result is correct, or else, tell me what I’m doing wrong?

image

There is a large amount of code to generate these drawings, so it’s not practical to post it here, but the relevant parts, once the drawing is done, is simple:

camera.position.x += 800;
// re-render

and then

const preferred_lookat = // ...some method to retrieve it
camera.lookAt (preferred_lookat)
// reposition the blue sphere to preferred_lookat
// re-render

Thanks so much.

To clarify, when I move the camera to the right, then the coordinates of the look at point do change – by the same amount as the camera movement – but the position in space of the look at point does not change (i.e., the camera’s world direction remains constant) until I call the camera.lookAt() method to force the look at point back to the original value.

It may be an illusion but it looks like your model is not on the xz plane but on the xy plane, is that correct? The look at method always ensures that an objects z axis remains unrotated (0,1,0) or “up”, if your model is on the xy plane you’ll need to rotate it 90 degrees on to the xz plane to get the desired result you’re after. To clarify, the default forward axis is z and the default up axis is y in threejs

1 Like

Ahhh, that would explain a lot. Yes, z is up for me. Here is the original drawing with the AxesHelper turned on.

image

Okay, how do I “rotate it 90 degrees” and maintain the original view? All my data to draw the model, about 5 MB of JSON, assumes z is up. Thanks.

I assume you’re using ObjectLoader to load the JSON model? You can rotate the object returned by the loader with something like this…

loader.load(url, function(obj){
  obj.rotation.x = -90 * Math.PI / 180
} 

Then it should be as simple as swapping the y and z values in your Vector3’s eg…

(297, -2323, 2031)

Would become

(297, 2031, -2323)

Ummm, actually, no. The JSON data was given to me in its current format, which long pre-dated using Three.js. I read it with a simple JSON.parse() method and then build Three.js mesh data by manually looping over all the parsed JSON, building a Float32Array from all the triangle vertices and another from the triangle normals and then load those into BufferGeometry attributes and then finally build a THREE.Mesh from the geometry. It may not have been the most efficient way to do it, but I eventually made it work. I rather doubt that ObjectLoader would know how to grok the existing JSON data.

Now what? Thanks again.

OK no worries, it’d be the same process, are you creating a single mesh out of the entire geometry? If so you can just apply the rotation to that mesh, otherwise you can add the meshes to a group and rotate the entire group…

Let modelGroup = new THREE.Group()
modelGroup.add(yourJsonMesh1, yourJsonMesh2) 
modelGroup.rotation.x = -90 * Math.PI / 180
scene.add(modelGroup)

Awesome. Thanks. I’ll try that tomorrow.

1 Like

Well, I didn’t quite get to it when I wanted, but this was indeed the answer I needed. Thanks so much. It turns out that for my data I had to switch y and z and then negate the new z, but rotating the group was exactly what I needed to solve my problems. Thanks again.