Skip to main content

GridCollisionDetectionSystem Class

Collision detection system using uniform spatial partitioning for Broadphase and AABB overlaps in the Narrowphase. More...

Declaration

class helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem { ... }

Base class

classSystem

Abstract base class for game systems. More...

Public Constructors Index

GridCollisionDetectionSystem (const helios::math::aabbf &bounds, const float cellSize)

Constructs a GridCollisionDetectionSystem with specified bounds and cell size. More...

Public Member Functions Index

voidupdate (helios::engine::runtime::world::UpdateContext &updateContext) noexcept override

Performs collision detection for all active entities. More...

helios::math::aabbiworldBoundsToGridBounds (const helios::math::aabbf &aabbf) const noexcept

Converts world-space AABB bounds to grid cell indices. More...

voidupdateCollisionCandidate (helios::engine::ecs::GameObject go, const helios::math::aabbi &bounds, AabbColliderComponent *aabbColliderComponent, CollisionComponent *collisionComponent, CollisionStateComponent *collisionStateComponent)

Inserts a collision candidate into all grid cells it overlaps. More...

voidsolveCell (GridCell &cell, helios::engine::runtime::world::UpdateContext &updateContext)

Performs narrow-phase collision detection for all candidates in a cell. More...

GridCell &cell (const unsigned int x, const unsigned int y, const unsigned int z) noexcept

Accesses a grid cell by its 3D coordinates. More...

constexpr size_tcellIndex (const unsigned int x, const unsigned int y, const unsigned int z) const noexcept

Computes the 1D index of a cell in a 3D grid based on its x, y, and z coordinates. More...

unsigned intcellsX () const noexcept

Returns the number of cells along the X axis. More...

unsigned intcellsY () const noexcept

Returns the number of cells along the Y axis. More...

unsigned intcellsZ () const noexcept

Returns the number of cells along the Z axis. More...

Private Member Functions Index

voidinitGrid ()

Initializes the grid based on world bounds and cell size. More...

voidprepareCollisionDetection ()

Prepares the grid for a new collision detection pass. More...

voidpostEvent (const helios::engine::ecs::GameObject candidate, const helios::engine::ecs::GameObject match, const helios::math::vec3f contact, const CollisionStruct collisionStruct, const helios::engine::runtime::world::UpdateContext &updateContext, CollisionStateComponent *csc_a, CollisionStateComponent *csc_b) const noexcept

Posts collision events to the UpdateContext's event sink. More...

CollisionStructfindCollisionType (const CollisionComponent *cc, const CollisionComponent *matchCC) const noexcept

Determines the collision type between two entities based on their layer masks. More...

Private Member Attributes Index

std::unordered_set< std::pair< helios::engine::ecs::EntityHandle, helios::engine::ecs::EntityHandle >, EntityHandlePairHash >solvedCollisions_

Set of already-processed collision pairs to avoid duplicate events. More...

floatcellSize_

Size of each grid cell in world units. More...

helios::math::aabbfgridBounds_

World-space bounds defining the spatial region covered by the grid. More...

std::vector< GridCell >cells_

Flat storage for all grid cells, indexed as x + y * cellsX + z * (cellsX * cellsY). More...

unsigned intcellsX_

Number of cells along the X axis. More...

unsigned intcellsY_

Number of cells along the Y axis. More...

unsigned intcellsZ_

Number of cells along the Z axis. More...

std::vector< size_t >trackedCells_

Helper to keep track of updated cells (with potential collisions candidates) in one pass. More...

Private Static Attributes Index

static const auto &logger_ = helios::util::log::LogManager::loggerForScope(HELIOS_LOG_SCOPE)

Scoped logger instance for structured logging within the current context. More...

Description

Collision detection system using uniform spatial partitioning for Broadphase and AABB overlaps in the Narrowphase.

This system implements a grid-based spatial partitioning approach for efficient collision detection, following the principles outlined in Ericson's "Real-Time Collision Detection" (Chapter 7). The algorithm divides the world into a uniform 3D grid of cells and assigns each collidable entity to the cells it overlaps.

## Detection Phases

