aboutsummaryrefslogtreecommitdiff
path: root/src/Core/Camera.cpp
blob: 4dff2d736bfd4e7339df55dae32331ed6cef59c5 (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 aspectRatio, float nearPlane, float farPlane)
        : m_FOV(fov), m_AspectRatio(aspectRatio), m_NearPlane(nearPlane), m_FarPlane(farPlane)
    {
        RecalculateProjectionMatrix();
        RecalculateViewMatrix();
    }

    void Camera::SetProjection(float fov, float aspectRatio, float nearPlane, float farPlane)
    {
        m_FOV = fov;
        m_AspectRatio = aspectRatio;
        m_NearPlane = nearPlane;
        m_FarPlane = farPlane;
        RecalculateProjectionMatrix();
    }

    void Camera::RecalculateProjectionMatrix()
    {
        m_ProjectionMatrix = glm::perspective(glm::radians(m_FOV), m_AspectRatio, m_NearPlane, m_FarPlane);
        m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
    }

    void Camera::RecalculateViewMatrix()
    {
        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 worldUp(0.0f, 1.0f, 0.0f);
        glm::vec3 front = glm::normalize(direction);
        glm::vec3 right = glm::normalize(glm::cross(front, worldUp));
        glm::vec3 up    = glm::normalize(glm::cross(right, front));

        m_ViewMatrix           = glm::lookAt(m_Position, m_Position + front, up);
        m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
    }

    glm::vec3 Camera::GetForwardDirection() 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::GetRightDirection() const
    {
        glm::vec3 worldUp(0.0f, 1.0f, 0.0f);
        return glm::normalize(glm::cross(GetForwardDirection(), worldUp));
    }

    glm::vec3 Camera::GetUpDirection() const
    {
        return glm::normalize(glm::cross(GetRightDirection(), GetForwardDirection()));
    }

    void Camera::OnMouseMove(float xOffset, float yOffset, bool constrainPitch)
    {
        xOffset *= m_MouseSensitivity;
        yOffset *= m_MouseSensitivity;

        m_Rotation.y += xOffset;
        m_Rotation.x += yOffset;

        if (constrainPitch)
        {
            if (m_Rotation.x > 89.0f)
                m_Rotation.x = 89.0f;
            if (m_Rotation.x < -89.0f)
                m_Rotation.x = -89.0f;
        }

        RecalculateViewMatrix();
    }

    void Camera::MoveForward(float deltaTime)
    {
        m_Position += GetForwardDirection() * m_MovementSpeed * deltaTime;
        RecalculateViewMatrix();
    }

    void Camera::MoveBackward(float deltaTime)
    {
        m_Position -= GetForwardDirection() * m_MovementSpeed * deltaTime;
        RecalculateViewMatrix();
    }

    void Camera::MoveRight(float deltaTime)
    {
        m_Position += GetRightDirection() * m_MovementSpeed * deltaTime;
        RecalculateViewMatrix();
    }

    void Camera::MoveLeft(float deltaTime)
    {
        m_Position -= GetRightDirection() * m_MovementSpeed * deltaTime;
        RecalculateViewMatrix();
    }

    void Camera::MoveUp(float deltaTime)
    {
        glm::vec3 worldUp(0.0f, 1.0f, 0.0f);
        m_Position += worldUp * m_MovementSpeed * deltaTime;
        RecalculateViewMatrix();
    }

    void Camera::MoveDown(float deltaTime)
    {
        glm::vec3 worldUp(0.0f, 1.0f, 0.0f);
        m_Position -= worldUp * m_MovementSpeed * deltaTime;
        RecalculateViewMatrix();
    }
}