Fix first person camera rotation

This commit is contained in:
Abdelrahman Said 2024-09-28 19:38:57 +01:00
parent 69cca0d308
commit 6721044b6d

View File

@ -22,6 +22,7 @@
// STDLIB // STDLIB
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
#include <cmath>
#include <string> #include <string>
#include <vector> #include <vector>
@ -39,9 +40,15 @@ enum exit_codes : int {
}; };
struct Camera { struct Camera {
// Point in world coordinates where the camera is located
glm::vec3 position; glm::vec3 position;
// view_direction is an actual direction vector. When used with glm::lookAt, we add it to the position
// to calculate the target the camera is looking at
glm::vec3 view_direction; glm::vec3 view_direction;
glm::vec3 up_vector;
// The up vector in world coordinates
glm::vec3 up;
}; };
struct App { struct App {
@ -166,14 +173,14 @@ int init(App &app) {
); );
app.speed = 0.02f; app.speed = 0.02f;
app.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -1.5f)); app.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 1.5f));
app.rotation = glm::mat4(1.0f); app.rotation = glm::mat4(1.0f);
app.scale = glm::mat4(1.0f); app.scale = glm::mat4(1.0f);
app.camera.position = glm::vec3(0.0f); app.camera.position = glm::vec3(0.0f, 0.0f, 3.0f);
app.camera.view_direction = glm::vec3(0.0f, 0.0f, -1.0f); app.camera.view_direction = glm::vec3(0.0f, 0.0f, -1.0f);
app.camera.up_vector = glm::vec3(0.0f, 1.0f, 0.0f); app.camera.up = glm::vec3(0.0f, 1.0f, 0.0f);
app.model_mat = app.translation * app.rotation * app.scale; app.model_mat = app.translation * app.rotation * app.scale;
app.view_mat = glm::lookAt(app.camera.position, app.camera.view_direction, app.camera.up_vector); app.view_mat = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up);
app.projection_mat = glm::perspective(glm::radians(60.0f), app.projection_mat = glm::perspective(glm::radians(60.0f),
(float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT,
0.1f, 0.1f,
@ -439,12 +446,9 @@ void handle_object_movement(App &app) {
void handle_camera_movement(App &app) { void handle_camera_movement(App &app) {
if (app.event.type == SDL_MOUSEMOTION) { if (app.event.type == SDL_MOUSEMOTION) {
app.current_mouse += glm::vec2(app.event.motion.xrel, app.event.motion.yrel); glm::vec2 offset = glm::vec2(app.event.motion.xrel, 0) * 0.1f;
glm::vec2 mouse_delta = app.prev_mouse - app.current_mouse; app.prev_mouse += offset;
app.camera.view_direction = glm::rotate(app.camera.view_direction, app.camera.view_direction = glm::rotate(app.camera.view_direction, glm::radians(offset.x), app.camera.up);
glm::radians(mouse_delta.x),
app.camera.up_vector);
app.prev_mouse = app.current_mouse;
} else { } else {
switch (app.event.key.keysym.sym) { switch (app.event.key.keysym.sym) {
case SDLK_w: case SDLK_w:
@ -454,15 +458,15 @@ void handle_camera_movement(App &app) {
app.camera.position -= app.camera.view_direction * app.speed; app.camera.position -= app.camera.view_direction * app.speed;
break; break;
case SDLK_d: case SDLK_d:
app.camera.position.x += app.speed; app.camera.position += glm::normalize(glm::cross(app.camera.view_direction, app.camera.up)) * app.speed;
break; break;
case SDLK_a: case SDLK_a:
app.camera.position.x -= app.speed; app.camera.position -= glm::normalize(glm::cross(app.camera.view_direction, app.camera.up)) * app.speed;
break; break;
default: default:
return; return;
} }
} }
app.view_mat = glm::lookAt(app.camera.position, app.camera.view_direction, app.camera.up_vector); app.view_mat = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up);
} }