1. **Broadphase:** Entities are inserted into grid cells based on their AABB. Only entities sharing the same cell are considered potential collision pairs. 2. **Narrowphase:** For each cell with multiple candidates, AABB intersection tests determine actual collisions.

## Collision Types

Collision events are published to the `UpdateContext`'s event sink, distinguishing between:

  • **Solid collisions:** Symmetric collisions where both entities can physically interact.
  • **Trigger collisions:** Asymmetric collisions for gameplay logic (e.g., pickups, zones).

## Hit Policy

The system respects each entity's HitPolicy setting:

  • **OneHit:** Entity receives only its first collision per frame, then skips further checks.
  • **All:** Entity receives collision events for all overlapping entities.

This allows projectiles to stop on first contact while area effects can damage multiple targets.

## Layer Filtering

During the broadphase, the system uses layer masks to filter which entity types can collide with each other, enabling fine-grained control over collision pairs.

See Also

CollisionComponent

See Also

AabbColliderComponent

See Also

TriggerCollisionEvent

See Also

SolidCollisionEvent

See Also

HitPolicy

See Also

[Eri05, Chapter 7]

Definition at line 91 of file GridCollisionDetectionSystem.ixx.

Public Constructors

GridCollisionDetectionSystem()

helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::GridCollisionDetectionSystem (const helios::math::aabbf & bounds, const float cellSize)
inline explicit

Constructs a GridCollisionDetectionSystem with specified bounds and cell size.

The grid is initialized to cover the given world bounds. Cell size determines the granularity of spatial partitioning; smaller cells reduce false positives but increase memory and insertion overhead.

Parameters
bounds

World-space AABB defining the region where collision detection is active.

cellSize

Size of each grid cell in world units. Must be greater than zero.

info

Given n objects, the 1/3 rule should be applied for determining the number of cells for partitioning, i.e. with n objects, the cube should consist of k x k x k cells, with k = n^{1/3} - that is, on average, one cell fits one object that should be tested for collision. Dimensions of said cells are derived by taking the reference space into account, e.g. WorldBounds.size/k (see [HS99]).

Definition at line 412 of file GridCollisionDetectionSystem.ixx.

413 const helios::math::aabbf& bounds,
414 const float cellSize
415 ) : gridBounds_(bounds),
416 cellSize_(cellSize) {
417 assert(cellSize_ > 0.0f && "cellSize must not be <= 0.0f");
418 initGrid();
419 }

Public Member Functions

cell()

GridCell & helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cell (const unsigned int x, const unsigned int y, const unsigned int z)
inline nodiscard noexcept

Accesses a grid cell by its 3D coordinates.

Parameters
x

X-coordinate of the cell (0 to cellsX - 1).

y

Y-coordinate of the cell (0 to cellsY - 1).

z

Z-coordinate of the cell (0 to cellsZ - 1).

Returns

Reference to the GridCell at the specified coordinates.

Definition at line 655 of file GridCollisionDetectionSystem.ixx.

655 [[nodiscard]] inline GridCell& cell(const unsigned int x, const unsigned int y, const unsigned int z) noexcept {
656 return cells_[cellIndex(x, y, z)];
657 }

Reference cellIndex.

Referenced by solveCell and updateCollisionCandidate.

cellIndex()

size_t helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cellIndex (const unsigned int x, const unsigned int y, const unsigned int z)
inline nodiscard constexpr noexcept

Computes the 1D index of a cell in a 3D grid based on its x, y, and z coordinates.

Parameters
x

