#pragma once #include #include #include #include #include #include "Gedeng/Logger.h" #include "Input.h" #include "Spatial.h" namespace Gedeng { class Camera : public Spatial { public: /// Create a camera with a field of view (in degrees), width and height (in any unit) and near /// and far distances Camera(float fov, float width, float height, float near, float far) : projection(glm::perspective(glm::radians(fov), width / height, near, far)) { } glm::mat4 get_projection() const { return projection; } glm::mat4 get_view() const { return glm::inverse(get_matrix()); } private: glm::mat4 projection; }; class FPSCamera : public Camera { public: FPSCamera(float fov, float width, float height, float near, float far) : Camera(fov, width, height, near, far), move_speed(glm::vec3(5.0, 5.0, 5.0)), mouse_sensitivity(0.1), last_mouse_position(Input::get_mouse_position()), pitch(0.0), yaw(0.0) { } void update(float delta) { if (Input::is_key_down(GLFW_KEY_W)) { translate(glm::vec3(0.0, 0.0, -1.0) * move_speed * delta); } if (Input::is_key_down(GLFW_KEY_S)) { translate(-glm::vec3(0.0, 0.0, -1.0) * move_speed * delta); } if (Input::is_key_down(GLFW_KEY_D)) { translate(glm::vec3(1.0, 0.0, 0.0) * move_speed * delta); } if (Input::is_key_down(GLFW_KEY_A)) { translate(-glm::vec3(1.0, 0.0, 0.0) * move_speed * delta); } if (Input::is_key_down(GLFW_KEY_Q)) { translate(glm::vec3(0.0, 1.0, 0.0) * move_speed * delta); } if (Input::is_key_down(GLFW_KEY_E)) { translate(-glm::vec3(0.0, 1.0, 0.0) * move_speed * delta); } glm::vec2 mouse_difference = Input::get_mouse_position() - last_mouse_position; yaw -= mouse_difference.x * mouse_sensitivity; pitch -= mouse_difference.y * mouse_sensitivity; if (pitch > 80.0f) pitch = 80.0f; if (pitch < -80.0f) pitch = -80.0f; glm::qua rotation = glm::angleAxis(glm::radians((float)yaw), glm::vec3(0.f, 1.f, 0.f)); rotation *= glm::angleAxis(glm::radians((float)pitch), glm::vec3(1.f, 0.f, 0.f)); set_rotation_from_quat(rotation); last_mouse_position = Input::get_mouse_position(); } private: glm::vec3 move_speed; float mouse_sensitivity; glm::vec2 last_mouse_position; float pitch; float yaw; }; } // namespace Gedeng