From 6ee58d4901bc0fbb380eb44a65eaf92843552cca Mon Sep 17 00:00:00 2001 From: sebastian Date: Tue, 4 Aug 2026 14:42:42 +0200 Subject: [PATCH] ADD: Visualize BoundingSpheres --- CMakeLists.txt | 11 ++++ assets/shaders/bounding_debug.frag | 8 +++ assets/shaders/bounding_debug.vert | 14 +++++ engine/src/core/Application.cpp | 9 ++-- .../src/core/inputsOutputs/inputs/Mouse.cpp | 2 + engine/src/ecs/systems/PickingSystem.cpp | 4 +- engine/src/ecs/systems/PickingSystem.h | 17 +++++-- engine/src/layer/DebugLayer.cpp | 48 +++++++++++++++++ engine/src/layer/DebugLayer.h | 40 +++++++++++++++ engine/src/renderer/DebugRenderer.cpp | 23 +++++++++ engine/src/renderer/DebugRenderer.h | 25 +++++++++ engine/src/renderer/MeshRenderSystem.cpp | 2 + engine/src/renderer/MeshRenderer.cpp | 21 +++++--- .../renderer/shader/BoundingDebugShader.cpp | 5 ++ .../src/renderer/shader/BoundingDebugShader.h | 51 +++++++++++++++++++ game/src/GameLayer.cpp | 2 + game/src/GameLayer.h | 4 +- game/src/GameScene.cpp | 4 ++ game/src/ludo/LudoTypes.h | 2 +- game/src/ludo/PiecePresenter.cpp | 2 + .../ludo/ecs/highlight/HighlightComponent.h | 15 ++++++ .../ludo/ecs/highlight/HighlightSystem.cpp | 26 ++++++++++ game/src/ludo/ecs/highlight/HighlightSystem.h | 22 ++++++++ 23 files changed, 338 insertions(+), 19 deletions(-) create mode 100644 assets/shaders/bounding_debug.frag create mode 100644 assets/shaders/bounding_debug.vert create mode 100644 engine/src/layer/DebugLayer.cpp create mode 100644 engine/src/layer/DebugLayer.h create mode 100644 engine/src/renderer/DebugRenderer.cpp create mode 100644 engine/src/renderer/DebugRenderer.h create mode 100644 engine/src/renderer/shader/BoundingDebugShader.cpp create mode 100644 engine/src/renderer/shader/BoundingDebugShader.h create mode 100644 game/src/ludo/ecs/highlight/HighlightComponent.h create mode 100644 game/src/ludo/ecs/highlight/HighlightSystem.cpp create mode 100644 game/src/ludo/ecs/highlight/HighlightSystem.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7926419..fc0f9be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,8 @@ add_library(Engine STATIC engine/src/utils/openglWrapper/shader/ShaderProgram.h engine/src/renderer/primitives/CubeFactory.cpp engine/src/renderer/primitives/CubeFactory.h + engine/src/renderer/primitives/SphereFactory.cpp + engine/src/renderer/primitives/SphereFactory.h engine/src/utils/openglWrapper/shader/Uniform.cpp engine/src/utils/openglWrapper/shader/Uniform.h engine/src/utils/openglWrapper/shader/UniformValue.cpp @@ -158,6 +160,12 @@ add_library(Engine STATIC engine/src/ecs/systems/PickingSystem.h engine/src/ui/ImGuiContext.cpp engine/src/ui/ImGuiContext.h + engine/src/renderer/shader/BoundingDebugShader.cpp + engine/src/renderer/shader/BoundingDebugShader.h + engine/src/renderer/DebugRenderer.cpp + engine/src/renderer/DebugRenderer.h + engine/src/layer/DebugLayer.cpp + engine/src/layer/DebugLayer.h ) target_include_directories(Engine PUBLIC engine/src) target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image) @@ -214,6 +222,9 @@ add_executable(ColorRace game/src/ludo/PiecePresenter.h game/src/ludo/LudoAiController.cpp game/src/ludo/LudoAiController.h + game/src/ludo/ecs/highlight/HighlightSystem.cpp + game/src/ludo/ecs/highlight/HighlightSystem.h + game/src/ludo/ecs/highlight/HighlightComponent.h ) diff --git a/assets/shaders/bounding_debug.frag b/assets/shaders/bounding_debug.frag new file mode 100644 index 0000000..a3d8e9d --- /dev/null +++ b/assets/shaders/bounding_debug.frag @@ -0,0 +1,8 @@ +#version 460 core + +uniform vec3 color; + +out vec4 fragColor; +void main() { + fragColor = vec4(color, 1.0f); +} \ No newline at end of file diff --git a/assets/shaders/bounding_debug.vert b/assets/shaders/bounding_debug.vert new file mode 100644 index 0000000..5e2c107 --- /dev/null +++ b/assets/shaders/bounding_debug.vert @@ -0,0 +1,14 @@ +#version 460 core +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec2 textureCoords; + +uniform mat4 transformationMatrix; +uniform mat4 projectionMatrix; +uniform mat4 viewMatrix; + +void main() { + vec4 worldPosition = transformationMatrix * vec4(position, 1.0f); + gl_Position = projectionMatrix * viewMatrix * worldPosition; + +} \ No newline at end of file diff --git a/engine/src/core/Application.cpp b/engine/src/core/Application.cpp index 673ab34..106596d 100644 --- a/engine/src/core/Application.cpp +++ b/engine/src/core/Application.cpp @@ -15,7 +15,8 @@ namespace engine { m_inputContextStack(), m_keyboard(*m_window), m_mouse(*m_window), - m_sceneManager(m_inputContextStack) {} + m_sceneManager(m_inputContextStack) { + } Application::~Application() = default; @@ -28,8 +29,7 @@ namespace engine { lastTime = currentTime; m_window->pollEvents(); - m_keyboard.update(); - m_mouse.update(); + m_imguiContext.beginFrame(); @@ -41,6 +41,9 @@ namespace engine { m_imguiContext.endFrame(); m_window->swapBuffers(); + + m_keyboard.update(); + m_mouse.update(); } } } diff --git a/engine/src/core/inputsOutputs/inputs/Mouse.cpp b/engine/src/core/inputsOutputs/inputs/Mouse.cpp index f2dc204..1bbace8 100644 --- a/engine/src/core/inputsOutputs/inputs/Mouse.cpp +++ b/engine/src/core/inputsOutputs/inputs/Mouse.cpp @@ -7,6 +7,7 @@ #include "imgui_impl_glfw.h" #include "core/Window.h" #include "GLFW/glfw3.h" +#include "spdlog/spdlog.h" engine::Mouse::Mouse(Window &window) { window.setMouse(this); @@ -60,6 +61,7 @@ glm::vec2 engine::Mouse::getXY(bool ndc) const { } void engine::Mouse::reportButtonClick(int button) { + spdlog::debug("Button {} clicked", button); buttonsDown.insert(button); buttonsClickedThisFrame.insert(button); } diff --git a/engine/src/ecs/systems/PickingSystem.cpp b/engine/src/ecs/systems/PickingSystem.cpp index 50e166d..eafb50f 100644 --- a/engine/src/ecs/systems/PickingSystem.cpp +++ b/engine/src/ecs/systems/PickingSystem.cpp @@ -6,8 +6,8 @@ std::pair engine::PickingSystem::screenToRay(const glm::vec2 &ndc, const Camera &camera) { glm::mat4 invVP = glm::inverse(camera.getProjectionMatrix() * camera.getViewMatrix()); - glm::vec4 nearPoint = invVP * glm::vec4(ndc.x, -ndc.y, -1.0f, 1.0f); // Y invertiert (Screen vs. NDC) - glm::vec4 farPoint = invVP * glm::vec4(ndc.x, -ndc.y, 1.0f, 1.0f); + glm::vec4 nearPoint = invVP * glm::vec4(ndc.x, ndc.y, -1.0f, 1.0f); // Y invertiert (Screen vs. NDC) + glm::vec4 farPoint = invVP * glm::vec4(ndc.x, ndc.y, 1.0f, 1.0f); nearPoint /= nearPoint.w; farPoint /= farPoint.w; auto origin = glm::vec3(nearPoint); diff --git a/engine/src/ecs/systems/PickingSystem.h b/engine/src/ecs/systems/PickingSystem.h index 2976ef7..9a570a2 100644 --- a/engine/src/ecs/systems/PickingSystem.h +++ b/engine/src/ecs/systems/PickingSystem.h @@ -12,7 +12,13 @@ #include "ecs/EntityRegistry.h" #include "ecs/standardComponents/PickableComponent.h" #include "ecs/standardComponents/TransformComponent.h" +#define GLM_ENABLE_EXPERIMENTAL +#include + +#include "glm/gtx/string_cast.hpp" + #include "renderer/entities/Camera.h" +#include "spdlog/spdlog.h" namespace engine { @@ -23,10 +29,13 @@ namespace engine { explicit PickingSystem(Camera& camera) : m_camera(camera) {} std::optional update(const Mouse& mouse, EntityRegistry& registry) { - if (ImGui::GetIO().WantCaptureMouse) return std::nullopt; - if (!mouse.isClickEvent(MouseButton::LEFT)) return std::nullopt; + //if (ImGui::GetIO().WantCaptureMouse) return std::nullopt; + if (!mouse.isClickEvent(MouseButton::LEFT)) return std::nullopt; + std::cout << "PickingSystem::update" << std::endl; auto [origin, dir] = screenToRay(mouse.getXY(/*ndc=*/true), m_camera); + printf("Ray: %f %f %f\n", origin.x, origin.y, origin.z); + spdlog::info("Ray: {} {}", glm::to_string(origin), glm::to_string(dir)); float closestT = std::numeric_limits::max(); std::optional hit; @@ -41,12 +50,12 @@ namespace engine { return hit; } - private: - Camera& m_camera; static std::pair screenToRay(const glm::vec2& screenPos, const Camera& camera); static bool raySphereIntersect(const glm::vec3& origin, const glm::vec3& dir, const glm::vec3& center, float radius, float& t); + private: + Camera& m_camera; }; } diff --git a/engine/src/layer/DebugLayer.cpp b/engine/src/layer/DebugLayer.cpp new file mode 100644 index 0000000..155109c --- /dev/null +++ b/engine/src/layer/DebugLayer.cpp @@ -0,0 +1,48 @@ +// +// Created by sebastian on 04.08.26. +// + +#include "DebugLayer.h" + +#include "ecs/standardComponents/PickableComponent.h" +#include "ecs/standardComponents/TransformComponent.h" +#include "GLFW/glfw3.h" +#include "renderer/RenderQueue.h" +#include "renderer/primitives/SphereFactory.h" + + + +void engine::DebugLayer::onUpdate(float deltaTime) { + Layer::onUpdate(deltaTime); + if (getKeyboard().isKeyDown(GLFW_KEY_H)) { + m_showDebugInfo = !m_showDebugInfo; + } +} + +void engine::DebugLayer::onRender() { + Layer::onRender(); + if (m_showDebugInfo) { + auto pickablePool = m_entityRegistry.getPool(); + auto transforms = m_entityRegistry.getPool(); + + for (auto& [entity, pickableComponent] : pickablePool) { + if (transforms.has(entity)) { + const auto sphereTransformComp = TransformComponent(transforms.get(entity).m_position, {0,0,0}, {pickableComponent.radius, pickableComponent.radius, pickableComponent.radius}); + glm::mat4 modelMatrix = sphereTransformComp.computeModelMatrix(); + + RenderCommand renderCommand(m_sphereModel, modelMatrix); + m_renderQueue.submit(renderCommand); + } + } + + m_debugRenderer.render(m_renderQueue, m_camera); + } +} + +void engine::DebugLayer::onAttachImpl() { + Layer::onAttachImpl(); +} + +void engine::DebugLayer::onDetachImpl() { + Layer::onDetachImpl(); +} diff --git a/engine/src/layer/DebugLayer.h b/engine/src/layer/DebugLayer.h new file mode 100644 index 0000000..e32f1fe --- /dev/null +++ b/engine/src/layer/DebugLayer.h @@ -0,0 +1,40 @@ +// +// Created by sebastian on 04.08.26. +// + +#ifndef COLORRACE_DEBUGLAYER_H +#define COLORRACE_DEBUGLAYER_H +#include "Layer.h" +#include "renderer/DebugRenderer.h" +#include "renderer/RenderQueue.h" + +namespace engine { + class Model; + + class DebugLayer: public Layer { + public: + DebugLayer(Camera& camera, engine::EntityRegistry& registry, Keyboard &keyboard, Mouse &mouse, std::shared_ptr sphereModel) + : Layer(keyboard, mouse), m_entityRegistry(registry), m_sphereModel(std::move(sphereModel)), m_camera(camera) { + } + + void onUpdate(float deltaTime) override; + void onRender() override; + protected: + + void onAttachImpl() override; + void onDetachImpl() override; + + private: + engine::EntityRegistry& m_entityRegistry; + bool m_showDebugInfo = true; + + std::shared_ptr m_sphereModel; + RenderQueue m_renderQueue; + DebugRenderer m_debugRenderer; + + Camera& m_camera; + }; + + +} +#endif //COLORRACE_DEBUGLAYER_H diff --git a/engine/src/renderer/DebugRenderer.cpp b/engine/src/renderer/DebugRenderer.cpp new file mode 100644 index 0000000..472a165 --- /dev/null +++ b/engine/src/renderer/DebugRenderer.cpp @@ -0,0 +1,23 @@ +// +// Created by sebastian on 04.08.26. +// + +#include "DebugRenderer.h" + +void engine::DebugRenderer::render(RenderQueue &queue, const Camera &camera) { + m_shader->start(); + m_shader->loadViewMatrix(camera.getViewMatrix()); + m_shader->loadProjectionMatrix(camera.getProjectionMatrix()); + m_shader->loadColor(debugColor); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + for (const auto&[mesh, transformationMatrix] : queue.getRenderCommands()) { + m_shader->loadTransformationMatrix(transformationMatrix); + mesh->bind(); + mesh->draw(); + mesh->unbind(); + } + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + m_shader->stop(); +} diff --git a/engine/src/renderer/DebugRenderer.h b/engine/src/renderer/DebugRenderer.h new file mode 100644 index 0000000..e7983c5 --- /dev/null +++ b/engine/src/renderer/DebugRenderer.h @@ -0,0 +1,25 @@ +// +// Created by sebastian on 04.08.26. +// + +#ifndef COLORRACE_DEBUGRENDERER_H +#define COLORRACE_DEBUGRENDERER_H +#include + +#include "RenderQueue.h" +#include "entities/Camera.h" +#include "shader/BoundingDebugShader.h" + + +namespace engine { + class DebugRenderer { + public: + DebugRenderer() : m_shader(std::make_unique()) {} + void render(RenderQueue& queue, const Camera& camera); + private: + std::unique_ptr m_shader; + glm::vec3 debugColor = glm::vec3(1.0f, 1.0f, 1.0f); + }; +} + +#endif //COLORRACE_DEBUGRENDERER_H diff --git a/engine/src/renderer/MeshRenderSystem.cpp b/engine/src/renderer/MeshRenderSystem.cpp index a605b58..e010f3d 100644 --- a/engine/src/renderer/MeshRenderSystem.cpp +++ b/engine/src/renderer/MeshRenderSystem.cpp @@ -22,4 +22,6 @@ void engine::MeshRenderSystem::update(engine::EntityRegistry ®istry, engine:: renderQueue.submit(engine::RenderCommand(mesh.model, transform.computeModelMatrix())); } + + } diff --git a/engine/src/renderer/MeshRenderer.cpp b/engine/src/renderer/MeshRenderer.cpp index c0b9e71..973d9ff 100644 --- a/engine/src/renderer/MeshRenderer.cpp +++ b/engine/src/renderer/MeshRenderer.cpp @@ -14,15 +14,20 @@ void engine::MeshRenderer::render(RenderQueue &queue, const Camera &camera, cons m_shader->loadLight(light.position, light.color); for (const auto&[mesh, transformationMatrix] : queue.getRenderCommands()) { - m_shader->loadTransformationMatrix(transformationMatrix); + m_shader->loadTransformationMatrix(transformationMatrix); - mesh->bind(); - for (const auto& section : mesh->getSections()) { - m_shader->loadMaterial(*section.material); - section.material->bind(); - mesh->drawSectionRange(section.indexOffset, section.indexCount); - } - mesh->unbind(); + mesh->bind(); + if (mesh->hasSections()) { + for (const auto& section : mesh->getSections()) { + m_shader->loadMaterial(*section.material); + section.material->bind(); + mesh->drawSectionRange(section.indexOffset, section.indexCount); + } + } else { + mesh->draw(); + } + + mesh->unbind(); } m_shader->stop(); diff --git a/engine/src/renderer/shader/BoundingDebugShader.cpp b/engine/src/renderer/shader/BoundingDebugShader.cpp new file mode 100644 index 0000000..e462dd8 --- /dev/null +++ b/engine/src/renderer/shader/BoundingDebugShader.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 04.08.26. +// + +#include "BoundingDebugShader.h" diff --git a/engine/src/renderer/shader/BoundingDebugShader.h b/engine/src/renderer/shader/BoundingDebugShader.h new file mode 100644 index 0000000..bb91a77 --- /dev/null +++ b/engine/src/renderer/shader/BoundingDebugShader.h @@ -0,0 +1,51 @@ +// +// Created by sebastian on 04.08.26. +// + +#ifndef COLORRACE_BOUNDINGDEBUGSHADER_H +#define COLORRACE_BOUNDINGDEBUGSHADER_H +#include + +#include "glm/glm.hpp" +#include "utils/openglWrapper/shader/ShaderProgram.h" +#include "utils/openglWrapper/shader/UniformValue.h" + + +namespace engine { + class BoundingDebugShader: public engine::ShaderProgram { + public: + BoundingDebugShader() : ShaderProgram("assets/shaders/bounding_debug.vert", "assets/shaders/bounding_debug.frag") { + storeAllUniformLocations({ + std::ref(transformationMatrix), + std::ref(projectionMatrix), + std::ref(viewMatrix), + std::ref(color) + }); + } + + void loadTransformationMatrix(const glm::mat4& matrix) { + transformationMatrix.load(matrix); + } + + void loadProjectionMatrix(const glm::mat4& matrix) { + projectionMatrix.load(matrix); + } + + void loadViewMatrix(const glm::mat4& matrix) { + viewMatrix.load(matrix); + } + + void loadColor(const glm::vec3& debugColor) { + this->color.load(debugColor); + } + + private: + UniformValue transformationMatrix{"transformationMatrix"}; + engine::UniformValue projectionMatrix{"projectionMatrix"}; + engine::UniformValue viewMatrix{"viewMatrix"}; + engine::UniformValue color{"color"}; + }; +} + + +#endif //COLORRACE_BOUNDINGDEBUGSHADER_H diff --git a/game/src/GameLayer.cpp b/game/src/GameLayer.cpp index 4b810ac..2841d3a 100644 --- a/game/src/GameLayer.cpp +++ b/game/src/GameLayer.cpp @@ -72,6 +72,8 @@ void GameLayer::onUpdate(float deltaTime) { }, event); } + m_highlightSystem.update(getMouse(), m_entityRegistry); + if (auto entity = m_pickingSystem.update(getMouse(), m_entityRegistry)) { if (auto pieceIndex = m_piecePresenter.getPieceIndex(*entity)) { m_gameMode->sendCommand(ludo::MovePieceCommand{m_localPlayer, *pieceIndex}); diff --git a/game/src/GameLayer.h b/game/src/GameLayer.h index a248a11..650adbd 100644 --- a/game/src/GameLayer.h +++ b/game/src/GameLayer.h @@ -17,6 +17,7 @@ #include "renderer/RenderQueue.h" #include "utils/openglWrapper/GLRenderState.h" #include "ludo/LudoGameMode.h" +#include "ludo/ecs/highlight/HighlightSystem.h" class GameLayer: public engine::Layer { public: @@ -24,7 +25,7 @@ public: engine::Keyboard& keyboard, engine::Mouse& mouse, std::shared_ptr boardModel, std::unordered_map> pieceModdels) : Layer(keyboard, mouse), m_gameMode(std::move(gameMode)), m_entityRegistry(entityRegistry), m_camera(std::move(cam)), m_renderer(std::make_unique()), m_pointLight(std::move(light)), m_boardLayout(std::move(boardModel)), m_piecePresenter(m_entityRegistry, std::move(pieceModdels), m_boardLayout), - m_pickingSystem(*m_camera) { + m_pickingSystem(*m_camera), m_highlightSystem(*m_camera) { for (auto playerID : m_gameMode->getPlayerOrder()) { if (playerID != m_localPlayer) { aiControllers.emplace_back(m_gameMode, playerID); @@ -51,6 +52,7 @@ private: engine::PlayerID m_localPlayer = 0; std::shared_ptr m_gameMode; engine::PickingSystem m_pickingSystem; + ludo::HighlightSystem m_highlightSystem; std::string m_lastEventMessage; std::vector aiControllers; diff --git a/game/src/GameScene.cpp b/game/src/GameScene.cpp index 7afa47d..0b00375 100644 --- a/game/src/GameScene.cpp +++ b/game/src/GameScene.cpp @@ -8,6 +8,8 @@ #include "core/inputsOutputs/inputs/Mouse.h" #include "ecs/standardComponents/MeshComponent.h" #include "ecs/standardComponents/TransformComponent.h" +#include "layer/DebugLayer.h" +#include "renderer/primitives/SphereFactory.h" GameScene::GameScene(engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(inputStack, keyboard, mouse), m_camera(std::make_unique()) { m_pointLight = std::make_shared(glm::vec3(.0f, 10.f, -5.0f), glm::vec3(1.0f, 1.0f, 1.0f)); @@ -36,7 +38,9 @@ void GameScene::onEnter() { pieceModels["Green"] = assetManager->getModel("pawn_green"); pieceModels["Yellow"] = assetManager->getModel("pawn_yellow"); + addLayer(std::make_unique(*m_camera, entityRegistry, m_keyboard, m_mouse, engine::SphereFactory::createUVSphere(1.0f))); addLayer(std::make_unique(m_gameMode, entityRegistry, m_camera, m_pointLight, m_keyboard, m_mouse, assetManager->getModel("gameboard"), pieceModels)); + } void GameScene::onExit() { diff --git a/game/src/ludo/LudoTypes.h b/game/src/ludo/LudoTypes.h index c85a521..8353d55 100644 --- a/game/src/ludo/LudoTypes.h +++ b/game/src/ludo/LudoTypes.h @@ -16,7 +16,7 @@ namespace ludo { inline constexpr int kTrackLength = 40; inline constexpr int kHomeStretchLength = 4; - inline constexpr float kPieceRadius = 0.3f; + inline constexpr float kPieceRadius = 0.7f; enum class PlayerColor : uint8_t { Red, Blue, Yellow, Green, Count}; constexpr std::string_view toString(PlayerColor color) diff --git a/game/src/ludo/PiecePresenter.cpp b/game/src/ludo/PiecePresenter.cpp index ccd847e..b6ff05c 100644 --- a/game/src/ludo/PiecePresenter.cpp +++ b/game/src/ludo/PiecePresenter.cpp @@ -4,10 +4,12 @@ #include "PiecePresenter.h" + #include "ecs/standardComponents/MeshComponent.h" #include "ecs/standardComponents/PickableComponent.h" #include "ecs/standardComponents/TransformComponent.h" + void ludo::PiecePresenter::spawnPieces(const ludo::LudoGameState &state) { for (const auto& piece : state.getPieces()) { auto entity = m_registry.createEntity(); diff --git a/game/src/ludo/ecs/highlight/HighlightComponent.h b/game/src/ludo/ecs/highlight/HighlightComponent.h new file mode 100644 index 0000000..5298353 --- /dev/null +++ b/game/src/ludo/ecs/highlight/HighlightComponent.h @@ -0,0 +1,15 @@ +// +// Created by sebastian on 04.08.26. +// + +#ifndef COLORRACE_HIGHLIGHTCOMPONENT_H +#define COLORRACE_HIGHLIGHTCOMPONENT_H +#include "glm/vec3.hpp" + +namespace ludo { + struct HighlightComponent { + glm::vec3 highlightColor; + }; + +} +#endif //COLORRACE_HIGHLIGHTCOMPONENT_H diff --git a/game/src/ludo/ecs/highlight/HighlightSystem.cpp b/game/src/ludo/ecs/highlight/HighlightSystem.cpp new file mode 100644 index 0000000..4dde42d --- /dev/null +++ b/game/src/ludo/ecs/highlight/HighlightSystem.cpp @@ -0,0 +1,26 @@ +// +// Created by sebastian on 04.08.26. +// + +#include "HighlightSystem.h" + +#include "HighlightComponent.h" +#include "ecs/systems/PickingSystem.h" + +void ludo::HighlightSystem::update(const engine::Mouse& mouse, engine::EntityRegistry ®istry) { + auto [origin, dir] = engine::PickingSystem::screenToRay(mouse.getXY(/*ndc=*/true), m_camera); + float closestT = std::numeric_limits::max(); + std::optional hit; + + for (const auto& [entity, pickable] : registry.getPool()) { + const auto transform = registry.getComponent(entity); + if (float t; engine::PickingSystem::raySphereIntersect(origin, dir, transform.m_position, pickable.radius, t) && t < closestT) { + closestT = t; + hit = entity; + } + } + + if (hit.has_value()) { + registry.addComponent(hit.value(), HighlightComponent({1.0, 1.0f, 1.0})); + } +} diff --git a/game/src/ludo/ecs/highlight/HighlightSystem.h b/game/src/ludo/ecs/highlight/HighlightSystem.h new file mode 100644 index 0000000..21989fa --- /dev/null +++ b/game/src/ludo/ecs/highlight/HighlightSystem.h @@ -0,0 +1,22 @@ +// +// Created by sebastian on 04.08.26. +// + +#ifndef COLORRACE_HIGHLIGHTSYSTEM_H +#define COLORRACE_HIGHLIGHTSYSTEM_H +#include "core/inputsOutputs/inputs/Mouse.h" +#include "ecs/EntityRegistry.h" +#include "renderer/entities/Camera.h" + + +namespace ludo { + class HighlightSystem { + public: + explicit HighlightSystem(engine::Camera& camera) : m_camera(camera) {} + void update(const engine::Mouse& mouse, engine::EntityRegistry& registry); + private: + engine::Camera& m_camera; + }; +} + +#endif //COLORRACE_HIGHLIGHTSYSTEM_H