2025-01-19 14:17:36 +01:00

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);
}
};