#ifndef CAMERA_H #define CAMERA_H #include #include #include #include #include #include "chunk.hpp" class Camera { public: Camera() { view = glm::mat4(1.0f); // note that we're translating the scene in the reverse direction of where we want to move projection = glm::perspective(glm::radians(90.0f), 800.0f / 600.0f, 0.1f, 200.0f); } void update(GLFWwindow *window, float deltaTime) { const float cameraSpeed = 10.0f * deltaTime; // adjust accordingly if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) this->cameraPos += cameraSpeed * cameraFront; if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) this->cameraPos -= cameraSpeed * cameraFront; if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) this->cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) this->cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) this->cameraPos += cameraSpeed * cameraUp; if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) this->cameraPos -= cameraSpeed * cameraUp; direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); direction.y = sin(glm::radians(pitch)); direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); cameraFront = glm::normalize(direction); view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); } void viewPortCallBack(GLFWwindow *window, int width, int height) { projection = glm::perspective(glm::radians(80.0f), (float)width / (float)height, 0.1f, 350.0f); } void mouseCallback(GLFWwindow *window, double xpos, double ypos) { float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates range from bottom to top lastX = xpos; lastY = ypos; const float sensitivity = 0.1f; xoffset *= sensitivity; yoffset *= sensitivity; yaw += xoffset; pitch += yoffset; if (pitch > 89.0f) pitch = 89.0f; if (pitch < -89.0f) pitch = -89.0f; } glm::vec3 getPos() { return cameraPos; } glm::vec3 getFront() { return cameraFront; } glm::vec3 getUp() { return cameraUp; } glm::mat4 getView() { return view; } glm::mat4 getProjection() { return projection; } // Plane extraction as per Gribb&Hartmann // 6 planes, each with 4 components (a,b,c,d) void getFrustumPlanes(glm::vec4 planes[6], bool normalize){ glm::mat4 mat = transpose(projection*view); // This just compressed the code below float ap = mat[3][0], bp = mat[3][1], cp = mat[3][2], dp = mat[3][3]; planes[0] = glm::vec4(ap + mat[0][0], bp + mat[0][1], cp + mat[0][2], dp + mat[0][3]); planes[1] = glm::vec4(ap - mat[0][0], bp - mat[0][1], cp - mat[0][2], dp - mat[0][3]); planes[2] = glm::vec4(ap + mat[1][0], bp + mat[1][1], cp + mat[1][2], dp + mat[1][3]); planes[3] = glm::vec4(ap - mat[1][0], bp - mat[1][1], cp - mat[1][2], dp - mat[1][3]); planes[4] = glm::vec4(ap + mat[2][0], bp + mat[2][1], cp + mat[2][2], dp + mat[2][3]); planes[5] = glm::vec4(ap - mat[2][0], bp - mat[2][1], cp - mat[2][2], dp - mat[2][3]); if(normalize) for(int i = 0; i < 6; i++){ float mag = sqrt(planes[i].x + planes[i].x + planes[i].y * planes[i].y + planes[i].z*planes[i].z); planes[i] /= mag; } } private: glm::vec3 cameraPos = glm::vec3(static_cast(CHUNK_SIZE)*24, 40.0f, static_cast(CHUNK_SIZE)*24); glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); glm::vec3 direction = glm::vec3(0.0f); glm::mat4 view, projection; float lastX = 400, lastY = 300; float yaw, pitch; }; #endif