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 { ... }

Public Member Typedefs Index

usingEngineRoleTag = helios::engine::common::tags::SystemRole

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

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

Updates the CollisionStateComponent for interacting entities. 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 state is updated in the `CollisionStateComponent`, 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

HitPolicy

See Also

[Eri05, Chapter 7]

Definition at line 88 of file GridCollisionDetectionSystem.ixx.

Public Member Typedefs

EngineRoleTag

using helios::engine::modules::physics::collision::systems::GridCollisionDetectionSystem::EngineRoleTag = helios::engine::common::tags::SystemRole

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.

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

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. Updates collision state components for detected collisions.

Parameters
updateContext

The update context providing access to GameWorld and event queue.

Definition at line 433 of file GridCollisionDetectionSystem.ixx.

434
435 prepareCollisionDetection();
436
437 for (auto [entity, cc, csc, acc, active] : updateContext.view<
442 >().whereEnabled().exclude<DeadTagComponent>()) {
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::modules::physics::collision::components::CollisionComponent::isEnabled, helios::engine::modules::physics::collision::components::CollisionComponent::solidCollisionMask, solveCell, helios::engine::modules::physics::collision::components::CollisionComponent::triggerCollisionMask, updateCollisionCandidate, helios::engine::runtime::world::UpdateContext::view 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.

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 and cellIndex.

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 342 of file GridCollisionDetectionSystem.ixx.

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

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 241 of file GridCollisionDetectionSystem.ixx.

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

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

Updates the CollisionStateComponent for interacting entities.

Updates the CollisionStateComponent of both entities with collision information including contact point, collision type, behavior, and reporter status.

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 291 of file GridCollisionDetectionSystem.ixx.

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

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 268 of file GridCollisionDetectionSystem.ixx.

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

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 213 of file GridCollisionDetectionSystem.ixx.

213 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 203 of file GridCollisionDetectionSystem.ixx.

203 float cellSize_;

cellsX_

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

Number of cells along the X axis.

Definition at line 218 of file GridCollisionDetectionSystem.ixx.

218 unsigned int cellsX_;

cellsY_

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

Number of cells along the Y axis.

Definition at line 223 of file GridCollisionDetectionSystem.ixx.

223 unsigned int cellsY_;

cellsZ_

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

Number of cells along the Z axis.

Definition at line 228 of file GridCollisionDetectionSystem.ixx.

228 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 208 of file GridCollisionDetectionSystem.ixx.

208 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 198 of file GridCollisionDetectionSystem.ixx.

198 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 233 of file GridCollisionDetectionSystem.ixx.

233 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 190 of file GridCollisionDetectionSystem.ixx.

190 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.