This repository has been archived by the owner on Jan 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFreeCamera.h
210 lines (167 loc) · 6.45 KB
/
FreeCamera.h
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/** resources and credit for parts of the code in this source:
Joey de Vries
https://learnopengl.com/#!Getting-started/Camera
https://joeydevries.com/#home
Hammad Mazhar
hammad (at) hamelot.io
http://hamelot.io/visualization/moderngl-camera/
Laurie Bradshaw
see comment section from https://learnopengl.com/#!Getting-started/Camera
resource and credit for how Quaternion words:
A lot of great websites so additional credits goes to all the authors out there who
are contributing to the world wide collection of knoweldge.
**/
//http://disq.us/p/1kicwh7
//This doesn't seem to work. When implemented, it breaks rendering process and window displays empty scene
#ifndef __FREECAMERA_H__
#define __FREECAMERA_H__
#include<glad/glad.h> // for opengl function and type
// for matrices and vector calculation
#define GLM_FORCE_RADIANS
#include<glm/glm.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>
enum class Camera_Movement{
UP,
DOWN,
LEFT,
RIGHT,
FORWARD,
BACKWARD
};
// FOV zooming
enum class ZoomState{
_IN, _OUT
};
class Camera{
private:
float FOV;
float zoomDelta = glm::radians(1.0f);
float aspect;
float nearClip;
float farClip;
glm::vec3 position;
glm::quat orientation; // store rotation and orientation data
glm::vec3 mousePosition; // use to calculate the yaw and pitch rotation.
float mouseSenstivitiy = 0.0009f; // slow down the rate in which the camera rotate
// play around with those two values until you get a roll speed that you like.
const float ROLL_ANGLE = 0.009f; // we're using this because roll depends on the mouse scroll.
float rollDamp = 0.95f; // we're using this because roll depends on the mouse scroll.
float damp = 0.8f; // a value to damp the camera rotational speed
// the angles to rotate the camera by.
float yaw = 0.0f; // rotate about the y axis
float pitch = 0.0f; // rotate about the x axis
float roll = 0.0f; // rotate about the z axis
float twoPI = glm::two_pi<float>(); // check radian bound
float speed = 0.2f; // the linear travel speed of the camera
glm::mat4 perspectiveMatrix;
//glm::mat4 viewMatrix;
glm::vec3 xAxis = glm::vec3(1.0f, 0.0f, 0.0f);
glm::vec3 yAxis = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 zAxis = glm::vec3(0.0f, 0.0f, 1.0f);
void rotate(float angle, const glm::vec3& axis);
public:
float zoom;
Camera() = delete;
///<param name="FOV">The vertical Field of View. In radians</param>
///<param name="windowWidth">The width of the display window</param>
///<param name="windowHeight">The height of the display window</param>
///<param name="near">The near-clipping plane</param>
///<param name="far">The far-clipping plane</param>
///<param name="position">The position of the camera</param>
Camera(float fov, int width, int height, float near, float far);
Camera(float fov, int width, int height, float near, float far, glm::vec3 position);
void Update(float delta = 1.0f);
void ProcessKeyboard(Camera_Movement td, float deltaTime);
void ProcessMouseMovement(float x, float y); // control pitch and yaw
void ProcessMouseScroll(float yOffset); // control roll
void Zoom(ZoomState z);
void SetAspect(float aspect);
void SetMousePosition(float x, float y);
void GetMatrices(glm::mat4& perspective, glm::mat4& view);
glm::mat4 GetViewMatrix();
};
Camera::Camera(float fov, int width, int height, float nearClip, float farClip)
: Camera(fov, width, height, nearClip, farClip, glm::vec3(0.0f, 0.0f, 1.0f)){}
Camera::Camera(float fov, int width, int height, float nearClip, float farClip, glm::vec3 position)
: FOV(fov), aspect(float(width) / float(height)), nearClip(nearClip), farClip(farClip), position(position){
zoom = fov;
perspectiveMatrix = glm::perspective(FOV, aspect, nearClip, farClip);
mousePosition.x = width / 2.0f;
mousePosition.y = height / 2.0f;
}
void Camera::Update(float delta){
if(pitch != 0.0f) rotate(pitch, xAxis);
if(yaw != 0.0f) rotate(yaw, yAxis);
if(roll != 0.0f) rotate(roll, zAxis);
//
//// instead of setting to zero immediately, we have the value eventually go to zero.
pitch *= damp;
yaw *= damp;
roll *= rollDamp;
}
void Camera::rotate(float angle, const glm::vec3& axis){
orientation *= glm::angleAxis(angle, axis * orientation);
}
void Camera::ProcessKeyboard(Camera_Movement td, float deltaTime){
// basically, translating the position vector
float velocity = speed * deltaTime;
if(td == Camera_Movement::UP) position -= glm::vec3(0.0f, speed, 0.0f) * orientation * velocity;
if(td == Camera_Movement::DOWN) position += glm::vec3(0.0f, speed, 0.0f) * orientation * velocity;
if(td == Camera_Movement::LEFT) position += glm::vec3(speed, 0.0f, 0.0f) * orientation * velocity;
if(td == Camera_Movement::RIGHT) position -= glm::vec3(speed, 0.0f, 0.0f) * orientation * velocity;
if(td == Camera_Movement::FORWARD) position += glm::vec3(0.0f, 0.0f, speed) * orientation * velocity;
if(td == Camera_Movement::BACKWARD) position -= glm::vec3(0.0f, 0.0f, speed) * orientation * velocity;
}
void Camera::ProcessMouseMovement(float x, float y){
// updateing yaw
yaw += (x - mousePosition.x) * mouseSenstivitiy;
if(yaw > twoPI) yaw -= twoPI;
else if(yaw < -twoPI) yaw += twoPI;
// updateing pitch
pitch += (y - mousePosition.y) * mouseSenstivitiy;
if(pitch > twoPI) pitch -= twoPI;
else if(pitch < -twoPI) pitch += twoPI;
mousePosition.x = x;
mousePosition.y = y;
}
void Camera::ProcessMouseScroll(float yOffset){
roll -= yOffset * ROLL_ANGLE;
if(roll > twoPI) roll -= twoPI;
else if(roll < -twoPI) roll += twoPI;
}
void Camera::Zoom(ZoomState z){
bool recalculatePerspective = true;
switch (z) {
case ZoomState::_IN:
if((zoom -= zoomDelta) < 0){
zoom = 0;
recalculatePerspective = false;
}
break;
case ZoomState::_OUT:
if((zoom += zoomDelta) > FOV){
zoom = FOV;
recalculatePerspective = false;
}
break;
}
if (recalculatePerspective) perspectiveMatrix = glm::perspective(zoom, aspect, nearClip, farClip);
}
void Camera::SetAspect(float aspect){
this->aspect = aspect;
perspectiveMatrix = glm::perspective(zoom, aspect, nearClip, farClip);
}
// ideally you want to set the mouse position to the center of the scene
void Camera::SetMousePosition(float x, float y){
mousePosition.x = x;
mousePosition.y = y;
}
void Camera::GetMatrices(glm::mat4& perspective, glm::mat4& view){
perspective = perspectiveMatrix;
view = glm::translate(glm::mat4_cast(orientation), position);;
}
glm::mat4 Camera::GetViewMatrix() {
return glm::translate(glm::mat4_cast(orientation), position);
}
#endif