The x-coordinate of the cell (must be less than the grid's x-dimension).

y

The y-coordinate of the cell (must be less than the grid's y-dimension).

z

The z-coordinate of the cell (must be less than the grid's z-dimension).

Returns

The 1D index of the cell in the grid.

Definition at line 668 of file GridCollisionDetectionSystem.ixx.

668 [[nodiscard]] inline constexpr size_t cellIndex(const unsigned int x, const unsigned int y, const unsigned int z) const noexcept {
669 assert (x < cellsX_ && y < cellsY_ && z < cellsZ_ && "Invalid range values");
670
671 return x + y * cellsX_ + (z * cellsX_ * cellsY_);
672 }

Referenced by cell and updateCollisionCandidate.

cellsX()

unsigned int helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cellsX ()
inline nodiscard noexcept

Returns the number of cells along the X axis.

Returns

Number of grid cells in the X dimension.

Definition at line 679 of file GridCollisionDetectionSystem.ixx.

679 [[nodiscard]] unsigned int cellsX() const noexcept {
680 return cellsX_;
681 }

cellsY()

unsigned int helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cellsY ()
inline nodiscard noexcept

Returns the number of cells along the Y axis.

Returns

Number of grid cells in the Y dimension.

Definition at line 688 of file GridCollisionDetectionSystem.ixx.

688 [[nodiscard]] unsigned int cellsY() const noexcept {
689 return cellsY_;
690 }

cellsZ()

unsigned int helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cellsZ ()
inline nodiscard noexcept

Returns the number of cells along the Z axis.

Returns

Number of grid cells in the Z dimension.

Definition at line 697 of file GridCollisionDetectionSystem.ixx.

697 [[nodiscard]] unsigned int cellsZ() const noexcept {
698 return cellsZ_;
699 }

solveCell()

void helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::solveCell (GridCell & cell, helios::engine::runtime::world::UpdateContext & updateContext)
inline

Performs narrow-phase collision detection for all candidates in a cell.

Tests all unique pairs of collision candidates within the cell using AABB intersection. For each collision detected, determines collision type (solid/trigger) based on layer masks and publishes appropriate events. Uses a solved-set to avoid duplicate events when entities span multiple cells.

Parameters
cell

The grid cell containing collision candidates to test.

updateContext

Context for pushing collision events to the event queue.

Definition at line 570 of file GridCollisionDetectionSystem.ixx.

570 inline void solveCell(GridCell& cell, helios::engine::runtime::world::UpdateContext& updateContext) {
571
572 auto& candidates = cell.collisionCandidates;
573
574 // we will skip this cell if none of the candidates reports a collision
575 bool isCollisionReporter = false;
576 for (const auto& candidate : candidates) {
577 if (candidate.collisionComponent->isCollisionReporter()) {
578 isCollisionReporter = true;
579 break;
580 }
581 }
582
583 if (!isCollisionReporter) {
584 return;
585 }
586
587 for (size_t i = 0; i < candidates.size(); i++) {
588
589 CollisionCandidate& candidate = candidates[i];
590 CollisionComponent* cc = candidate.collisionComponent;
591 CollisionStateComponent* csc = candidate.collisionStateComponent;
592
593 auto hitPolicy = cc->hitPolicy();
595 continue;
596 }
597
598 const helios::math::aabbf& aabbCandidate = candidate.aabbColliderComponent->bounds();
599
600 for (size_t j = i+1; j < candidates.size(); j++) {
601
602 auto& [gameObject, aabbColliderComponent, collisionComponent, collisionStateComponent] = candidates[j];
603
604 CollisionComponent* matchCC = collisionComponent;
605 CollisionStateComponent* matchCSC = collisionStateComponent;
606
607 const auto collisionStruct = findCollisionType(cc, matchCC);
608
609 if (!collisionStruct.hasAnyInteraction()) {
610 continue;
611 }
612
613 const helios::math::aabbf& aabbMatch = aabbColliderComponent->bounds();
614 if (!aabbCandidate.intersects(aabbMatch)) {
615 continue;
616 }
617
618 auto lHandle = candidate.gameObject.entityHandle();
619 auto rHandle = gameObject.entityHandle();
620
621 if (lHandle > rHandle) {
622 std::swap(lHandle, rHandle);
623 }
624
625 // if we have already processed a collision, do not add this collision again.
626 if (solvedCollisions_.contains({lHandle, rHandle})) {
627 continue;
628 }
629
630 solvedCollisions_.insert({lHandle, rHandle});
631
632 postEvent(
633 candidate.gameObject, gameObject,
634 helios::math::overlapCenter(aabbCandidate, aabbMatch),
635 collisionStruct,
636 updateContext, csc, matchCSC
637 );
638
640 break;
641 }
642 }
643 }
644 }

References helios::engine::modules::physics::collision::components::AabbColliderComponent::bounds, cell, helios::engine::ecs::GameObject::entityHandle, helios::engine::modules::physics::collision::components::CollisionStateComponent::hasCollision, helios::engine::modules::physics::collision::components::CollisionComponent::hitPolicy, helios::math::aabb< T >::intersects, helios::engine::modules::physics::collision::types::OneHit and helios::math::overlapCenter.

Referenced by update.

update()

void helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::update (helios::engine::runtime::world::UpdateContext & updateContext)
inline noexcept virtual

Performs collision detection for all active entities.

Executes the complete collision detection pipeline each frame: 1. Clears all grid cells and resets solved collision pairs. 2. Iterates all active GameObjects with CollisionComponent and AabbColliderComponent. 3. Inserts each entity into all grid cells its AABB overlaps. 4. For each cell with multiple candidates, runs narrow-phase AABB intersection tests. 5. Publishes collision events (TriggerCollisionEvent, SolidCollisionEvent) to the event queue.

Parameters
updateContext

The update context providing access to GameWorld and event queue.

Definition at line 433 of file GridCollisionDetectionSystem.ixx.

433 void update(helios::engine::runtime::world::UpdateContext& updateContext) noexcept override {
434
435 prepareCollisionDetection();
436
437 for (auto [entity, cc, csc, acc, active] : gameWorld_->view<
442 >().whereEnabled()) {
443
444 if (!acc->boundsInitialized()) {
445 continue;
446 }
447
448 if (!cc->isEnabled() || (cc->triggerCollisionMask() == 0 && cc->solidCollisionMask() == 0)) {
449 continue;
450 }
451
452 const auto& worldBounds = acc->bounds();
453
455 entity,
456 worldBoundsToGridBounds(worldBounds),
457 acc,
458 cc,
459 csc
460 );
461 }
462
463 for (const auto idx : trackedCells_) {
464
465 if (cells_[idx].collisionCandidates.size() < 2) {
466 continue;
467 }
468
469 solveCell(cells_[idx], updateContext);
470 }
471 }

