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);
33 util_keyHandler* keyHandler;
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);
39 float sensitivity = 0.05f;
44 float far_z = 1000.0f;
46 float pitch_max = 89.0f;
47 float pitch_min = -89.0f;
49 int window_width = 800;
50 int window_height = 600;
54 void handleInput(float deltaTime);
56 void mouseUpdate(double xpos, double ypos, bool isClicking = true);
58 glm::mat4 getViewMatrix();
59 glm::mat4 getProjectionMatrix();
61 glm::vec3 getViewRay(double xpos, double ypos, int viewWidth, int viewHeight);
63 Camera(util_keyHandler* keyHandler);
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;
72 return glm::vec2(x, -y);
75 glm::vec4 calculateViewCoords(glm::vec4 clipCoords, glm::mat4 projectionMatrix)
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);
82 glm::vec3 calculateWorldVector(glm::vec4 viewCoords, glm::mat4 viewMatrix)
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);
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);
99 glm::vec3 Camera::getViewRay(double xpos, double ypos, int viewWidth, int viewHeight)
101 return calculateMouseRay(xpos, ypos, viewWidth, viewHeight, this->getProjectionMatrix(), this->getViewMatrix());
110 void Camera::handleInput(float deltaTime)
112 glm::vec3 travelDir = cameraFront;
115 travelDir = this->travelFront;
117 if (keyHandler->getKeyDown(GLFW_KEY_LEFT_SHIFT))
122 if (keyHandler->getKeyDown(GLFW_KEY_W))
123 cameraPos += speed * travelDir * deltaTime;
125 if (keyHandler->getKeyDown(GLFW_KEY_S))
126 cameraPos -= speed * travelDir * deltaTime;
128 if (keyHandler->getKeyDown(GLFW_KEY_A))
129 cameraPos -= glm::normalize(glm::cross(travelDir, cameraUp)) * speed * deltaTime;
131 if (keyHandler->getKeyDown(GLFW_KEY_D))
132 cameraPos += glm::normalize(glm::cross(travelDir, cameraUp)) * speed * deltaTime;
135 void Camera::mouseUpdate(double xpos, double ypos, bool isClicking)
137 if (isClicking && (isClicking != this->lastStatus)) {
142 this->lastStatus = isClicking;
147 //Removes first movement skips
156 float xoffset = xpos - lastX;
157 float yoffset = lastY - ypos;
162 xoffset *= (fov / 90.0f) * this->sensitivity;
163 yoffset *= (fov / 90.0f) * this->sensitivity;
165 this->yaw = glm::mod(this->yaw + xoffset, 360.0f);
166 this->pitch = glm::clamp(this->pitch + yoffset, this->pitch_min, this->pitch_max);
168 //Front facing vector
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));
174 //Used for fps movement
176 tFront.x = cos(glm::radians(this->yaw));
177 tFront.z = sin(glm::radians(this->yaw));
180 //Update class vectors
181 this->cameraFront = glm::normalize(front);
182 this->travelFront = glm::normalize(tFront);
185 glm::mat4 Camera::getViewMatrix()
187 return glm::lookAt(this->cameraPos, this->cameraPos + this->cameraFront, this->cameraUp);
190 glm::mat4 Camera::getProjectionMatrix()
192 return glm::perspective(glm::radians(fov / 2), (float)window_width / (float)window_height, near_z, far_z);
195 Camera::Camera(util_keyHandler* keyHandler)
197 this->keyHandler = keyHandler;