3 #include <GLFW\glfw3.h>
6 #include <glm\gtc\matrix_transform.hpp>
7 #include <glm\gtc\type_ptr.hpp>
9 #include "GLFWUtil.hpp"
17 bool firstMouse = true;
19 bool lastStatus = false;
27 //Used for true fps control
28 glm::vec3 travelFront = glm::vec3(0.0f, 0.0f, 1.0f);
32 util_keyHandler* keyHandler;
34 glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, 1.0f);
35 glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
36 glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, -16.0f);
41 float sensitivity = 0.05f;
46 float far_z = 1000.0f;
48 float pitch_max = 89.0f;
49 float pitch_min = -89.0f;
51 int window_width = 800;
52 int window_height = 600;
56 void handleInput(float deltaTime);
58 void mouseUpdate(double xpos, double ypos, bool isClicking = true);
60 glm::mat4 getViewMatrix();
61 glm::mat4 getProjectionMatrix();
63 glm::vec3 getViewRay(double xpos, double ypos, int viewWidth, int viewHeight);
65 Camera(util_keyHandler* keyHandler);
70 glm::vec2 getNormalizedDeviceCoords(double xpos, double ypos, int viewWidth, int viewHeight) {
71 float x = (2.0f * xpos) / viewWidth - 1.0f;
72 float y = (2.0f * ypos) / viewHeight - 1.0f;
74 return glm::vec2(x, -y);
77 glm::vec4 calculateViewCoords(glm::vec4 clipCoords, glm::mat4 projectionMatrix)
79 glm::mat4 inverted = glm::inverse(projectionMatrix);
80 glm::vec4 viewCoords = inverted * clipCoords;
81 return glm::vec4(viewCoords.x, viewCoords.y, -1.0f, 0.0f);
84 glm::vec3 calculateWorldVector(glm::vec4 viewCoords, glm::mat4 viewMatrix)
86 glm::mat4 inverted = glm::inverse(viewMatrix);
87 glm::vec4 worldCoord = inverted * viewCoords;
88 glm::vec3 mouseRay = glm::vec3(worldCoord.x, worldCoord.y, worldCoord.z);
89 mouseRay = glm::normalize(mouseRay);
93 glm::vec3 calculateMouseRay(double xpos, double ypos, int viewWidth, int viewHeight, glm::mat4 projectionMatrix, glm::mat4 viewMatrix) {
94 glm::vec2 normalizedCoords = getNormalizedDeviceCoords(xpos, ypos, viewWidth, viewHeight);
95 glm::vec4 clipCoords = glm::vec4(normalizedCoords.x, normalizedCoords.y, -1.0f, 1.0f);
96 glm::vec4 viewCoords = calculateViewCoords(clipCoords, projectionMatrix);
97 glm::vec3 worldRay = calculateWorldVector(viewCoords, viewMatrix);
101 glm::vec3 Camera::getViewRay(double xpos, double ypos, int viewWidth, int viewHeight)
103 return calculateMouseRay(xpos, ypos, viewWidth, viewHeight, this->getProjectionMatrix(), this->getViewMatrix());
112 void Camera::handleInput(float deltaTime)
114 glm::vec3 travelDir = cameraFront;
117 travelDir = this->travelFront;
119 if (keyHandler->getKeyDown(GLFW_KEY_LEFT_SHIFT))
124 if (keyHandler->getKeyDown(GLFW_KEY_W))
125 cameraPos += speed * travelDir * deltaTime;
127 if (keyHandler->getKeyDown(GLFW_KEY_S))
128 cameraPos -= speed * travelDir * deltaTime;
130 if (keyHandler->getKeyDown(GLFW_KEY_A))
131 cameraPos -= glm::normalize(glm::cross(travelDir, cameraUp)) * speed * deltaTime;
133 if (keyHandler->getKeyDown(GLFW_KEY_D))
134 cameraPos += glm::normalize(glm::cross(travelDir, cameraUp)) * speed * deltaTime;
137 void Camera::mouseUpdate(double xpos, double ypos, bool isClicking)
139 if (isClicking && (isClicking != this->lastStatus)) {
144 this->lastStatus = isClicking;
149 //Removes first movement skips
158 float xoffset = xpos - lastX;
159 float yoffset = lastY - ypos;
164 xoffset *= (fov / 90.0f) * this->sensitivity;
165 yoffset *= (fov / 90.0f) * this->sensitivity;
167 this->yaw = glm::mod(this->yaw + xoffset, 360.0f);
168 this->pitch = glm::clamp(this->pitch + yoffset, this->pitch_min, this->pitch_max);
170 //Front facing vector
172 front.x = cos(glm::radians(this->pitch)) * cos(glm::radians(this->yaw));
173 front.y = sin(glm::radians(this->pitch));
174 front.z = cos(glm::radians(this->pitch)) * sin(glm::radians(this->yaw));
176 //Used for fps movement
178 tFront.x = cos(glm::radians(this->yaw));
179 tFront.z = sin(glm::radians(this->yaw));
182 //Update class vectors
183 this->cameraFront = glm::normalize(front);
184 this->travelFront = glm::normalize(tFront);
187 glm::mat4 Camera::getViewMatrix()
189 //return glm::lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 10) + glm::vec3(0, 0, -1), glm::vec3(1, 0, 0));
190 return glm::lookAt(this->cameraPos, this->cameraPos + this->cameraFront, this->cameraUp);
193 glm::mat4 Camera::getProjectionMatrix()
195 //return glm::ortho(-20.0f, 20.0f, -20.0f, 20.0f, 0.1f, 100.0f);
196 return glm::perspective(glm::radians(fov / 2), (float)window_width / (float)window_height, near_z, far_z);
199 Camera::Camera(util_keyHandler* keyHandler)
201 this->keyHandler = keyHandler;