I want to move the camera with a rotation from one point to another one (following the surface of a sphere). The camera is looking at the center of one object.
I use the following code that works, but I’m not sure if it is correct.
rotateCameraTo (cameraX, cameraY, cameraZ, time) {
const camera = this._camera.camera;
const initialCamera = new Vector3().copy(camera.position);
const cameraVectorStart = new Vector3(camera.position.x, camera.position.y, camera.position.z);
const cameraVectorEnd = new Vector3(cameraX, cameraY, cameraZ);
cameraVectorStart.normalize();
cameraVectorEnd.normalize();
let qa = new Quaternion(0, 0, 0, 1);
let qb = new Quaternion().setFromUnitVectors(cameraVectorStart, cameraVectorEnd);
let qm = new Quaternion();
let ti = { t: 0 };
new TWEEN.Tween(ti)
.to({ t: 1 }, time)
.easing(TWEEN.Easing.Quadratic.InOut)
.onUpdate(function () {
camera.position.set(initialCamera.x, initialCamera.y, initialCamera.z);
qm.slerpQuaternions(qa, qb, ti.t);
camera.position.applyQuaternion(qm);
//At the moment the object is centered in the origin
camera.lookAt(0, 0, 0);
})
.onComplete(function () {
window.cancelAnimationFrame(animationID);
})
.start();
}
Things that I don’t know if there are correct:
I set the camera to initial position every .onUpdate().
I use let qa = new Quaternion(0, 0, 0, 1) because it works but I’m not sure about this.
If there is a better solution than use quaternions
Another doubt is if it is possible to get another path instead the shorter from one point to the other one. This is because I prefer to rotate with Y as a pivot, but If I use points with different values of Y it does not work.
What if I use OrbitControls, where the camera is always looking at the target, but I want to use a button that also starts a movement above the target which would also trigger a gimble lock? Would I need to disable the controls, tween the quaternion, tween the position and then turn it back on?
Sadly when setting orbitControls.enable = false I still can control it which seems to be a bug.
In theory, using quaternions avoids gimbal lock. With the code in my post, I achieved rotation without experiencing gimbal lock. Another issue I encountered was that I didn’t want to take the shortest path. One solution was to chain two tweens (with one point more) to modify the path and avoidgo over the model like in this image.
I don’t remember, it was 1-2 years ago, and I don’t work there anymore so I don’t have access to the code. I think it was related to finding the midpoint and moving it in the X or Z direction based on certain values. However, there should be a better way.