References helios::engine::ecs::System::gameWorld_, helios::engine::modules::physics::collision::components::CollisionComponent::isEnabled, helios::engine::modules::physics::collision::components::CollisionComponent::solidCollisionMask, solveCell, helios::engine::modules::physics::collision::components::CollisionComponent::triggerCollisionMask, updateCollisionCandidate and worldBoundsToGridBounds.

updateCollisionCandidate()

void helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::updateCollisionCandidate (helios::engine::ecs::GameObject go, const helios::math::aabbi & bounds, AabbColliderComponent * aabbColliderComponent, CollisionComponent * collisionComponent, CollisionStateComponent * collisionStateComponent)
inline

Inserts a collision candidate into all grid cells it overlaps.

Iterates through all cells within the given bounds and adds the candidate to each cell's collision candidate list for subsequent narrow-phase testing.

Parameters
go

Pointer to the GameObject entity.

bounds

Grid cell index bounds (integer AABB) the entity spans.

aabbColliderComponent

Pointer to the entity's AABB collider component.

collisionComponent

Pointer to the entity's collision component.

Definition at line 519 of file GridCollisionDetectionSystem.ixx.

521 const helios::math::aabbi& bounds,
522 AabbColliderComponent* aabbColliderComponent,
523 CollisionComponent* collisionComponent,
524 CollisionStateComponent* collisionStateComponent
525 ) {
526 const auto xMin = bounds.min()[0];
527 const auto xMax = bounds.max()[0];
528 const auto yMin = bounds.min()[1];
529 const auto yMax = bounds.max()[1];
530 const auto zMin = bounds.min()[2];
531 const auto zMax = bounds.max()[2];
532
533 for (int x = xMin; x <= xMax; x++) {
534 for (int y = yMin; y <= yMax; y++) {
535 for (int z = zMin; z <= zMax; z++) {
536 auto& [collisionCandidates] = cell(x, y, z);
537
538 collisionCandidates.push_back(
539 CollisionCandidate{
540 go,
541 aabbColliderComponent,
542 collisionComponent,
543 collisionStateComponent
544 }
545 );
546
547 // only consider the first added to prevent dups
548 if (collisionCandidates.size() == 1) {
549 const auto idx = cellIndex(x, y, z);
550 trackedCells_.push_back(idx);
551 }
552 }
553 }
554 }
555
556 }

