113 lines
3.1 KiB
C++
113 lines
3.1 KiB
C++
#pragma once
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <glm/ext.hpp>
|
|
|
|
|
|
|
|
#include "Entity.h"
|
|
|
|
#include <GLFW/glfw3.h>
|
|
|
|
class Camera : public Entity {
|
|
private:
|
|
GLFWwindow* _window;
|
|
InputSystem* _inputSystem;
|
|
|
|
glm::mat4 _view;
|
|
glm::mat4 _projection;
|
|
|
|
glm::quat _orientation;
|
|
|
|
glm::vec2 _dragStart;
|
|
bool _wasMouseClicked;
|
|
|
|
float _scrollPositionPrevious;
|
|
float _scrollPositionDelta;
|
|
|
|
static inline float cameraDistance = 8.15f;
|
|
|
|
static inline Camera* _instance;
|
|
|
|
public:
|
|
const glm::mat4& View() const { return _view * glm::mat4_cast(_orientation); }
|
|
const glm::mat4& Projection() const { return _projection; }
|
|
|
|
public:
|
|
Camera(GLFWwindow* window, InputSystem* inputSystem) : Entity(nullptr) {
|
|
_instance = this;
|
|
_window = window;
|
|
_inputSystem = inputSystem;
|
|
|
|
_wasMouseClicked = false;
|
|
|
|
_view = glm::lookAt(glm::vec3(0.0f, 0.0f, cameraDistance), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
|
_projection = glm::mat4(1.0f);
|
|
}
|
|
|
|
void Update(double deltaTime) override {
|
|
int screenWidth;
|
|
int screenHeight;
|
|
|
|
glfwGetFramebufferSize(_window, &screenWidth, &screenHeight);
|
|
|
|
float aspec = (float)screenWidth / (float)screenHeight;
|
|
|
|
_projection = glm::perspective(glm::radians(45.0f), aspec, 0.1f, 100.0f);
|
|
|
|
if (_inputSystem->WasKeyPressed(GLFW_KEY_SPACE))
|
|
_orientation = glm::quat(1.0f, glm::vec3(0.0f, 0.0f, 0.0f));
|
|
|
|
glm::fvec2 velocity(0.0f, 0.0f);
|
|
if (_inputSystem->IsKeyPressed(GLFW_KEY_UP))
|
|
velocity.x = glm::radians(90.0f);
|
|
if (_inputSystem->IsKeyPressed(GLFW_KEY_DOWN))
|
|
velocity.x = glm::radians(-90.0f);
|
|
|
|
if (_inputSystem->IsKeyPressed(GLFW_KEY_RIGHT))
|
|
velocity.y = glm::radians(90.0f);
|
|
if (_inputSystem->IsKeyPressed(GLFW_KEY_LEFT))
|
|
velocity.y = glm::radians(-90.0f);
|
|
|
|
if (!_wasMouseClicked && _inputSystem->IsRightMouseDown()) {
|
|
_inputSystem->GetMousePos(_dragStart);
|
|
}
|
|
|
|
if (_wasMouseClicked && _inputSystem->IsRightMouseDown()) {
|
|
glm::vec2 currentMousePositions;
|
|
_inputSystem->GetMousePos(currentMousePositions);
|
|
glm::vec2 dragDiff = currentMousePositions - _dragStart;
|
|
_dragStart = currentMousePositions;
|
|
|
|
_orientation = glm::quat(1.0f, glm::vec3(dragDiff.y, dragDiff.x, 0.0f) * 0.008f) * _orientation;
|
|
_orientation = glm::normalize(_orientation);
|
|
}
|
|
|
|
_wasMouseClicked = _inputSystem->IsRightMouseDown();
|
|
|
|
glm::quat velocityQuaternion = glm::quat(0.0f, glm::vec3(velocity.x, velocity.y, 0.0f));
|
|
|
|
_orientation += 0.5f * (float)deltaTime * velocityQuaternion * _orientation;
|
|
_orientation = glm::normalize(_orientation);
|
|
|
|
_view = glm::translate(_view, glm::vec3(0.0f, 0.0f, _scrollPositionDelta));
|
|
_scrollPositionDelta = 0.0f;
|
|
|
|
// since callbacks need to be static use a singleton
|
|
glfwSetScrollCallback(_window, Camera::scrollCallbackGlobal);
|
|
}
|
|
|
|
static void scrollCallbackGlobal(GLFWwindow* window, double xOffset, double yOffset) {
|
|
_instance->scrollCallback(window, xOffset, yOffset);
|
|
}
|
|
|
|
void scrollCallback(GLFWwindow* window, double xOffset, double yOffset) {
|
|
_scrollPositionDelta = yOffset;
|
|
}
|
|
|
|
void SetAspectRatio(float aspec) {
|
|
_projection = glm::perspective(glm::radians(45.0f), aspec, 0.1f, 100.0f);
|
|
}
|
|
};
|