hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/core/camera.cpp
blob: f580191252cd5661d60eaa6da18ae42db467c246 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#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 world_up(0.0f, 1.0f, 0.0f);
        glm::vec3 front = glm::normalize(direction);
        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_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();
    }
}