I am building a sort of object viewer in javascript. In said object viewer you can move de camera further away (3rd person camera), move it closer (inverse 3rd person camera?) or have it at it's starting position (1st person camera).
The type of camera I am trying to build is the type you get in a 1st person game (e.g. Fortnite).
I started with a guide on how to calculate the point on a circle. And using the results from the "vertical circle" to calculate the "horizontal circle" (see code below).
The end result is close to how I would like the camera to work. When moving the camera JUST up and down, it looks like a 3rd person camera, and when moving the camera JUST to the left and right it looks fine. But whenever my camera is off center on both axis, moving up/down also moves slight left/right (and vice versa).
In your average game looking up/down always just goes STRAIGHT up, not in some sort of bend way like mine.
I figured I had to calculate the point on a sphere, not on a circle. So I found a guide on how to do just that. But, alas... the end results appears to be the same (or very similar).
What am I missing here, is my thought process just plain wrong? How to make the camera work like the ones in 3rd person games.
Two 2d calculations
function syncCamera() {
let offset_for_y = Math.abs(zoom);
let camera_y = camera.position.y;
let degrees_y = Math.abs(camera_y) * 90;
let degrees_y_sin = sin(degrees_y);
let position_y = offset_for_y * degrees_y_sin;
let degrees_y_cos = cos(degrees_y);
let offset_for_x = offset_for_y * degrees_y_cos;
let camera_x = camera.position.x;
let degrees_x = Math.abs(camera_x) * 90;
let degrees_x_cos = cos(degrees_x);
let position_x = offset_for_x * degrees_x_cos;
let degrees_x_sin = sin(degrees_x);
let position_z = offset_for_x * degrees_x_sin;
if (zoom > 0) { // moved closer
if (camera_y < 0) { // looking up
scene.position.y = -Math.abs(position_y);
} else { // looking down
scene.position.y = position_y;
}
scene.position.z = position_x;
if (camera_x < 0) { // looking right
scene.position.x = -Math.abs(position_z);
} else { // looking left
scene.position.x = position_z;
}
} else if (zoom < 0) { // moved further away
if (camera_y < 0) { // looking up
scene.position.y = position_y;
} else { // looking down
scene.position.y = -Math.abs(position_y);
}
scene.position.z = -Math.abs(position_x);
if (camera_x < 0) { // looking right
scene.position.x = position_z;
} else { // looking left
scene.position.x = -Math.abs(position_z);
}
} else { // center
scene.position.x = 0;
scene.position.y = 0;
scene.position.z = 0;
}
}
3D calculations
function syncCamera() {
let offset = zoom;
let camera_x = camera.position.x;
let camera_y = camera.position.y;
let phi = (camera_y + 1) / 2 * 180;
let theta = camera_x * 90;
let z = offset * Math.cos(radian(theta)) * Math.sin(radian(phi));
let x = offset * Math.sin(radian(theta)) * Math.sin(radian(phi));
let y = offset * Math.cos(radian(phi));
scene.position.x = x;
scene.position.y = reverse_sign(y); // reverse_sign switches positive/negative numbers.
scene.position.z = z;
}
Please note that the x,y,z axises seem to be labelled different in my software package. Y = up/down, X = left/right, Z = forward/backwards. Most pictures I find on axis are different.