References cell, cellIndex, helios::math::aabb< T >::max and helios::math::aabb< T >::min.

Referenced by update.

worldBoundsToGridBounds()

helios::math::aabbi helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::worldBoundsToGridBounds (const helios::math::aabbf & aabbf)
inline nodiscard noexcept

Converts world-space AABB bounds to grid cell indices.

Transforms a floating-point AABB in world space to integer cell coordinates, clamped to the valid grid range. Used to determine which cells an entity occupies.

Parameters
aabbf

The world-space AABB to convert.

Returns

An integer AABB representing the range of grid cell indices the entity spans.

Definition at line 484 of file GridCollisionDetectionSystem.ixx.

484 [[nodiscard]] helios::math::aabbi worldBoundsToGridBounds(const helios::math::aabbf& aabbf) const noexcept {
485
486 helios::math::vec3f min = aabbf.min() - gridBounds_.min();
487 helios::math::vec3f max = aabbf.max() - gridBounds_.min();
488
489 int xMin = static_cast<int>(std::floor(min[0] / cellSize_));
490 int yMin = static_cast<int>(std::floor(min[1] / cellSize_));
491 int zMin = static_cast<int>(std::floor(min[2] / cellSize_));
492
493 int xMax = static_cast<int>(std::floor(max[0] / cellSize_));
494 int yMax = static_cast<int>(std::floor(max[1] / cellSize_));
495 int zMax = static_cast<int>(std::floor(max[2] / cellSize_));
496
498 std::clamp(xMin, 0, static_cast<int>(cellsX_ - 1)),
499 std::clamp(yMin, 0, static_cast<int>(cellsY_ - 1)),
500 std::clamp(zMin, 0, static_cast<int>(cellsZ_ - 1)),
501 std::clamp(xMax, 0, static_cast<int>(cellsX_ - 1)),
502 std::clamp(yMax, 0, static_cast<int>(cellsY_ - 1)),
503 std::clamp(zMax, 0, static_cast<int>(cellsZ_ - 1)),
504 };
505 }

References helios::math::aabb< T >::max and helios::math::aabb< T >::min.

Referenced by update.

Private Member Functions

findCollisionType()

CollisionStruct helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::findCollisionType (const CollisionComponent * cc, const CollisionComponent * matchCC)
inline nodiscard noexcept

Determines the collision type between two entities based on their layer masks.

Evaluates both solid and trigger collision masks to determine if and how two entities can collide. Solid collisions are symmetric (both entities must accept collision with each other), while trigger collisions are asymmetric (either entity can trigger).

Parameters
cc

Collision component of the first entity.

matchCC

Collision component of the second entity.

Returns

CollisionStruct a struct with the requested collision information.

Definition at line 344 of file GridCollisionDetectionSystem.ixx.

