5#include <unordered_set>
10#include "collision/collisionBuffer.hpp"
12#include "components/AABBCollider.hpp"
13#include "components/Transform.hpp"
15namespace rtk::systems {
37 : _collisionBuffer(collisionBuffer), _window(window),
38 _inputState(inputState) {}
44 void onStart(rtk::ecs::Registry &)
override {
45 constexpr std::array<std::uint8_t, 4> whitePixel{255, 255, 255, 255};
46 const std::span<const std::uint8_t> pixels{whitePixel};
48 _debugTextureId = _window.loadTextureFromMemory(pixels, 1, 1).getHandle();
55 void update(rtk::ecs::Registry ®istry,
float)
override {
56 _collidingEntities.clear();
58 for (
const auto &collision : _collisionBuffer.
collisions()) {
59 _collidingEntities.insert(collision.firstEntity);
60 _collidingEntities.insert(collision.secondEntity);
63 std::vector<DebugLine> lines;
71 constexpr float thickness = 2.f;
73 for (
const auto entity : view) {
74 const auto *transform = transforms.get(entity);
75 const auto *collider = colliders.get(entity);
77 if (!transform || !collider)
81 transform->
position.
x + collider->offsetX * transform->scale.x;
82 const float secondX = firstX + collider->width * transform->scale.x;
84 transform->position.y + collider->offsetY * transform->scale.y;
85 const float secondY = firstY + collider->height * transform->scale.y;
87 const float left = std::min(firstX, secondX);
88 const float top = std::min(firstY, secondY);
89 const float right = std::max(firstX, secondX);
90 const float bottom = std::max(firstY, secondY);
91 const float width = right - left;
92 const float height = bottom - top;
93 const bool colliding = _collidingEntities.contains(entity);
95 lines.push_back({left, top, width, thickness, colliding});
97 {left, bottom - thickness, width, thickness, colliding});
98 lines.push_back({left, top, thickness, height, colliding});
99 lines.push_back({right - thickness, top, thickness, height, colliding});
103 resizeDebugEntities(registry, lines.size());
105 for (std::size_t index = 0; index < lines.size(); ++index)
106 updateDebugLine(registry, _debugEntities[index], lines[index]);
113 void onStop(rtk::ecs::Registry ®istry)
override {
114 for (
const auto entity : _debugEntities)
115 registry.kill_entity(entity);
119 _debugEntities.clear();
120 _collidingEntities.clear();
124 void clearDebugEntities(rtk::ecs::Registry ®istry) {
125 for (
const auto entity : _debugEntities)
126 registry.kill_entity(entity);
128 _debugEntities.clear();
139 void resizeDebugEntities(rtk::ecs::Registry ®istry, std::size_t count) {
140 while (_debugEntities.size() < count) {
141 const auto entity = registry.spawn_entity();
145 registry.get_components<ecs::concepts::SpriteData>().insert_at(
146 entity, ecs::concepts::SpriteData{});
148 _debugEntities.push_back(entity);
151 while (_debugEntities.size() > count) {
152 registry.kill_entity(_debugEntities.back());
153 _debugEntities.pop_back();
157 void updateDebugLine(rtk::ecs::Registry ®istry, std::size_t entity,
158 const DebugLine &line) {
162 registry.get_components<ecs::concepts::SpriteData>().get(entity);
164 if (!transform || !sprite)
167 transform->position = {line.x, line.y};
168 transform->rotation = 0.f;
169 transform->scale = {1.f, 1.f};
171 if (!_inputState.
debug)
172 sprite->size = {0, 0};
174 sprite->size = {line.width, line.height};
175 sprite->origin = {0.f, 0.f};
176 sprite->textureRect = {0, 0, 1, 1};
177 sprite->color = line.colliding ? ecs::concepts::ColorRGBA8{255, 0, 0, 255}
178 : ecs::concepts::ColorRGBA8{0, 255, 0, 255};
179 sprite->textureId = _debugTextureId;
183 rtk::RenderWindow &_window;
186 std::uint32_t _debugTextureId = 0;
188 std::vector<std::size_t> _debugEntities;
189 std::unordered_set<std::size_t> _collidingEntities;
Collisions detected during the current frame.
Definition collisionBuffer.hpp:24
const std::vector< Collision > & collisions() const
Returns the stored collisions.
Definition collisionBuffer.hpp:41
Draws collider outlines while the debug overlay is enabled.
Definition DebugCollisionSystem.hpp:26
void onStart(rtk::ecs::Registry &) override
Creates the 1x1 white texture used to draw outlines.
Definition DebugCollisionSystem.hpp:44
DebugCollisionSystem(const rtk::collision::CollisionBuffer &collisionBuffer, rtk::RenderWindow &window, const rtk::InputState &inputState)
Creates the system.
Definition DebugCollisionSystem.hpp:34
void update(rtk::ecs::Registry ®istry, float) override
Updates one outline entity per collider edge.
Definition DebugCollisionSystem.hpp:55
void onStop(rtk::ecs::Registry ®istry) override
Destroys the outline entities.
Definition DebugCollisionSystem.hpp:113
Axis aligned bounding box used for collision detection.
Definition AABBCollider.hpp:40
float x
Horizontal component.
Definition vec2.hpp:13