diff --git a/CMakeLists.txt b/CMakeLists.txt index 31d63b6..05d0c8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,10 +11,8 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -find_package(EnTT CONFIG REQUIRED) find_package(flecs CONFIG REQUIRED) find_package(glm CONFIG REQUIRED) -find_package(nlohmann_json CONFIG REQUIRED) find_package(glfw3 REQUIRED) find_package(spdlog REQUIRED) find_package(fx-gltf REQUIRED) @@ -22,9 +20,8 @@ find_package(fx-gltf REQUIRED) add_subdirectory(${PROJECT_SOURCE_DIR}/lib) add_library(fever_core - src/asset/asset_manager.cpp - src/components/transform.cpp - # src/core/application.cpp + src/asset/asset.cpp + src/transform/transform.cpp src/core/camera.cpp src/core/glad.cpp src/core/graphics/framebuffer.cpp @@ -50,12 +47,10 @@ target_link_libraries( glad stb glfw - EnTT::EnTT flecs::flecs spdlog::spdlog glm::glm fx-gltf::fx-gltf - nlohmann_json::nlohmann_json ) add_subdirectory(${PROJECT_SOURCE_DIR}/apps) diff --git a/apps/fall-fever/controller.cpp b/apps/fall-fever/controller.cpp index 02674c8..6a98d9d 100644 --- a/apps/fall-fever/controller.cpp +++ b/apps/fall-fever/controller.cpp @@ -2,7 +2,7 @@ #include "flycam.h" #include "components/name.h" -#include "components/transform.h" +#include "transform/transform.h" #include "core/camera.h" #include "core/light.h" #include "window/window.h" diff --git a/apps/flecs-test/main.cpp b/apps/flecs-test/main.cpp index 81e4f50..e5a7fb7 100644 --- a/apps/flecs-test/main.cpp +++ b/apps/flecs-test/main.cpp @@ -1,10 +1,11 @@ -#include -#include +#include #include #include +#include #include #include +#include #include int main() @@ -16,12 +17,7 @@ int main() world.import (); world.import (); world.import (); - - Asset::AssetManager manager; - manager.register_asset_type(world); - auto handle0 = manager.load(world, "hi"); - auto handle1 = manager.load(world, "hi"); - auto handle2 = manager.load(world, "hi2"); + world.import (); #ifndef NDEBUG world.import (); @@ -59,6 +55,13 @@ int main() .kind(flecs::PostUpdate) .each([](std::shared_ptr& glfw_window) { glfwSwapBuffers(glfw_window.get()); }); + auto parent = world.entity("TestParent").add().add(); + parent.get_mut()->translation += glm::vec3(1.0); + + auto child = world.entity("TestChild").add().add(); + child.get_mut()->translation += glm::vec3(1.0); + child.child_of(parent); + while (world.progress()) { } } diff --git a/src/asset/asset.cpp b/src/asset/asset.cpp new file mode 100644 index 0000000..5ce7638 --- /dev/null +++ b/src/asset/asset.cpp @@ -0,0 +1,9 @@ +#include "asset.h" + +namespace Asset { + +AssetModule::AssetModule([[maybe_unused]] flecs::world& world) +{ +} + +} // namespace Asset diff --git a/src/asset/asset.h b/src/asset/asset.h new file mode 100644 index 0000000..d694aba --- /dev/null +++ b/src/asset/asset.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include +#include + +namespace Asset { + +struct AssetModule +{ + AssetModule(flecs::world& world); +}; + +template struct AssetCache +{ + std::unordered_map> cache; +}; + +template struct AssetLoader +{ + template std::shared_ptr operator()(Args&&...) + { + static_assert(sizeof(T) == 0, "AssetLoader not implemented for this type."); + } +}; + +template std::shared_ptr load(flecs::world& world, std::string asset_path) +{ + auto& asset_cache = world.ensure>(); + + auto asset_it = asset_cache.cache.find(asset_path); + if (asset_it != asset_cache.cache.end()) + return asset_it->second; + + AssetLoader asset_loader; + auto loaded_asset = asset_loader(asset_path); + + asset_cache.cache.emplace(asset_path, loaded_asset); + return loaded_asset; +} +} // namespace Asset diff --git a/src/asset/asset_manager.cpp b/src/asset/asset_manager.cpp deleted file mode 100644 index a80d0be..0000000 --- a/src/asset/asset_manager.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "asset_manager.h" - -namespace Asset { - -AssetModule::AssetModule(flecs::world& world) -{ - auto asset_manager = world.component(); -} - -} // namespace Asset diff --git a/src/asset/asset_manager.h b/src/asset/asset_manager.h deleted file mode 100644 index 4f925f2..0000000 --- a/src/asset/asset_manager.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace Asset { - -struct AssetModule -{ - AssetModule(flecs::world& world); -}; - -template struct AssetCache -{ - std::unordered_map> cache; -}; - -template struct AssetLoader -{ - template std::shared_ptr operator()(Args&&...) - { - static_assert(sizeof(T) == 0, "AssetLoader not implemented for this type."); - } -}; - -template <> struct AssetLoader -{ - std::shared_ptr operator()(std::string_view path) - { - static int i = 0; - return std::make_shared(i++); - } -}; - -struct AssetManager -{ - template void register_asset_type(flecs::world& world) - { - world.set>({}); - } - - template std::shared_ptr load(flecs::world& world, std::string asset_path) - { - auto asset_cache = world.get_mut>(); - - auto asset_it = asset_cache->cache.find(asset_path); - if (asset_it != asset_cache->cache.end()) - return asset_it->second; - - AssetLoader asset_loader; - auto loaded_asset = asset_loader(asset_path); - - asset_cache->cache.emplace(asset_path, loaded_asset); - return loaded_asset; - } -}; - -} // namespace Asset diff --git a/src/components/name.h b/src/components/name.h deleted file mode 100644 index c5370c0..0000000 --- a/src/components/name.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include - -struct Name -{ - std::string name; -}; diff --git a/src/components/transform.cpp b/src/components/transform.cpp deleted file mode 100644 index 87ba1bc..0000000 --- a/src/components/transform.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "transform.h" -#include "relationship.h" - -void GlobalTransform::update(entt::registry ®istry) -{ - // Update GlobalTransform components - // TODO: Only do this when the Transform changed. - auto root_transform_view = - registry.view(entt::exclude); - auto transform_view = registry.view(); - - for (auto [entity, transform, global_transform] : root_transform_view.each()) { - global_transform = transform; - - auto parent_global_transform = global_transform; - if (auto *children = registry.try_get(entity)) { - for (auto child : children->children) { - std::function - transform_propagate = - [®istry, &transform_propagate, &transform_view]( - entt::entity entity, GlobalTransform parent_global_transform) { - auto [transform, global_transform, parent] = transform_view.get(entity); - global_transform.transform = parent_global_transform.transform * - GlobalTransform(transform).transform; - - if (auto *children = registry.try_get(entity)) { - for (auto child : children->children) { - transform_propagate(child, global_transform); - } - } - }; - - transform_propagate(child, parent_global_transform); - } - } - } -} diff --git a/src/components/transform.h b/src/components/transform.h deleted file mode 100644 index 2a93eeb..0000000 --- a/src/components/transform.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include -#include - -#define GLM_ENABLE_EXPERIMENTAL -#include - -struct Transform -{ - glm::vec3 translation{}; - glm::quat orientation{}; - glm::vec3 scale{1.0, 1.0, 1.0}; -}; - -struct GlobalTransform -{ - GlobalTransform() = default; - GlobalTransform(Transform const &transform) - { - // Translate * Rotate * Scale * vertex_vec; - // First scaling, then rotation, then translation - - // Translate - glm::mat4 translation_matrix = glm::translate(glm::mat4(1.0F), transform.translation); - - // Rotate - glm::mat4 rotation_matrix = glm::toMat4(transform.orientation); - - // Scale - glm::mat4 scale_matrix = glm::scale(glm::mat4(1.0F), transform.scale); - - this->transform = translation_matrix * rotation_matrix * scale_matrix; - } - - glm::mat4 transform{}; - - [[nodiscard]] auto position() const -> glm::vec3 { return transform[3]; }; - - static void update(entt::registry ®istry); -}; diff --git a/src/core/camera.h b/src/core/camera.h index bac1dd2..ecc218c 100644 --- a/src/core/camera.h +++ b/src/core/camera.h @@ -1,6 +1,6 @@ #pragma once -#include "components/transform.h" +#include "transform/transform.h" #include #include diff --git a/src/core/light.cpp b/src/core/light.cpp index c8a42f8..bfddd0e 100644 --- a/src/core/light.cpp +++ b/src/core/light.cpp @@ -1,5 +1,5 @@ #include "light.h" -#include "components/transform.h" +#include "transform/transform.h" static auto light_active(float illuminance) -> bool { diff --git a/src/scene/gltf.cpp b/src/scene/gltf.cpp index 0033c21..700b67c 100644 --- a/src/scene/gltf.cpp +++ b/src/scene/gltf.cpp @@ -1,5 +1,4 @@ #include "gltf.h" -#include "components/name.h" #include "components/relationship.h" #include "core/camera.h" @@ -38,7 +37,7 @@ auto Gltf::spawn_scene(std::size_t index, std::function spawn_node = [®istry, &spawn_node](GltfNode const& node, entt::entity parent) { auto entity = registry.create(); - registry.emplace(entity, node.name); + // registry.emplace(entity, node.name); registry.emplace(entity, node.transform); registry.emplace(entity, GlobalTransform{}); registry.emplace(entity, Parent{.parent = parent}); diff --git a/src/scene/gltf.h b/src/scene/gltf.h index 8545e50..7a48a30 100644 --- a/src/scene/gltf.h +++ b/src/scene/gltf.h @@ -1,6 +1,6 @@ #pragma once -#include "components/transform.h" +#include "transform/transform.h" #include "core/graphics/material.h" #include "core/graphics/mesh.h" diff --git a/src/scene/gltf_loader.cpp b/src/scene/gltf_loader.cpp index 9c98223..03fedb8 100644 --- a/src/scene/gltf_loader.cpp +++ b/src/scene/gltf_loader.cpp @@ -1,5 +1,4 @@ #include "gltf_loader.h" -#include "components/name.h" #include "components/relationship.h" #include "core/camera.h" #include "entt/entity/fwd.hpp" diff --git a/src/transform/transform.cpp b/src/transform/transform.cpp new file mode 100644 index 0000000..90876d3 --- /dev/null +++ b/src/transform/transform.cpp @@ -0,0 +1,36 @@ +#include "transform.h" + +void GlobalTransform::update(entt::registry& registry) +{ + // Update GlobalTransform components + // TODO: Only do this when the Transform changed. + // auto root_transform_view = + // registry.view(entt::exclude); + // auto transform_view = registry.view(); + + // for (auto [entity, transform, global_transform] : root_transform_view.each()) { + // global_transform = transform; + + // auto parent_global_transform = global_transform; + // if (auto* children = registry.try_get(entity)) { + // for (auto child : children->children) { + // std::function + // transform_propagate = + // [®istry, &transform_propagate, &transform_view]( + // entt::entity entity, GlobalTransform parent_global_transform) { + // auto [transform, global_transform, parent] = transform_view.get(entity); + // global_transform.transform = parent_global_transform.transform * + // GlobalTransform(transform).transform; + + // if (auto* children = registry.try_get(entity)) { + // for (auto child : children->children) { + // transform_propagate(child, global_transform); + // } + // } + // }; + + // transform_propagate(child, parent_global_transform); + // } + // } + // } +} diff --git a/src/transform/transform.h b/src/transform/transform.h new file mode 100644 index 0000000..f202950 --- /dev/null +++ b/src/transform/transform.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include + +#define GLM_ENABLE_EXPERIMENTAL +#include + +struct Transform +{ + glm::vec3 translation{}; + glm::quat orientation{}; + glm::vec3 scale{1.0, 1.0, 1.0}; +}; + +struct GlobalTransform +{ + GlobalTransform() = default; + GlobalTransform(Transform const& transform) + { + // Translate * Rotate * Scale * vertex_vec; + // First scaling, then rotation, then translation + + // Translate + glm::mat4 translation_matrix = glm::translate(glm::mat4(1.0F), transform.translation); + + // Rotate + glm::mat4 rotation_matrix = glm::toMat4(transform.orientation); + + // Scale + glm::mat4 scale_matrix = glm::scale(glm::mat4(1.0F), transform.scale); + + this->transform = translation_matrix * rotation_matrix * scale_matrix; + } + + glm::mat4 transform{}; + + [[nodiscard]] auto position() const -> glm::vec3 { return transform[3]; }; + + static void update(entt::registry& registry); +}; + +// namespace Transform { + +struct TransformModule +{ + TransformModule(flecs::world& world) + { + world.system("PropagateTransform") + .kind(flecs::PostUpdate) + .each([](flecs::entity e, + GlobalTransform& global_transform, + Transform const& local_transform) { + // There is no guarantee that the parent is iterated first. So there could be a two + // frame delay. + if (e.parent() == flecs::entity::null()) { + global_transform.transform = GlobalTransform(local_transform).transform; + } else { + auto parent_global_transform = e.parent().get_mut(); + global_transform.transform = parent_global_transform->transform * + GlobalTransform(local_transform).transform; + } + }); + } +}; + +// } // namespace Transform diff --git a/vcpkg.json b/vcpkg.json index 21ac891..e487f66 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -6,7 +6,7 @@ }, "dependencies": [ "cxxopts", - "entt", + "entt", "fmt", "fx-gltf", { @@ -16,7 +16,6 @@ ] }, "glm", - "nlohmann-json", "spdlog", "fx-gltf", "flecs"