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
|
#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();
}
}
|