344 [[nodiscard]] inline CollisionStruct findCollisionType(
345 const CollisionComponent* cc,
346 const CollisionComponent* matchCC
347 ) const noexcept {
348
349 auto isSolidCollision = false;
350 auto isTriggerCollision = false;
351
352 auto aIsCollisionReporter = cc->isCollisionReporter();
353 auto bIsCollisionReporter = matchCC->isCollisionReporter();
354
355 // none of the reports a collision as a pair? skip!
356 if (!aIsCollisionReporter && !bIsCollisionReporter) {
357 return CollisionStruct{};
358 }
359
360 bool aCanSolidCollideWithB = (cc->solidCollisionMask() & matchCC->layerId()) != 0;
361 bool bCanSolidCollideWithA = (matchCC->solidCollisionMask() & cc->layerId()) != 0;
362
363 bool aCanTriggerCollideWithB = (cc->triggerCollisionMask() & matchCC->layerId()) != 0;
364 bool bCanTriggerCollideWithA = (matchCC->triggerCollisionMask() & cc->layerId()) != 0;
365
366 // solid collision is treated symmetric
367 isSolidCollision = aCanSolidCollideWithB && bCanSolidCollideWithA;
368
369 #if HELIOS_DEBUG
370 // detect asymmetric solid collision
371 if (aCanSolidCollideWithB && !bCanSolidCollideWithA) {
372 logger_.warn("Collision Asymmetry detected!");
373 }
374 #endif
375
376 // trigger collision is treated asymmetric
377 isTriggerCollision = aCanTriggerCollideWithB || bCanTriggerCollideWithA;
378
379 return CollisionStruct {
380 isSolidCollision,
381 isTriggerCollision,
382 aIsCollisionReporter,
383 bIsCollisionReporter,
384 isSolidCollision
385 ? cc->solidCollisionBehavior(matchCC->layerId()) : cc->triggerCollisionBehavior(matchCC->layerId()),
386 isSolidCollision
387 ? matchCC->solidCollisionBehavior(cc->layerId()) : matchCC->triggerCollisionBehavior(cc->layerId()),
388 // use the layerId of cc
389 cc->layerId(),
390 matchCC->layerId()
391
392 };
393 }

initGrid()

void helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::initGrid ()
inline

Initializes the grid based on world bounds and cell size.

Computes the number of cells needed in each dimension and allocates the cell storage.

Definition at line 244 of file GridCollisionDetectionSystem.ixx.

244 void initGrid() {
245
246 helios::math::vec3f size = gridBounds_.size();
247
248 cellsX_ = std::max(1u, static_cast<unsigned int>(std::ceil(size[0] / cellSize_)));
249 cellsY_ = std::max(1u, static_cast<unsigned int>(std::ceil(size[1] / cellSize_)));
250 cellsZ_ = std::max(1u, static_cast<unsigned int>(std::ceil(size[2] / cellSize_)));
251
252 const size_t cellCount = static_cast<size_t>(cellsX_) * cellsY_ * cellsZ_;
253
254 // this would make 100'000'000 * sizeof(GridCell) Bytes
255 // if we have 24 Bytes per GridCell, we end up with 2,4 GB alone for this spatial grid.
256 if (cellCount > 100'000'000) {
257 logger_.warn(std::format("Spatial Grid requested {0} cells", cellCount));
258 throw std::runtime_error("Cell count too high.");
259 }
260
261 trackedCells_.reserve(cellCount);
262 cells_.resize(cellCount);
263 }

postEvent()

void helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::postEvent (const helios::engine::ecs::GameObject candidate, const helios::engine::ecs::GameObject match, const helios::math::vec3f contact, const CollisionStruct collisionStruct, const helios::engine::runtime::world::UpdateContext & updateContext, CollisionStateComponent * csc_a, CollisionStateComponent * csc_b)
inline noexcept

Posts collision events to the UpdateContext's event sink.

Updates the CollisionStateComponent of both entities with collision information including contact point, collision type, behavior, and reporter status. An entity marked as collision reporter receives the event as the "source" entity.

Parameters
candidate

First collision candidate (potential event source).

match

Second collision candidate (collision partner).

contact

The contact point between the two AABBs.

collisionStruct

Struct containing collision type and behavior information.

updateContext

Context for pushing events to the event queue.

csc_a

Collision state component of the first entity.

csc_b

Collision state component of the second entity.

Definition at line 295 of file GridCollisionDetectionSystem.ixx.

