hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/core/camera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/camera.cpp')
-rw-r--r--src/core/camera.cpp132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/core/camera.cpp b/src/core/camera.cpp
new file mode 100644
index 0000000..bad2919
--- /dev/null
+++ b/src/core/camera.cpp
@@ -0,0 +1,132 @@
+#include "camera.h"
+#include <glm/gtc/quaternion.hpp>
+
+namespace Donut
+{
+ Camera::Camera(float fov, float aspect_ratio, float near_plane, float far_plane)
+ : m_fov(fov), m_aspect_ratio(aspect_ratio), m_near_plane(near_plane), m_far_plane(far_plane)
+ {
+ recalculate_projection_matrix();
+ recalculate_view_matrix();
+ }
+
+ void Camera::set_projection(float fov, float aspect_ratio, float near_plane, float far_plane)
+ {
+ m_fov = fov;
+ m_aspect_ratio = aspect_ratio;
+ m_near_plane = near_plane;
+ m_far_plane = far_plane;
+ recalculate_projection_matrix();
+ }
+
+ void Camera::recalculate_projection_matrix()
+ {
+ m_projection_matrix = glm::perspective(glm::radians(m_fov), m_aspect_ratio, m_near_plane, m_far_plane);
+ m_view_projection_matrix = m_projection_matrix * m_view_matrix;
+ }
+
+ void Camera::recalculate_view_matrix()
+ {
+ float pitch = glm::radians(m_rotation.x);
+ float yaw = glm::radians(m_rotation.y);
+ float roll = glm::radians(m_rotation.z);
+
+ glm::vec3 direction;
+ direction.x = cos(yaw) * cos(pitch);
+ direction.y = sin(pitch);
+ direction.z = sin(yaw) * cos(pitch);
+
+ glm::vec3 front = glm::normalize(direction);
+ glm::vec3 world_up(0.0f, 1.0f, 0.0f);
+ glm::vec3 right = glm::normalize(glm::cross(front, world_up));
+ glm::vec3 up = glm::normalize(glm::cross(right, front));
+
+ m_view_matrix = glm::lookAt(m_position, m_position + front, up);
+ m_view_projection_matrix = m_projection_matrix * m_view_matrix;
+ }
+
+ glm::vec3 Camera::get_forward_direction() const
+ {
+ float pitch = glm::radians(m_rotation.x);
+ float yaw = glm::radians(m_rotation.y);
+
+ glm::vec3 direction;
+ direction.x = cos(yaw) * cos(pitch);
+ direction.y = sin(pitch);
+ direction.z = sin(yaw) * cos(pitch);
+
+ return glm::normalize(direction);
+ }
+
+ glm::vec3 Camera::get_right_direction() const
+ {
+ glm::vec3 world_up(0.0f, 1.0f, 0.0f);
+ return glm::normalize(glm::cross(get_forward_direction(), world_up));
+ }
+
+ glm::vec3 Camera::get_up_direction() const
+ {
+ return glm::normalize(glm::cross(get_right_direction(), get_forward_direction()));
+ }
+
+ void Camera::on_update(float delta_time)
+ {
+ }
+
+ void Camera::on_mouse_move(float x_offset, float y_offset, bool constrain_pitch)
+ {
+ x_offset *= m_mouse_sensitivity;
+ y_offset *= m_mouse_sensitivity;
+
+ m_rotation.y += x_offset;
+ m_rotation.x += y_offset;
+
+ if (constrain_pitch)
+ {
+ if (m_rotation.x > 89.0f)
+ m_rotation.x = 89.0f;
+ if (m_rotation.x < -89.0f)
+ m_rotation.x = -89.0f;
+ }
+
+ recalculate_view_matrix();
+ }
+
+ void Camera::move_forward(float delta_time)
+ {
+ m_position += get_forward_direction() * m_movement_speed * delta_time;
+ recalculate_view_matrix();
+ }
+
+ void Camera::move_backward(float delta_time)
+ {
+ m_position -= get_forward_direction() * m_movement_speed * delta_time;
+ recalculate_view_matrix();
+ }
+
+ void Camera::move_right(float delta_time)
+ {
+ m_position += get_right_direction() * m_movement_speed * delta_time;
+ recalculate_view_matrix();
+ }
+
+ void Camera::move_left(float delta_time)
+ {
+ m_position -= get_right_direction() * m_movement_speed * delta_time;
+ recalculate_view_matrix();
+ }
+
+ void Camera::move_up(float delta_time)
+ {
+ glm::vec3 world_up(0.0f, 1.0f, 0.0f);
+ m_position += world_up * m_movement_speed * delta_time;
+ recalculate_view_matrix();
+ }
+
+ void Camera::move_down(float delta_time)
+ {
+ glm::vec3 world_up(0.0f, 1.0f, 0.0f);
+ m_position -= world_up * m_movement_speed * delta_time;
+ recalculate_view_matrix();
+ }
+}