Organize systems
This commit is contained in:
@@ -3,7 +3,6 @@ add_library(fever_engine
|
|||||||
Controller.cpp
|
Controller.cpp
|
||||||
Window.cpp
|
Window.cpp
|
||||||
ShaderProgram.cpp
|
ShaderProgram.cpp
|
||||||
Camera.cpp
|
|
||||||
Light.cpp
|
Light.cpp
|
||||||
Scene.cpp
|
Scene.cpp
|
||||||
FrameBuffer.cpp
|
FrameBuffer.cpp
|
||||||
|
|||||||
105
src/Camera.cpp
105
src/Camera.cpp
@@ -1,105 +0,0 @@
|
|||||||
#include "Camera.h"
|
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
|
|
||||||
Camera::Camera(float fov, float aspectRatio) : m_fov(fov)
|
|
||||||
{
|
|
||||||
m_viewMatrix = glm::mat4(1.);
|
|
||||||
updateAspectRatio(aspectRatio);
|
|
||||||
updateVPM();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::updateVPM()
|
|
||||||
{
|
|
||||||
m_viewProjectionMatrix = m_projectionMatrix * m_viewMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::updateAspectRatio(float aspectRatio)
|
|
||||||
{
|
|
||||||
m_projectionMatrix = glm::perspective(m_fov / 2.F, aspectRatio, .01F, 1000.F);
|
|
||||||
updateVPM();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::translate(glm::vec3 translateVector)
|
|
||||||
{
|
|
||||||
m_position += translateVector;
|
|
||||||
m_viewMatrix = glm::translate(m_viewMatrix, translateVector * -1.F);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::lookForward()
|
|
||||||
{
|
|
||||||
m_viewMatrix = glm::lookAt(m_position, m_position + m_front_vec, UP_VEC);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::updatePositionFromKeyboardInput(KeyInput const &key_input, float deltaTime)
|
|
||||||
{
|
|
||||||
glm::vec3 frontVecWithoutY = glm::vec3(m_front_vec.x, 0., m_front_vec.z);
|
|
||||||
glm::vec3 deltaPos = glm::vec3(0., 0., 0.);
|
|
||||||
float deltaFactor = SPEED * deltaTime * (m_accellerate ? 5.0 : 1.0);
|
|
||||||
m_accellerate = false;
|
|
||||||
|
|
||||||
for (auto const &[key, pressed] : key_input) {
|
|
||||||
if (key == GLFW_KEY_W && pressed) {
|
|
||||||
deltaPos += deltaFactor * glm::normalize(frontVecWithoutY);
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_S && pressed) {
|
|
||||||
deltaPos -= deltaFactor * glm::normalize(frontVecWithoutY);
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_A && pressed) {
|
|
||||||
deltaPos -= deltaFactor * glm::normalize(glm::cross(m_front_vec, UP_VEC));
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_D && pressed) {
|
|
||||||
deltaPos += deltaFactor * glm::normalize(glm::cross(m_front_vec, UP_VEC));
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_SPACE && pressed) {
|
|
||||||
deltaPos += deltaFactor * UP_VEC;
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_LEFT_SHIFT && pressed) {
|
|
||||||
deltaPos -= deltaFactor * UP_VEC;
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_LEFT_ALT && pressed) {
|
|
||||||
m_accellerate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_position += deltaPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::updateDirectionFromMouseInput(MouseCursorInput const &mouse_cursor_input)
|
|
||||||
{
|
|
||||||
auto [deltaX, deltaY] = mouse_cursor_input;
|
|
||||||
|
|
||||||
if (std::abs(deltaX) < std::numeric_limits<double>::epsilon() && std::abs(deltaY) < std::numeric_limits<double>::epsilon()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_yaw += static_cast<float>(deltaX);
|
|
||||||
m_pitch += static_cast<float>(deltaY);
|
|
||||||
|
|
||||||
static constexpr float CLIP = 89.;
|
|
||||||
|
|
||||||
if (m_pitch > CLIP) {
|
|
||||||
m_pitch = CLIP;
|
|
||||||
}
|
|
||||||
if (m_pitch < -CLIP) {
|
|
||||||
m_pitch = -CLIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 direction;
|
|
||||||
direction.x = std::cos(glm::radians(m_yaw)) * std::cos(glm::radians(m_pitch));
|
|
||||||
direction.y = std::sin(glm::radians(m_pitch));
|
|
||||||
direction.z = std::sin(glm::radians(m_yaw)) * std::cos(glm::radians(m_pitch));
|
|
||||||
m_front_vec = glm::normalize(direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Camera::getViewProj() const -> glm::mat4
|
|
||||||
{
|
|
||||||
return m_viewProjectionMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Camera::getPosition() const -> glm::vec3
|
|
||||||
{
|
|
||||||
return m_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
41
src/Camera.h
41
src/Camera.h
@@ -1,41 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Window.h"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
class Camera
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Camera(float fov, float aspectRatio);
|
|
||||||
|
|
||||||
void updateVPM();
|
|
||||||
void updateAspectRatio(float aspectRatio);
|
|
||||||
void updatePositionFromKeyboardInput(KeyInput const &key_input, float deltaTime);
|
|
||||||
void updateDirectionFromMouseInput(MouseCursorInput const &mouse_cursor_input);
|
|
||||||
|
|
||||||
void translate(glm::vec3 translateVector);
|
|
||||||
void lookForward();
|
|
||||||
|
|
||||||
[[nodiscard]] auto getViewProj() const -> glm::mat4;
|
|
||||||
[[nodiscard]] auto getPosition() const -> glm::vec3;
|
|
||||||
|
|
||||||
private:
|
|
||||||
glm::mat4 m_viewMatrix;
|
|
||||||
glm::mat4 m_projectionMatrix;
|
|
||||||
glm::mat4 m_viewProjectionMatrix;
|
|
||||||
|
|
||||||
glm::vec3 m_position = glm::vec3(0., 0., 0.);
|
|
||||||
glm::vec3 m_front_vec = glm::vec3(0., 0., -1.);
|
|
||||||
|
|
||||||
static constexpr glm::vec3 UP_VEC = glm::vec3(0., 1., 0.);
|
|
||||||
static constexpr float SPEED = .5;
|
|
||||||
static constexpr float DEFAULT_YAW = -90.;
|
|
||||||
|
|
||||||
float m_pitch{};
|
|
||||||
float m_yaw = DEFAULT_YAW;
|
|
||||||
|
|
||||||
float m_fov;
|
|
||||||
|
|
||||||
bool m_accellerate = false;
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "Camera.h"
|
|
||||||
#include "FrameBuffer.h"
|
#include "FrameBuffer.h"
|
||||||
#include "Helper.h"
|
#include "Helper.h"
|
||||||
#include "Light.h"
|
#include "Light.h"
|
||||||
@@ -64,16 +63,6 @@ void Controller::run()
|
|||||||
limit_framerate();
|
limit_framerate();
|
||||||
|
|
||||||
// --- Update game ---
|
// --- Update game ---
|
||||||
|
|
||||||
// --- Render and buffer swap ---
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
m_postProcessFrameBuffer.bind();
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
// m_camera->lookForward();
|
|
||||||
// m_camera->updateVPM();
|
|
||||||
|
|
||||||
m_gameWindow->clear_mouse_cursor_input(); // MOVE DOWN AGAIN!
|
m_gameWindow->clear_mouse_cursor_input(); // MOVE DOWN AGAIN!
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
@@ -83,9 +72,16 @@ void Controller::run()
|
|||||||
static constexpr auto MICROSECONDS_PER_SECOND = 1'000'000;
|
static constexpr auto MICROSECONDS_PER_SECOND = 1'000'000;
|
||||||
m_scene.update(
|
m_scene.update(
|
||||||
std::chrono::microseconds(static_cast<unsigned>(m_deltaTime * MICROSECONDS_PER_SECOND)),
|
std::chrono::microseconds(static_cast<unsigned>(m_deltaTime * MICROSECONDS_PER_SECOND)),
|
||||||
&defaultProgram,
|
|
||||||
key_input,mouse_cursor_input, m_gameWindow->aspectRatio());
|
key_input,mouse_cursor_input, m_gameWindow->aspectRatio());
|
||||||
|
|
||||||
|
// --- Render and buffer swap ---
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
m_postProcessFrameBuffer.bind();
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
m_scene.draw(&defaultProgram);
|
||||||
|
|
||||||
Framebuffer::unbind();
|
Framebuffer::unbind();
|
||||||
m_postProcessFrameBuffer.drawOnEntireScreen();
|
m_postProcessFrameBuffer.drawOnEntireScreen();
|
||||||
|
|
||||||
@@ -145,5 +141,5 @@ void Controller::updateExposure(ShaderProgram &shaderProgram) const
|
|||||||
{
|
{
|
||||||
shaderProgram.bind();
|
shaderProgram.bind();
|
||||||
shaderProgram.setUniform("u_exposure", m_exposure);
|
shaderProgram.setUniform("u_exposure", m_exposure);
|
||||||
shaderProgram.unbind();
|
ShaderProgram::unbind();
|
||||||
}
|
}
|
||||||
|
|||||||
138
src/Scene.cpp
138
src/Scene.cpp
@@ -7,9 +7,6 @@
|
|||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include "util/Log.h"
|
#include "util/Log.h"
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace entt::literals;
|
using namespace entt::literals;
|
||||||
|
|
||||||
// TODO: make scene initialization part of gltf loader as seen in bevy
|
// TODO: make scene initialization part of gltf loader as seen in bevy
|
||||||
@@ -95,14 +92,13 @@ Scene::Scene()
|
|||||||
// Spawn the camera
|
// Spawn the camera
|
||||||
auto entity = m_registry.create();
|
auto entity = m_registry.create();
|
||||||
m_registry.emplace<Name>(entity, "Camera");
|
m_registry.emplace<Name>(entity, "Camera");
|
||||||
m_registry.emplace<Transform>(entity, Transform{.translation = glm::vec3(0.0, 0.5, -2.0)});
|
m_registry.emplace<Transform>(entity, Transform{.translation = glm::vec3(0.0, 0.5, -1.0)});
|
||||||
m_registry.emplace<GlobalTransform>(entity, GlobalTransform{});
|
m_registry.emplace<GlobalTransform>(entity, GlobalTransform{});
|
||||||
m_registry.emplace<Camera>(entity,
|
m_registry.emplace<Camera>(entity,
|
||||||
Camera{.projection = Camera::Perspective{.aspect_ratio = 1.6}});
|
Camera{.projection = Camera::Perspective{}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::update(std::chrono::duration<float> delta,
|
void Scene::update(std::chrono::duration<float> delta,
|
||||||
ShaderProgram *shaderprogram,
|
|
||||||
KeyInput const &key_input,
|
KeyInput const &key_input,
|
||||||
MouseCursorInput const &mouse_cursor_input,
|
MouseCursorInput const &mouse_cursor_input,
|
||||||
float aspect_ratio)
|
float aspect_ratio)
|
||||||
@@ -142,114 +138,38 @@ void Scene::update(std::chrono::duration<float> delta,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
Camera::keyboard_movement(m_registry, key_input, delta);
|
||||||
auto mesh_view = m_registry.view<GpuMesh const, GpuMaterial const, GlobalTransform const>();
|
Camera::mouse_orientation(m_registry, mouse_cursor_input);
|
||||||
auto camera_view = m_registry.view<Camera const, GlobalTransform const>();
|
Camera::aspect_ratio_update(m_registry, aspect_ratio);
|
||||||
auto camera_entity = camera_view.front();
|
}
|
||||||
auto [camera, camera_transform] = camera_view.get(camera_entity);
|
|
||||||
glm::mat4 view_projection_matrix =
|
|
||||||
camera.projection_matrix() * Camera::view_matrix(camera_transform);
|
|
||||||
|
|
||||||
for (auto [entity, mesh, material, transform] : mesh_view.each()) {
|
void Scene::draw(ShaderProgram *shaderprogram) const
|
||||||
shaderprogram->bind();
|
{
|
||||||
|
auto mesh_view = m_registry.view<GpuMesh const, GpuMaterial const, GlobalTransform const>();
|
||||||
|
auto camera_view = m_registry.view<Camera const, GlobalTransform const>();
|
||||||
|
auto camera_entity = camera_view.front();
|
||||||
|
auto [camera, camera_transform] = camera_view.get(camera_entity);
|
||||||
|
glm::mat4 view_projection_matrix =
|
||||||
|
camera.projection_matrix() * Camera::view_matrix(camera_transform);
|
||||||
|
|
||||||
// Bind textures
|
for (auto [entity, mesh, material, transform] : mesh_view.each()) {
|
||||||
material.bind(*shaderprogram);
|
shaderprogram->bind();
|
||||||
|
|
||||||
// Bind modelview matrix uniform
|
// Bind textures
|
||||||
{
|
material.bind(*shaderprogram);
|
||||||
glm::mat4 modelViewProj = view_projection_matrix * transform.transform;
|
|
||||||
shaderprogram->setUniform("u_modelViewProjMatrix", modelViewProj);
|
|
||||||
shaderprogram->setUniform("u_modelMatrix", transform.transform);
|
|
||||||
shaderprogram->setUniform("u_viewPosition", camera_transform.position());
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindVertexArray(mesh.vao);
|
// Bind modelview matrix uniform
|
||||||
glDrawElements(GL_TRIANGLES, mesh.indices_count, mesh.indices_type, nullptr);
|
{
|
||||||
glBindVertexArray(0);
|
glm::mat4 modelViewProj = view_projection_matrix * transform.transform;
|
||||||
|
shaderprogram->setUniform("u_modelViewProjMatrix", modelViewProj);
|
||||||
ShaderProgram::unbind();
|
shaderprogram->setUniform("u_modelMatrix", transform.transform);
|
||||||
}
|
shaderprogram->setUniform("u_viewPosition", camera_transform.position());
|
||||||
}
|
|
||||||
|
|
||||||
// Camera keyboard update
|
|
||||||
{
|
|
||||||
auto camera_view = m_registry.view<Camera const, Transform, GlobalTransform const>();
|
|
||||||
auto camera_entity = camera_view.front();
|
|
||||||
auto [camera, camera_transform, camera_global_transform] = camera_view.get(camera_entity);
|
|
||||||
|
|
||||||
glm::vec3 front_vec = Camera::front_vector(camera_global_transform);
|
|
||||||
glm::vec3 front_vec_without_y = glm::vec3(front_vec.x, 0., front_vec.z);
|
|
||||||
glm::vec3 deltaPos = glm::vec3(0., 0., 0.);
|
|
||||||
// float deltaFactor = SPEED * deltaTime * (m_accellerate ? 5.0 : 1.0);
|
|
||||||
float delta_factor = 0.5 * delta.count();
|
|
||||||
// m_accellerate = false;
|
|
||||||
|
|
||||||
for (auto const &[key, pressed] : key_input) {
|
|
||||||
if (key == GLFW_KEY_W && pressed) {
|
|
||||||
deltaPos += delta_factor * glm::normalize(front_vec_without_y);
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_S && pressed) {
|
|
||||||
deltaPos -= delta_factor * glm::normalize(front_vec_without_y);
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_A && pressed) {
|
|
||||||
deltaPos -= delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR));
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_D && pressed) {
|
|
||||||
deltaPos += delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR));
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_SPACE && pressed) {
|
|
||||||
deltaPos += delta_factor * Camera::UP_VECTOR;
|
|
||||||
}
|
|
||||||
if (key == GLFW_KEY_LEFT_SHIFT && pressed) {
|
|
||||||
deltaPos -= delta_factor * Camera::UP_VECTOR;
|
|
||||||
}
|
|
||||||
// if (key == GLFW_KEY_LEFT_ALT && pressed) {
|
|
||||||
// m_accellerate = true;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
camera_transform.translation += deltaPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Camera mouse update
|
|
||||||
{
|
|
||||||
auto camera_view = m_registry.view<Camera, Transform>();
|
|
||||||
auto camera_entity = camera_view.front();
|
|
||||||
auto [camera, camera_transform] = camera_view.get(camera_entity);
|
|
||||||
|
|
||||||
auto [deltaX, deltaY] = mouse_cursor_input;
|
|
||||||
|
|
||||||
if (std::abs(deltaX) < std::numeric_limits<double>::epsilon() &&
|
|
||||||
std::abs(deltaY) < std::numeric_limits<double>::epsilon()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pitch = static_cast<float>(deltaY);
|
glBindVertexArray(mesh.vao);
|
||||||
auto yaw = static_cast<float>(deltaX);
|
glDrawElements(GL_TRIANGLES, mesh.indices_count, mesh.indices_type, nullptr);
|
||||||
auto roll = 0.0F;
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// Orthographic projection currently unsupported
|
ShaderProgram::unbind();
|
||||||
auto &camera_perspective = std::get<Camera::Perspective>(camera.projection);
|
|
||||||
|
|
||||||
camera_perspective.pitch += glm::radians(pitch);
|
|
||||||
camera_perspective.yaw += glm::radians(yaw);
|
|
||||||
|
|
||||||
static constexpr float PITCH_CLIP = glm::radians(89.);
|
|
||||||
camera_perspective.pitch =
|
|
||||||
std::clamp(static_cast<float>(camera_perspective.pitch), -PITCH_CLIP, PITCH_CLIP);
|
|
||||||
|
|
||||||
camera_transform.orientation =
|
|
||||||
glm::quat(glm::vec3(-camera_perspective.pitch, -camera_perspective.yaw, 0.0));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Camera aspect ratio update
|
|
||||||
{
|
|
||||||
auto camera_view = m_registry.view<Camera>();
|
|
||||||
auto camera_entity = camera_view.front();
|
|
||||||
auto [camera] = camera_view.get(camera_entity);
|
|
||||||
|
|
||||||
// Orthographic projection currently unsupported
|
|
||||||
auto &camera_perspective = std::get<Camera::Perspective>(camera.projection);
|
|
||||||
camera_perspective.aspect_ratio = aspect_ratio;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
10
src/Scene.h
10
src/Scene.h
@@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
#include "gltf_loader.h"
|
#include "gltf_loader.h"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "Window.h"
|
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <entt/entt.hpp>
|
#include <entt/entt.hpp>
|
||||||
@@ -15,8 +15,12 @@ class Scene
|
|||||||
public:
|
public:
|
||||||
Scene();
|
Scene();
|
||||||
|
|
||||||
void update(std::chrono::duration<float> delta,
|
void update(std::chrono::duration<float> delta_time,
|
||||||
ShaderProgram *shaderprogram, KeyInput const &key_input,MouseCursorInput const &mouse_cursor_input, float aspect_ratio);
|
KeyInput const &key_input,
|
||||||
|
MouseCursorInput const &mouse_cursor_input,
|
||||||
|
float aspect_ratio);
|
||||||
|
|
||||||
|
void draw(ShaderProgram *shaderprogram) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entt::registry m_registry;
|
entt::registry m_registry;
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using KeyInput = std::unordered_map<int, bool>;
|
|
||||||
using MouseButtonInput = std::unordered_map<int, bool>;
|
|
||||||
using MouseCursorInput = std::pair<double, double>;
|
|
||||||
|
|
||||||
class GLFWwindow;
|
class GLFWwindow;
|
||||||
|
|
||||||
class Window
|
class Window
|
||||||
@@ -35,7 +33,7 @@ private:
|
|||||||
static void glfw_error_callback(int error, const char *description);
|
static void glfw_error_callback(int error, const char *description);
|
||||||
static void framebuffer_size_callback(GLFWwindow *glfw_window, int width, int height);
|
static void framebuffer_size_callback(GLFWwindow *glfw_window, int width, int height);
|
||||||
|
|
||||||
static constexpr float MOUSE_SENSITIVITY = 0.15f;
|
static constexpr float MOUSE_SENSITIVITY = 0.15F;
|
||||||
|
|
||||||
void set_catched_cursor(bool value);
|
void set_catched_cursor(bool value);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "util/Log.h"
|
#include "util/Log.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
auto Camera::projection_matrix() const -> glm::mat4
|
auto Camera::projection_matrix() const -> glm::mat4
|
||||||
@@ -26,3 +28,93 @@ auto Camera::front_vector(GlobalTransform const &transform) -> glm::vec3
|
|||||||
{
|
{
|
||||||
return glm::normalize(transform.transform * glm::vec4(0.0, 0.0, 1.0, 0.0));
|
return glm::normalize(transform.transform * glm::vec4(0.0, 0.0, 1.0, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::keyboard_movement(entt::registry ®istry,
|
||||||
|
KeyInput const &key_input,
|
||||||
|
std::chrono::duration<float> delta_time)
|
||||||
|
{
|
||||||
|
struct KeyboardMovementContext
|
||||||
|
{
|
||||||
|
bool accelerate{};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto &context = registry.ctx().emplace<KeyboardMovementContext>();
|
||||||
|
|
||||||
|
auto camera_view = registry.view<Camera const, Transform, GlobalTransform const>();
|
||||||
|
auto camera_entity = camera_view.front();
|
||||||
|
auto [camera, camera_transform, camera_global_transform] = camera_view.get(camera_entity);
|
||||||
|
|
||||||
|
glm::vec3 front_vec = front_vector(camera_global_transform);
|
||||||
|
front_vec.y = 0; // NOLINT (cppcoreguidelines-pro-type-union-access)
|
||||||
|
|
||||||
|
glm::vec3 delta_pos = glm::vec3(0., 0., 0.);
|
||||||
|
float delta_factor = SPEED * delta_time.count() * (context.accelerate ? ACCELERATION : 1.0F);
|
||||||
|
context.accelerate = false;
|
||||||
|
|
||||||
|
for (auto const &[key, pressed] : key_input) {
|
||||||
|
if (key == GLFW_KEY_W && pressed) {
|
||||||
|
delta_pos += delta_factor * glm::normalize(front_vec);
|
||||||
|
}
|
||||||
|
if (key == GLFW_KEY_S && pressed) {
|
||||||
|
delta_pos -= delta_factor * glm::normalize(front_vec);
|
||||||
|
}
|
||||||
|
if (key == GLFW_KEY_A && pressed) {
|
||||||
|
delta_pos -= delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR));
|
||||||
|
}
|
||||||
|
if (key == GLFW_KEY_D && pressed) {
|
||||||
|
delta_pos += delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR));
|
||||||
|
}
|
||||||
|
if (key == GLFW_KEY_SPACE && pressed) {
|
||||||
|
delta_pos += delta_factor * UP_VECTOR;
|
||||||
|
}
|
||||||
|
if (key == GLFW_KEY_LEFT_SHIFT && pressed) {
|
||||||
|
delta_pos -= delta_factor * UP_VECTOR;
|
||||||
|
}
|
||||||
|
if (key == GLFW_KEY_LEFT_ALT && pressed) {
|
||||||
|
context.accelerate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
camera_transform.translation += delta_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouse_orientation(entt::registry ®istry, MouseCursorInput const &mouse_cursor_input)
|
||||||
|
{
|
||||||
|
auto camera_view = registry.view<Camera, Transform>();
|
||||||
|
auto camera_entity = camera_view.front();
|
||||||
|
auto [camera, camera_transform] = camera_view.get(camera_entity);
|
||||||
|
|
||||||
|
auto [deltaX, deltaY] = mouse_cursor_input;
|
||||||
|
|
||||||
|
if (std::abs(deltaX) < std::numeric_limits<double>::epsilon() &&
|
||||||
|
std::abs(deltaY) < std::numeric_limits<double>::epsilon()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pitch = static_cast<float>(deltaY);
|
||||||
|
auto yaw = static_cast<float>(deltaX);
|
||||||
|
auto roll = 0.0F;
|
||||||
|
|
||||||
|
// Orthographic projection currently unsupported
|
||||||
|
auto &camera_perspective = std::get<Perspective>(camera.projection);
|
||||||
|
|
||||||
|
camera_perspective.pitch += glm::radians(pitch);
|
||||||
|
camera_perspective.yaw += glm::radians(yaw);
|
||||||
|
|
||||||
|
static constexpr float PITCH_CLIP = glm::radians(89.);
|
||||||
|
camera_perspective.pitch =
|
||||||
|
std::clamp(static_cast<float>(camera_perspective.pitch), -PITCH_CLIP, PITCH_CLIP);
|
||||||
|
|
||||||
|
camera_transform.orientation =
|
||||||
|
glm::quat(glm::vec3(-camera_perspective.pitch, -camera_perspective.yaw, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::aspect_ratio_update(entt::registry ®istry, float aspect_ratio)
|
||||||
|
{
|
||||||
|
auto camera_view = registry.view<Camera>();
|
||||||
|
auto camera_entity = camera_view.front();
|
||||||
|
auto [camera] = camera_view.get(camera_entity);
|
||||||
|
|
||||||
|
// Orthographic projection currently unsupported
|
||||||
|
auto &camera_perspective = std::get<Perspective>(camera.projection);
|
||||||
|
camera_perspective.aspect_ratio = aspect_ratio;
|
||||||
|
}
|
||||||
|
|||||||
15
src/camera.h
15
src/camera.h
@@ -1,7 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <chrono>
|
||||||
|
#include <entt/entt.hpp>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
@@ -13,10 +17,13 @@ struct Camera
|
|||||||
|
|
||||||
static constexpr glm::vec3 UP_VECTOR = glm::vec3(0.0, 1.0, 0.0);
|
static constexpr glm::vec3 UP_VECTOR = glm::vec3(0.0, 1.0, 0.0);
|
||||||
|
|
||||||
|
static constexpr float SPEED = 0.5;
|
||||||
|
static constexpr float ACCELERATION = 5.0;
|
||||||
|
|
||||||
struct Perspective
|
struct Perspective
|
||||||
{
|
{
|
||||||
float fov = DEFAULT_FOV;
|
float fov = DEFAULT_FOV;
|
||||||
float aspect_ratio;
|
float aspect_ratio{};
|
||||||
float near = DEFAULT_NEAR;
|
float near = DEFAULT_NEAR;
|
||||||
float far = DEFAULT_FAR;
|
float far = DEFAULT_FAR;
|
||||||
|
|
||||||
@@ -39,4 +46,10 @@ struct Camera
|
|||||||
[[nodiscard]] auto projection_matrix() const -> glm::mat4;
|
[[nodiscard]] auto projection_matrix() const -> glm::mat4;
|
||||||
[[nodiscard]] static auto view_matrix(GlobalTransform const &transform) -> glm::mat4;
|
[[nodiscard]] static auto view_matrix(GlobalTransform const &transform) -> glm::mat4;
|
||||||
[[nodiscard]] static auto front_vector(GlobalTransform const &transform) -> glm::vec3;
|
[[nodiscard]] static auto front_vector(GlobalTransform const &transform) -> glm::vec3;
|
||||||
|
|
||||||
|
static void keyboard_movement(entt::registry ®istry,
|
||||||
|
KeyInput const &key_input,
|
||||||
|
std::chrono::duration<float> delta_time);
|
||||||
|
static void mouse_orientation(entt::registry ®istry, MouseCursorInput const &mouse_cursor_input);
|
||||||
|
static void aspect_ratio_update(entt::registry ®istry, float aspect_ratio);
|
||||||
};
|
};
|
||||||
|
|||||||
8
src/input.h
Normal file
8
src/input.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
using KeyInput = std::unordered_map<int, bool>;
|
||||||
|
using MouseButtonInput = std::unordered_map<int, bool>;
|
||||||
|
using MouseCursorInput = std::pair<double, double>;
|
||||||
Reference in New Issue
Block a user