295 inline void postEvent(
296 const helios::engine::ecs::GameObject candidate,
298 const helios::math::vec3f contact,
299 const CollisionStruct collisionStruct,
303 ) const noexcept {
304
305 bool aIsCollisionReporter = collisionStruct.aIsCollisionReporter;
306 bool bIsCollisionReporter = collisionStruct.bIsCollisionReporter;
307 bool isSolidCollision = collisionStruct.isSolidCollision;
308 bool isTriggerCollision = collisionStruct.isTriggerCollision;
309 uint32_t collisionLayer = collisionStruct.collisionLayer;
310 uint32_t otherCollisionLayer = collisionStruct.otherCollisionLayer;
311
312 assert((isSolidCollision || isTriggerCollision)
313 && (aIsCollisionReporter || bIsCollisionReporter)
314 && "Preconditions not matched for postEvent.");
315
316 // post the events
317 if (isTriggerCollision || isSolidCollision) {
318 csc_a->setState(
319 candidate,
320 contact, isSolidCollision, isTriggerCollision, collisionStruct.aCollisionBehavior,
321 aIsCollisionReporter, match.entityHandle(), collisionLayer, otherCollisionLayer
322 );
323 csc_b->setState(
324 match,
325 contact, isSolidCollision, isTriggerCollision, collisionStruct.bCollisionBehavior,
326 bIsCollisionReporter, candidate.entityHandle(), collisionLayer, otherCollisionLayer
327 );
328 }
329
330 }

prepareCollisionDetection()

void helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::prepareCollisionDetection ()
inline

Prepares the grid for a new collision detection pass.

Clears all collision candidates from every cell and resets the set of already-solved collision pairs.

Definition at line 271 of file GridCollisionDetectionSystem.ixx.

271 inline void prepareCollisionDetection() {
272 for (const auto idx : trackedCells_) {
273 cells_[idx].clear();
274 }
275
276 trackedCells_.clear();
277 solvedCollisions_.clear();
278 }

Private Member Attributes

cells_

std::vector<GridCell> helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cells_

Flat storage for all grid cells, indexed as x + y * cellsX + z * (cellsX * cellsY).

Definition at line 216 of file GridCollisionDetectionSystem.ixx.

216 std::vector<GridCell> cells_;

cellSize_

float helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cellSize_

Size of each grid cell in world units.

Definition at line 206 of file GridCollisionDetectionSystem.ixx.

206 float cellSize_;

cellsX_

unsigned int helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cellsX_

Number of cells along the X axis.

Definition at line 221 of file GridCollisionDetectionSystem.ixx.

221 unsigned int cellsX_;

cellsY_

unsigned int helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cellsY_

Number of cells along the Y axis.

Definition at line 226 of file GridCollisionDetectionSystem.ixx.

226 unsigned int cellsY_;

cellsZ_

unsigned int helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::cellsZ_

Number of cells along the Z axis.

Definition at line 231 of file GridCollisionDetectionSystem.ixx.

231 unsigned int cellsZ_;

gridBounds_

helios::math::aabbf helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::gridBounds_

World-space bounds defining the spatial region covered by the grid.

Definition at line 211 of file GridCollisionDetectionSystem.ixx.

211 helios::math::aabbf gridBounds_;

solvedCollisions_

std::unordered_set<std::pair<helios::engine::ecs::EntityHandle, helios::engine::ecs::EntityHandle>, EntityHandlePairHash> helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::solvedCollisions_

Set of already-processed collision pairs to avoid duplicate events.

Stores pairs of EntityHandles in canonical order (smaller handle first) to ensure each collision pair is processed only once per frame, even when entities span multiple cells.

Definition at line 201 of file GridCollisionDetectionSystem.ixx.

201 std::unordered_set<std::pair<helios::engine::ecs::EntityHandle, helios::engine::ecs::EntityHandle>, EntityHandlePairHash> solvedCollisions_;

trackedCells_

std::vector<size_t> helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::trackedCells_

Helper to keep track of updated cells (with potential collisions candidates) in one pass.

Definition at line 236 of file GridCollisionDetectionSystem.ixx.

236 std::vector<size_t> trackedCells_;

Private Static Attributes

logger_

const auto& helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::logger_ = helios::util::log::LogManager::loggerForScope(HELIOS_LOG_SCOPE)
static

Scoped logger instance for structured logging within the current context.

Definition at line 193 of file GridCollisionDetectionSystem.ixx.

193 static inline const auto& logger_ = helios::util::log::LogManager::loggerForScope(HELIOS_LOG_SCOPE);

The documentation for this class was generated from the following file:


Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.