From eb38a34c936f7422e8a634a866d20a86cdced6ac Mon Sep 17 00:00:00 2001 From: Ritchie Cunningham Date: Tue, 16 Sep 2025 18:59:57 +0100 Subject: [PATCH] [Add] Camera modes, for first person/third person. --- libbettola/include/bettola/math/vec3.h | 4 ++++ src/bettola.cpp | 10 ++++++++-- src/bettola.h | 1 + src/graphics/camera.cpp | 15 ++++++++++----- src/graphics/camera.h | 9 ++++++++- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/libbettola/include/bettola/math/vec3.h b/libbettola/include/bettola/math/vec3.h index 3e99c5e..b062216 100644 --- a/libbettola/include/bettola/math/vec3.h +++ b/libbettola/include/bettola/math/vec3.h @@ -10,4 +10,8 @@ inline Vec3 operator+(const Vec3& a, const Vec3& b) { return {a.x + b.x, a.y + b.y, a.z + b.z}; } +inline Vec3 operator*(const Vec3& v, float scalar) { + return { v.x * scalar, v.y * scalar, v.z * scalar }; +} + } /* namespace BettolaMath. */ diff --git a/src/bettola.cpp b/src/bettola.cpp index 622a20e..0f05386 100644 --- a/src/bettola.cpp +++ b/src/bettola.cpp @@ -8,6 +8,7 @@ #include #include #include "game/player.h" +#include "graphics/camera.h" #include "bettola.h" @@ -18,7 +19,8 @@ const int SCREEN_HEIGHT = 600; Bettola::Bettola(void) : _is_running(false), _window(nullptr), - _gl_context(nullptr) {} + _gl_context(nullptr), + _camera_mode(Camera::CameraMode::FIRST_PERSON) {} Bettola::~Bettola(void) { if(_gl_context) { @@ -87,6 +89,10 @@ void Bettola::process_events(void) { case SDLK_S: _input.down = true; break; case SDLK_A: _input.left = true; break; case SDLK_D: _input.right = true; break; + case SDLK_V: + _camera_mode = (_camera_mode == Camera::CameraMode::FIRST_PERSON) ? + Camera::CameraMode::THIRD_PERSON :Camera::CameraMode::FIRST_PERSON; + break; } } else if(event.type == SDL_EVENT_KEY_UP) { switch(event.key.key) { @@ -115,7 +121,7 @@ void Bettola::update(double dt) { /* Update camera to follow the local player. */ const BettolaMath::Vec3 player_pos = player.get_position(); - _camera.update(player_pos); + _camera.update(player_pos, _camera_mode); } void Bettola::render(void) { diff --git a/src/bettola.h b/src/bettola.h index f00ef0d..97c19d4 100644 --- a/src/bettola.h +++ b/src/bettola.h @@ -32,5 +32,6 @@ private: Renderer _renderer; GameClient _game_client; Camera _camera; + Camera::CameraMode _camera_mode; PlayerBase::InputState _input; }; diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 52951bd..ac19146 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -14,15 +14,20 @@ Camera::Camera(void) : _pitch(0.0f), _distance(10.0f), _mouse_sensitivity(0.1f), - _zoom_sensitivity(0.5f) { + _zoom_sensitivity(0.5f), + _first_person_offset({0.0f, 0.5f, 0.0f}) { _update_camera_vectors(); } -void Camera::update(const BettolaMath::Vec3& target_pos) { - _position.x = target_pos.x - _front.x * _distance; - _position.y = target_pos.y - _front.y * _distance; - _position.z = target_pos.z - _front.z * _distance; +void Camera::update(const BettolaMath::Vec3& target_pos, CameraMode mode) { + if(mode == CameraMode::THIRD_PERSON) { + _position.x = target_pos.x - _front.x * _distance; + _position.y = target_pos.y - _front.y * _distance; + _position.z = target_pos.z - _front.z * _distance; + } else { + _position = target_pos + _first_person_offset + (_front * 0.6f); + } } void Camera::process_mouse_movement(float x_offset, float y_offset) { diff --git a/src/graphics/camera.h b/src/graphics/camera.h index a6755f7..f9e48a5 100644 --- a/src/graphics/camera.h +++ b/src/graphics/camera.h @@ -5,9 +5,15 @@ class Camera { public: + enum class CameraMode { + FIRST_PERSON, + THIRD_PERSON + }; + Camera(void); - void update(const BettolaMath::Vec3& target_pos); + void set_mode(CameraMode mode); + void update(const BettolaMath::Vec3& target_pos, CameraMode mode); void process_mouse_movement(float x_offset, float y_offset); void process_mouse_scroll(float y_offset); @@ -21,6 +27,7 @@ private: float _yaw; float _pitch; float _distance; + BettolaMath::Vec3 _first_person_offset; BettolaMath::Vec3 _position; BettolaMath::Vec3 _front;