Move flycam to binary
This commit is contained in:
@@ -1,8 +1 @@
|
||||
CPMAddPackage(NAME argparse URL "https://github.com/p-ranav/argparse/archive/refs/tags/v3.1.tar.gz")
|
||||
|
||||
add_executable(Fall-Fever
|
||||
main.cpp
|
||||
controller.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(Fall-Fever PRIVATE fever_core argparse)
|
||||
add_subdirectory(fall-fever)
|
||||
|
||||
9
src/bin/fall-fever/CMakeLists.txt
Normal file
9
src/bin/fall-fever/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
CPMAddPackage(NAME argparse URL "https://github.com/p-ranav/argparse/archive/refs/tags/v3.1.tar.gz")
|
||||
|
||||
add_executable(Fall-Fever
|
||||
main.cpp
|
||||
controller.cpp
|
||||
flycam.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(Fall-Fever PRIVATE fever_core argparse)
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "controller.h"
|
||||
#include "flycam.h"
|
||||
|
||||
#include "components/name.h"
|
||||
#include "components/transform.h"
|
||||
#include "core/camera.h"
|
||||
#include "core/light.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "window/window.h"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
using namespace entt::literals;
|
||||
|
||||
Controller::Controller(std::string_view path)
|
||||
@@ -19,24 +22,6 @@ Controller::Controller(std::string_view path)
|
||||
|
||||
gltf_document->spawn_default_scene(registry(), gltf_node_cache);
|
||||
|
||||
// Convert meshes
|
||||
auto mesh_view = registry().view<entt::resource<Mesh>>();
|
||||
for (auto [entity, mesh] : mesh_view.each()) {
|
||||
registry().emplace<GpuMesh>(entity, GpuMesh(mesh));
|
||||
|
||||
// Remove Mesh resource as it is no longer needed.
|
||||
registry().erase<entt::resource<Mesh>>(entity);
|
||||
}
|
||||
|
||||
// Convert materials
|
||||
auto material_view = registry().view<entt::resource<Material>>();
|
||||
for (auto [entity, material] : material_view.each()) {
|
||||
registry().emplace<GpuMaterial>(entity, GpuMaterial(material));
|
||||
|
||||
// Remove Material resource as it is no longer needed.
|
||||
registry().erase<entt::resource<Material>>(entity);
|
||||
}
|
||||
|
||||
// Spawn default lights
|
||||
auto directional_light = registry().create();
|
||||
registry().emplace<Name>(directional_light, "Directional Light");
|
||||
@@ -55,13 +40,24 @@ Controller::Controller(std::string_view path)
|
||||
registry().emplace<GlobalTransform>(point_light, GlobalTransform{});
|
||||
registry().emplace<PointLight>(point_light,
|
||||
PointLight{.intensity = PointLight::DEFAULT_INTENSITY});
|
||||
|
||||
// Spawn default camera
|
||||
auto camera_view = registry().view<Camera const>();
|
||||
if (camera_view.empty()) {
|
||||
auto entity = registry().create();
|
||||
registry().emplace<Name>(entity, "Camera");
|
||||
registry().emplace<Transform>(entity, Transform{.translation = glm::vec3(0.0, 0.25, -1.0)});
|
||||
registry().emplace<GlobalTransform>(entity, GlobalTransform{});
|
||||
registry().emplace<Camera>(entity, Camera{.projection = Camera::Perspective{}});
|
||||
registry().emplace<Flycam>(entity);
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::update()
|
||||
{
|
||||
Camera::keyboard_movement(registry());
|
||||
Flycam::keyboard_movement(registry());
|
||||
|
||||
if (registry().ctx().get<Window::MouseCatched>().catched) {
|
||||
Camera::mouse_orientation(registry());
|
||||
Flycam::mouse_orientation(registry());
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/game_loop.h"
|
||||
#include "core/application.h"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class Controller : public GameLoop
|
||||
class Controller : public FeverCore::Application
|
||||
{
|
||||
public:
|
||||
Controller(std::string_view path);
|
||||
98
src/bin/fall-fever/flycam.cpp
Normal file
98
src/bin/fall-fever/flycam.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "flycam.h"
|
||||
|
||||
#include "core/camera.h"
|
||||
#include "core/time.h"
|
||||
#include "input/input.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
void Flycam::keyboard_movement(entt::registry& registry)
|
||||
{
|
||||
struct KeyboardMovementContext
|
||||
{
|
||||
bool accelerate{};
|
||||
};
|
||||
|
||||
auto& movement_context = registry.ctx().emplace<KeyboardMovementContext>();
|
||||
auto const& key_state = registry.ctx().get<Input::State<Input::KeyCode>>();
|
||||
auto const& delta_time = registry.ctx().get<Time::Delta>();
|
||||
|
||||
auto camera_view =
|
||||
registry.view<Flycam const, Camera const, Transform, GlobalTransform const>();
|
||||
auto camera_entity = camera_view.front();
|
||||
|
||||
if (camera_entity == entt::null) {
|
||||
spdlog::debug("No camera entity found");
|
||||
return;
|
||||
}
|
||||
|
||||
auto [camera, camera_transform, camera_global_transform] = camera_view.get(camera_entity);
|
||||
|
||||
glm::vec3 front_vec = Camera::front_vector(camera_global_transform);
|
||||
front_vec.y = 0;
|
||||
|
||||
glm::vec3 delta_pos = glm::vec3(0., 0., 0.);
|
||||
float acceleration = movement_context.accelerate ? ACCELERATION : 1.0F;
|
||||
float delta_factor = static_cast<float>(delta_time.delta.count()) * SPEED * acceleration;
|
||||
movement_context.accelerate = false;
|
||||
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_W})) {
|
||||
delta_pos += delta_factor * glm::normalize(front_vec);
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_S})) {
|
||||
delta_pos -= delta_factor * glm::normalize(front_vec);
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_A})) {
|
||||
delta_pos -= delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR));
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_D})) {
|
||||
delta_pos += delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR));
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_SPACE})) {
|
||||
delta_pos += delta_factor * Camera::UP_VECTOR;
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_LEFT_SHIFT})) {
|
||||
delta_pos -= delta_factor * Camera::UP_VECTOR;
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_LEFT_ALT})) {
|
||||
movement_context.accelerate = true;
|
||||
}
|
||||
|
||||
camera_transform.translation += delta_pos;
|
||||
}
|
||||
|
||||
void Flycam::mouse_orientation(entt::registry& registry)
|
||||
{
|
||||
auto camera_view = registry.view<Flycam const, Camera, Transform>();
|
||||
auto camera_entity = camera_view.front();
|
||||
|
||||
if (camera_entity == entt::null) {
|
||||
spdlog::debug("No camera entity found");
|
||||
return;
|
||||
}
|
||||
|
||||
auto [camera, camera_transform] = camera_view.get(camera_entity);
|
||||
|
||||
auto const& mouse_cursor_input = registry.ctx().get<Input::MouseMotion>();
|
||||
auto delta_x = mouse_cursor_input.delta.x;
|
||||
auto delta_y = mouse_cursor_input.delta.y;
|
||||
|
||||
auto pitch = static_cast<float>(-delta_y);
|
||||
auto yaw = static_cast<float>(delta_x);
|
||||
|
||||
// Orthographic projection currently unsupported
|
||||
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));
|
||||
}
|
||||
12
src/bin/fall-fever/flycam.h
Normal file
12
src/bin/fall-fever/flycam.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
struct Flycam
|
||||
{
|
||||
static constexpr float SPEED = 0.5;
|
||||
static constexpr float ACCELERATION = 5.0;
|
||||
|
||||
static void keyboard_movement(entt::registry& registry);
|
||||
static void mouse_orientation(entt::registry& registry);
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
add_library(fever_core
|
||||
components/transform.cpp
|
||||
core/application.cpp
|
||||
core/camera.cpp
|
||||
core/game_loop.cpp
|
||||
core/glad.cpp
|
||||
core/graphics/framebuffer.cpp
|
||||
core/graphics/image.cpp
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
#include "game_loop.h"
|
||||
#include "application.h"
|
||||
|
||||
#include "core/camera.h"
|
||||
#include "core/light.h"
|
||||
#include "core/render.h"
|
||||
#include "core/shader.h"
|
||||
#include "core/time.h"
|
||||
#include "input/input.h"
|
||||
#include "scene/scene.h"
|
||||
#include "window/window.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fx/gltf.h>
|
||||
#include <glad/gl.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <iostream>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
GameLoop::~GameLoop() = default;
|
||||
namespace FeverCore {
|
||||
|
||||
GameLoop::GameLoop() :
|
||||
Application::~Application() = default;
|
||||
|
||||
Application::Application() :
|
||||
game_window(std::make_shared<Window>(event_dispatcher)),
|
||||
post_processing_framebuffer(game_window->physical_dimensions()),
|
||||
key_listener{.registry = entt_registry},
|
||||
@@ -38,13 +34,13 @@ GameLoop::GameLoop() :
|
||||
{
|
||||
register_context_variables();
|
||||
|
||||
event_dispatcher.sink<Window::ResizeEvent>().connect<&GameLoop::recreate_framebuffer>(this);
|
||||
event_dispatcher.sink<Window::ResizeEvent>().connect<&Application::recreate_framebuffer>(this);
|
||||
event_dispatcher.sink<Input::KeyInput>().connect<&Input::KeyListener::key_event>(key_listener);
|
||||
event_dispatcher.sink<Input::MouseMotion>().connect<&Input::CursorListener::cursor_event>(
|
||||
cursor_listener);
|
||||
}
|
||||
|
||||
void GameLoop::run()
|
||||
void Application::run()
|
||||
{
|
||||
entt::hashed_string shader_hash(Material::SHADER_NAME.data());
|
||||
auto standard_material_shader =
|
||||
@@ -70,7 +66,7 @@ void GameLoop::run()
|
||||
GlobalTransform::update(entt_registry);
|
||||
Camera::aspect_ratio_update(entt_registry);
|
||||
|
||||
update();
|
||||
this->update();
|
||||
|
||||
Input::State<Input::KeyCode>::update_state(entt_registry);
|
||||
Input::reset_mouse_motion(entt_registry);
|
||||
@@ -91,14 +87,16 @@ void GameLoop::run()
|
||||
}
|
||||
}
|
||||
|
||||
void GameLoop::register_context_variables()
|
||||
void Application::register_context_variables()
|
||||
{
|
||||
entt_registry.ctx().emplace<Input::State<Input::KeyCode>>();
|
||||
entt_registry.ctx().emplace<Input::MouseMotion>();
|
||||
}
|
||||
|
||||
void GameLoop::recreate_framebuffer()
|
||||
void Application::recreate_framebuffer()
|
||||
{
|
||||
auto dimensions = game_window->physical_dimensions();
|
||||
post_processing_framebuffer = Framebuffer(dimensions);
|
||||
}
|
||||
|
||||
} // namespace FeverCore
|
||||
@@ -10,22 +10,22 @@
|
||||
#include <entt/entt.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class Camera;
|
||||
class Window;
|
||||
|
||||
class GameLoop
|
||||
namespace FeverCore {
|
||||
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
GameLoop();
|
||||
Application();
|
||||
|
||||
virtual ~GameLoop();
|
||||
GameLoop(GameLoop const&) = delete;
|
||||
GameLoop(GameLoop&&) = delete;
|
||||
auto operator=(GameLoop const&) -> GameLoop& = delete;
|
||||
auto operator=(GameLoop&&) -> GameLoop& = delete;
|
||||
virtual ~Application();
|
||||
Application(Application const&) = delete;
|
||||
Application(Application&&) = delete;
|
||||
auto operator=(Application const&) -> Application& = delete;
|
||||
auto operator=(Application&&) -> Application& = delete;
|
||||
|
||||
auto registry() -> entt::registry& { return entt_registry; }
|
||||
auto registry() const -> entt::registry const& { return entt_registry; }
|
||||
@@ -63,3 +63,5 @@ protected:
|
||||
GltfLoader gltf_loader;
|
||||
entt::resource_cache<Gltf, GltfLoader> gltf_cache;
|
||||
};
|
||||
|
||||
} // namespace FeverCore
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "camera.h"
|
||||
#include "core/time.h"
|
||||
#include "input/input.h"
|
||||
#include "window/window.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <algorithm>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
@@ -33,108 +30,15 @@ auto Camera::front_vector(GlobalTransform const& transform) -> glm::vec3
|
||||
return glm::normalize(transform.transform * glm::vec4(0.0, 0.0, 1.0, 0.0));
|
||||
}
|
||||
|
||||
void Camera::keyboard_movement(entt::registry& registry)
|
||||
{
|
||||
struct KeyboardMovementContext
|
||||
{
|
||||
bool accelerate{};
|
||||
};
|
||||
|
||||
auto& movement_context = registry.ctx().emplace<KeyboardMovementContext>();
|
||||
auto const& key_state = registry.ctx().get<Input::State<Input::KeyCode>>();
|
||||
auto const& delta_time = registry.ctx().get<Time::Delta>();
|
||||
|
||||
auto camera_view = registry.view<Camera const, Transform, GlobalTransform const>();
|
||||
auto camera_entity = camera_view.front();
|
||||
|
||||
if (camera_entity == entt::null) {
|
||||
spdlog::debug("No camera entity found");
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
glm::vec3 delta_pos = glm::vec3(0., 0., 0.);
|
||||
float acceleration = movement_context.accelerate ? ACCELERATION : 1.0F;
|
||||
float delta_factor = static_cast<float>(delta_time.delta.count()) * SPEED * acceleration;
|
||||
movement_context.accelerate = false;
|
||||
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_W})) {
|
||||
delta_pos += delta_factor * glm::normalize(front_vec);
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_S})) {
|
||||
delta_pos -= delta_factor * glm::normalize(front_vec);
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_A})) {
|
||||
delta_pos -= delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR));
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_D})) {
|
||||
delta_pos += delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR));
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_SPACE})) {
|
||||
delta_pos += delta_factor * UP_VECTOR;
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_LEFT_SHIFT})) {
|
||||
delta_pos -= delta_factor * UP_VECTOR;
|
||||
}
|
||||
if (key_state.pressed(Input::KeyCode{GLFW_KEY_LEFT_ALT})) {
|
||||
movement_context.accelerate = true;
|
||||
}
|
||||
|
||||
camera_transform.translation += delta_pos;
|
||||
}
|
||||
|
||||
void Camera::mouse_orientation(entt::registry& registry)
|
||||
{
|
||||
auto camera_view = registry.view<Camera, Transform>();
|
||||
auto camera_entity = camera_view.front();
|
||||
|
||||
if (camera_entity == entt::null) {
|
||||
spdlog::debug("No camera entity found");
|
||||
return;
|
||||
}
|
||||
|
||||
auto [camera, camera_transform] = camera_view.get(camera_entity);
|
||||
|
||||
auto const& mouse_cursor_input = registry.ctx().get<Input::MouseMotion>();
|
||||
auto delta_x = mouse_cursor_input.delta.x;
|
||||
auto delta_y = mouse_cursor_input.delta.y;
|
||||
|
||||
auto pitch = static_cast<float>(-delta_y);
|
||||
auto yaw = static_cast<float>(delta_x);
|
||||
|
||||
// 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& registry)
|
||||
{
|
||||
float aspect_ratio = registry.ctx().get<Window::Descriptor>().aspect_ratio;
|
||||
|
||||
auto camera_view = registry.view<Camera>();
|
||||
auto camera_entity = camera_view.front();
|
||||
|
||||
if (camera_entity == entt::null) {
|
||||
spdlog::debug("No camera entity found");
|
||||
return;
|
||||
}
|
||||
|
||||
auto [camera] = camera_view.get(camera_entity);
|
||||
|
||||
for (auto [entity, camera] : camera_view.each()) {
|
||||
// Orthographic projection currently unsupported
|
||||
auto& camera_perspective = std::get<Perspective>(camera.projection);
|
||||
camera_perspective.aspect_ratio = aspect_ratio;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "components/transform.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <entt/entt.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <variant>
|
||||
@@ -15,11 +14,6 @@ struct Camera
|
||||
|
||||
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;
|
||||
|
||||
static constexpr glm::vec3 DEFAULT_POSITION = glm::vec3(0.0, 0.25, -1.0);
|
||||
|
||||
struct Perspective
|
||||
{
|
||||
float fov = DEFAULT_FOV;
|
||||
|
||||
@@ -84,16 +84,6 @@ auto Gltf::spawn_scene(std::size_t index,
|
||||
registry.get<Children>(scene_entity).children.push_back(node_entity);
|
||||
}
|
||||
|
||||
auto camera_view = registry.view<Camera const>();
|
||||
if (camera_view.empty()) {
|
||||
// Spawn default camera
|
||||
auto entity = registry.create();
|
||||
registry.emplace<Name>(entity, "Camera");
|
||||
registry.emplace<Transform>(entity, Transform{.translation = Camera::DEFAULT_POSITION});
|
||||
registry.emplace<GlobalTransform>(entity, GlobalTransform{});
|
||||
registry.emplace<Camera>(entity, Camera{.projection = Camera::Perspective{}});
|
||||
}
|
||||
|
||||
return scene_entity;
|
||||
}
|
||||
|
||||
@@ -113,12 +103,32 @@ auto Gltf::spawn_scene(std::string_view name,
|
||||
return entt::null;
|
||||
}
|
||||
|
||||
auto Gltf::spawn_default_scene(entt::registry& registry, entt::resource_cache<GltfNode>& node_cache)
|
||||
-> entt::entity
|
||||
auto Gltf::spawn_default_scene(entt::registry& registry,
|
||||
entt::resource_cache<GltfNode>& node_cache) -> entt::entity
|
||||
{
|
||||
if (document.scene != -1) {
|
||||
return spawn_scene(document.scene, registry, node_cache);
|
||||
if (document.scene == -1) {
|
||||
return entt::null;
|
||||
}
|
||||
|
||||
return entt::null;
|
||||
auto scene = spawn_scene(document.scene, registry, node_cache);
|
||||
|
||||
// Convert meshes
|
||||
auto mesh_view = registry.view<entt::resource<Mesh>>();
|
||||
for (auto [entity, mesh] : mesh_view.each()) {
|
||||
registry.emplace<GpuMesh>(entity, GpuMesh(mesh));
|
||||
|
||||
// Remove Mesh resource as it is no longer needed.
|
||||
registry.erase<entt::resource<Mesh>>(entity);
|
||||
}
|
||||
|
||||
// Convert materials
|
||||
auto material_view = registry.view<entt::resource<Material>>();
|
||||
for (auto [entity, material] : material_view.each()) {
|
||||
registry.emplace<GpuMaterial>(entity, GpuMaterial(material));
|
||||
|
||||
// Remove Material resource as it is no longer needed.
|
||||
registry.erase<entt::resource<Material>>(entity);
|
||||
}
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user