bsp viewer
[tar-legacy.git] / MCDV / Camera.hpp
1 #pragma once
2
3 #include <GLFW\glfw3.h>
4
5 #include <glm\glm.hpp>
6 #include <glm\gtc\matrix_transform.hpp>
7 #include <glm\gtc\type_ptr.hpp>
8
9 #include "GLFWUtil.hpp"
10
11 #include <iostream>
12
13
14 class Camera
15 {
16 private:
17 bool firstMouse = true;
18
19 bool lastStatus = false;
20
21 double lastX = 400;
22 double lastY = 300;
23
24
25
26
27 //Used for true fps control
28 glm::vec3 travelFront = glm::vec3(0.0f, 0.0f, 1.0f);
29
30 float yaw = 90.0f;
31 float pitch = 0.0f;
32
33 util_keyHandler* keyHandler;
34 public:
35 glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, 1.0f);
36 glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
37 glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, -16.0f);
38
39 float sensitivity = 0.05f;
40 float speed = 2.5f;
41 float fov = 90.0f;
42
43 float near_z = 0.1f;
44 float far_z = 1000.0f;
45
46 float pitch_max = 89.0f;
47 float pitch_min = -89.0f;
48
49 int window_width = 800;
50 int window_height = 600;
51
52 bool isNoclip = true;
53
54 void handleInput(float deltaTime);
55
56 void mouseUpdate(double xpos, double ypos, bool isClicking = true);
57
58 glm::mat4 getViewMatrix();
59 glm::mat4 getProjectionMatrix();
60
61 glm::vec3 getViewRay(double xpos, double ypos, int viewWidth, int viewHeight);
62
63 Camera(util_keyHandler* keyHandler);
64 Camera();
65 ~Camera();
66 };
67
68 glm::vec2 getNormalizedDeviceCoords(double xpos, double ypos, int viewWidth, int viewHeight) {
69 float x = (2.0f * xpos) / viewWidth - 1.0f;
70 float y = (2.0f * ypos) / viewHeight - 1.0f;
71
72 return glm::vec2(x, -y);
73 }
74
75 glm::vec4 calculateViewCoords(glm::vec4 clipCoords, glm::mat4 projectionMatrix)
76 {
77 glm::mat4 inverted = glm::inverse(projectionMatrix);
78 glm::vec4 viewCoords = inverted * clipCoords;
79 return glm::vec4(viewCoords.x, viewCoords.y, -1.0f, 0.0f);
80 }
81
82 glm::vec3 calculateWorldVector(glm::vec4 viewCoords, glm::mat4 viewMatrix)
83 {
84 glm::mat4 inverted = glm::inverse(viewMatrix);
85 glm::vec4 worldCoord = inverted * viewCoords;
86 glm::vec3 mouseRay = glm::vec3(worldCoord.x, worldCoord.y, worldCoord.z);
87 mouseRay = glm::normalize(mouseRay);
88 return mouseRay;
89 }
90
91 glm::vec3 calculateMouseRay(double xpos, double ypos, int viewWidth, int viewHeight, glm::mat4 projectionMatrix, glm::mat4 viewMatrix) {
92 glm::vec2 normalizedCoords = getNormalizedDeviceCoords(xpos, ypos, viewWidth, viewHeight);
93 glm::vec4 clipCoords = glm::vec4(normalizedCoords.x, normalizedCoords.y, -1.0f, 1.0f);
94 glm::vec4 viewCoords = calculateViewCoords(clipCoords, projectionMatrix);
95 glm::vec3 worldRay = calculateWorldVector(viewCoords, viewMatrix);
96 return worldRay;
97 }
98
99 glm::vec3 Camera::getViewRay(double xpos, double ypos, int viewWidth, int viewHeight)
100 {
101 return calculateMouseRay(xpos, ypos, viewWidth, viewHeight, this->getProjectionMatrix(), this->getViewMatrix());
102 }
103
104
105 Camera::Camera()
106 {
107
108 }
109
110 void Camera::handleInput(float deltaTime)
111 {
112 glm::vec3 travelDir = cameraFront;
113
114 if (!isNoclip)
115 travelDir = this->travelFront;
116
117 if (keyHandler->getKeyDown(GLFW_KEY_LEFT_SHIFT))
118 this->speed = 20.0f;
119 else
120 this->speed = 2.5f;
121
122 if (keyHandler->getKeyDown(GLFW_KEY_W))
123 cameraPos += speed * travelDir * deltaTime;
124
125 if (keyHandler->getKeyDown(GLFW_KEY_S))
126 cameraPos -= speed * travelDir * deltaTime;
127
128 if (keyHandler->getKeyDown(GLFW_KEY_A))
129 cameraPos -= glm::normalize(glm::cross(travelDir, cameraUp)) * speed * deltaTime;
130
131 if (keyHandler->getKeyDown(GLFW_KEY_D))
132 cameraPos += glm::normalize(glm::cross(travelDir, cameraUp)) * speed * deltaTime;
133 }
134
135 void Camera::mouseUpdate(double xpos, double ypos, bool isClicking)
136 {
137 if (isClicking && (isClicking != this->lastStatus)) {
138 lastX = xpos;
139 lastY = ypos;
140 }
141
142 this->lastStatus = isClicking;
143
144 if (!isClicking)
145 return;
146
147 //Removes first movement skips
148 if (firstMouse)
149 {
150 lastX = xpos;
151 lastY = ypos;
152
153 firstMouse = false;
154 }
155
156 float xoffset = xpos - lastX;
157 float yoffset = lastY - ypos;
158
159 lastX = xpos;
160 lastY = ypos;
161
162 xoffset *= (fov / 90.0f) * this->sensitivity;
163 yoffset *= (fov / 90.0f) * this->sensitivity;
164
165 this->yaw = glm::mod(this->yaw + xoffset, 360.0f);
166 this->pitch = glm::clamp(this->pitch + yoffset, this->pitch_min, this->pitch_max);
167
168 //Front facing vector
169 glm::vec3 front;
170 front.x = cos(glm::radians(this->pitch)) * cos(glm::radians(this->yaw));
171 front.y = sin(glm::radians(this->pitch));
172 front.z = cos(glm::radians(this->pitch)) * sin(glm::radians(this->yaw));
173
174 //Used for fps movement
175 glm::vec3 tFront;
176 tFront.x = cos(glm::radians(this->yaw));
177 tFront.z = sin(glm::radians(this->yaw));
178 tFront.y = 0;
179
180 //Update class vectors
181 this->cameraFront = glm::normalize(front);
182 this->travelFront = glm::normalize(tFront);
183 }
184
185 glm::mat4 Camera::getViewMatrix()
186 {
187 return glm::lookAt(this->cameraPos, this->cameraPos + this->cameraFront, this->cameraUp);
188 }
189
190 glm::mat4 Camera::getProjectionMatrix()
191 {
192 return glm::perspective(glm::radians(fov / 2), (float)window_width / (float)window_height, near_z, far_z);
193 }
194
195 Camera::Camera(util_keyHandler* keyHandler)
196 {
197 this->keyHandler = keyHandler;
198 }
199
200 Camera::~Camera()
201 {
202 }
203
204