diff options
Diffstat (limited to 'src/core/camera.cpp')
| -rw-r--r-- | src/core/camera.cpp | 132 |
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(); + } +} |
