One of my favorite topics!
Here is a completely different approach that I use to accomplish the same thing.
I link the camera to a 3D object, which acts like a “selfie stick”.
I then link the 3D object to the 3D object of interest so that it is holding the stick
I use mouse input to orbit the camera around the object of interest:
- mouseX = longitude
- mouseY = latitude.
Here is some sample code:
// Camera Variables
let CamDst = 500; // distance from object you are looking at
let CamLat = 30; // vertical position of camera (+/-90 degrees) 30 = up
let CamLon = 0; // horizontal position of camera (0-360 degrees) 0 = straight ahead
let LatMax = 90; // limit input value to 90 degrees, so you don't go "upside down"
let LatMin = -90; // Same for down
// Create Camera and Holder
const camera = new THREE.PerspectiveCamera(45, width/height, 1, 15000);
camera.rotation.order = "YXZ";
const camobj = new THREE.Object3D(); // This is like a camera "selfie stick" that holds the camera
camobj.rotation.order = "YXZ"; // You rotate the "stick" to position the camera in space
camobj.add(camera); // Attach the camera to the stick
camera.position.z = -CamDst; // Length of "stick"
camera.rotation.y = 180*DegRad; // Camera looks towards the object holding the "stick"
// Object of Interest (you can add the mesh later)
const ctrobj = new THREE.Object3D(); // Create object
ctrobj.rotation.order = "YXZ";
ctrobj.add(camobj); // Attach camera "stick" to the object
scene.add(ctrobj);
// I use mouse input to rotate the lat/lon of the "stick", which causes the camera to orbit the object:
// * up/down changes latitude (limit to +/-90 degrees)
// * left/right changes longitude
// * mouse wheel changes distance from object
// I call the function below with each frame (but it is so small, you can just include it in your code)
function moveCamera() {
camera.position.z = -CamDst; // in case, change distance from object
camobj.rotation.x = Mod360(CamLat)*DegRad;
camobj.rotation.y = Mod360(CamLon+180)*DegRad;
}
Note: that you can also “bank” the camera using rotation.z - something you can’t do with LookAt
Also, note: I am using 3Dobjects, rather than just a mesh because you can link to a 3Dobject.
This is a pretty flexible setup:
- You can easily look outwards (just make camera.roation.y = 0)
- You can attach the camera holder to different objects of interest (e.g. different planets rotating the sun) to look at them.
- You can use linked objects to change the orientation of your axis.