Skip to content

Commit

Permalink
refactor(collisions): extract broadphase to plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
luishfonseca committed Oct 6, 2023
1 parent 5d133d8 commit db4adfa
Show file tree
Hide file tree
Showing 14 changed files with 400 additions and 346 deletions.
5 changes: 3 additions & 2 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ set(CUBOS_ENGINE_SOURCE
"src/cubos/engine/voxels/palette.cpp"

"src/cubos/engine/collisions/plugin.cpp"
"src/cubos/engine/collisions/broad_phase.cpp"
"src/cubos/engine/collisions/broad_phase_collisions.cpp"
"src/cubos/engine/collisions/broad_phase/plugin.cpp"
"src/cubos/engine/collisions/broad_phase/sweep_and_prune.cpp"
"src/cubos/engine/collisions/broad_phase/candidates.cpp"

"src/cubos/engine/input/plugin.cpp"
"src/cubos/engine/input/input.cpp"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// @file
/// @brief Resource @ref cubos::engine::BroadPhaseCollisions.
/// @ingroup collisions-plugin
/// @brief Resource @ref cubos::engine::Candidates.
/// @ingroup broad-phase-collisions-plugin

#pragma once

Expand All @@ -13,9 +13,9 @@

namespace cubos::engine
{
/// @brief Resource which stores data used in broad phase collision detection.
/// @ingroup collisions-plugin
struct BroadPhaseCollisions
/// @brief Resource which stores candidates found in broad phase collision detection.
/// @ingroup broad-phase-collisions-plugin
struct BroadPhaseCandidates
{
/// @brief Pair of entities that may collide.
using Candidate = std::pair<core::ecs::Entity, core::ecs::Entity>;
Expand All @@ -39,41 +39,10 @@ namespace cubos::engine
Count ///< Number of collision types.
};

/// @brief Marker used for sweep and prune.
struct SweepMarker
{
core::ecs::Entity entity; ///< Entity referenced by the marker.
bool isMin; ///< Whether the marker is a min or max marker.
};

/// @brief List of ordered sweep markers for each axis. Stores the index of the marker in mMarkers.
std::vector<SweepMarker> markersPerAxis[3];

/// @brief Maps of overlapping entities for each axis calculated by sweep and prune.
///
/// For each each map, the key is an entity and the value is a list of entities that
/// overlap with the key. Symmetrical pairs are not stored.
std::unordered_map<core::ecs::Entity, std::vector<core::ecs::Entity>, core::ecs::EntityHash>
sweepOverlapMaps[3];

/// @brief Set of active entities during sweep for each axis.
std::unordered_set<core::ecs::Entity, core::ecs::EntityHash> activePerAxis[3];

/// @brief Sets of collision candidates for each collision type. The index of the array is
/// the collision type.
std::unordered_set<Candidate, CandidateHash> candidatesPerType[static_cast<std::size_t>(CollisionType::Count)];

/// @brief Adds an entity to the list of entities tracked by sweep and prune.
/// @param entity Entity to add.
void addEntity(core::ecs::Entity entity);

/// @brief Removes an entity from the list of entities tracked by sweep and prune.
/// @param entity Entity to remove.
void removeEntity(core::ecs::Entity entity);

/// @brief Clears the list of entities tracked by sweep and prune.
void clearEntities();

/// @brief Adds a collision candidate to the list of candidates for a specific collision type.
/// @param type Collision type.
/// @param candidate Collision candidate.
Expand Down
27 changes: 27 additions & 0 deletions engine/include/cubos/engine/collisions/broad_phase/plugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/// @dir
/// @brief @ref broad-phase-collisions-plugin plugin directory.

/// @file
/// @brief Plugin entry point.
/// @ingroup broad-phase-collisions-plugin

#pragma once

#include <cubos/engine/cubos.hpp>

namespace cubos::engine
{
/// @defgroup broad-phase-collisions-plugin Broad-phase Collisions
/// @ingroup engine
/// @brief Adds broad-phase collision detection to @b CUBOS.
///
/// ## Resources
/// - @ref BroadPhaseCandidates - stores broad phase collision data.
/// - @ref BroadPhaseSweepAndPrune - stores sweep and prune markers.
///

/// @brief Plugin entry function.
/// @param cubos @b CUBOS. main class.
/// @ingroup broad-phase-collisions-plugin
void broadPhaseCollisionsPlugin(Cubos& cubos);
} // namespace cubos::engine
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/// @file
/// @brief Resource @ref cubos::engine::BroadPhaseSweepAndPrune.
/// @ingroup broad-phase-collisions-plugin

#pragma once

#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cubos/core/ecs/entity/hash.hpp>
#include <cubos/core/ecs/entity/manager.hpp>

namespace cubos::engine
{
/// @brief Resource which stores sweep and prune data.
/// @ingroup broad-phase-collisions-plugin
struct BroadPhaseSweepAndPrune
{
/// @brief Marker used for sweep and prune.
struct SweepMarker
{
core::ecs::Entity entity; ///< Entity referenced by the marker.
bool isMin; ///< Whether the marker is a min or max marker.
};

/// @brief List of ordered sweep markers for each axis. Stores the index of the marker in mMarkers.
std::vector<SweepMarker> markersPerAxis[3];

/// @brief Maps of overlapping entities for each axis calculated by sweep and prune.
///
/// For each each map, the key is an entity and the value is a list of entities that
/// overlap with the key. Symmetrical pairs are not stored.
std::unordered_map<core::ecs::Entity, std::vector<core::ecs::Entity>, core::ecs::EntityHash>
sweepOverlapMaps[3];

/// @brief Set of active entities during sweep for each axis.
std::unordered_set<core::ecs::Entity, core::ecs::EntityHash> activePerAxis[3];

/// @brief Adds an entity to the list of entities tracked by sweep and prune.
/// @param entity Entity to add.
void addEntity(core::ecs::Entity entity);

/// @brief Removes an entity from the list of entities tracked by sweep and prune.
/// @param entity Entity to remove.
void removeEntity(core::ecs::Entity entity);

/// @brief Clears the list of entities tracked by sweep and prune.
void clearEntities();
};
} // namespace cubos::engine
2 changes: 1 addition & 1 deletion engine/include/cubos/engine/collisions/collider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ namespace cubos::engine
/// The plugin will set it based on the shape associated with the collider.
float margin;

bool fresh = true; ///< Whether the collider is fresh. This is an hack and should be done in ECS.
int fresh = -1; ///< This is an hack and should be done in ECS.
};
} // namespace cubos::engine
23 changes: 10 additions & 13 deletions engine/include/cubos/engine/collisions/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
/// @brief Plugin entry point.
/// @ingroup collisions-plugin

/// @dir ./colliders
/// @brief Collider components directory.
/// @dir ./shapes
/// @brief Collision shapes components directory.

/// @dir ./broad_phase
/// @brief Broad phase collision sub-plugin directory.

#pragma once

Expand All @@ -19,23 +22,17 @@ namespace cubos::engine
/// @brief Adds collision detection to @b CUBOS.
///
/// ## Components
/// - @ref BoxCollider - holds the box collider data.
/// - @ref CapsuleCollider - holds the capsule collider data.
/// - @ref BoxCollisionShape - holds the box collision shape.
/// - @ref CapsuleCollisionShape - holds the capsule collision shape.
/// - @ref Collider - holds collider data.
///
/// ## Events
/// - @ref CollisionEvent - (TODO) emitted when a collision occurs.
/// - @ref TriggerEvent - (TODO) emitted when a trigger is entered or exited.
///
/// ## Resources
/// - @ref BroadPhaseCollisions - stores broad phase collision data.
///
/// ## Tags
/// - `cubos.collisions.aabb.missing` - missing aabb colliders are added.
/// - `cubos.collisions.aabb` - collider aabbs are updated.
/// - `cubos.collisions.broad.markers` - sweep markers are updated.
/// - `cubos.collisions.broad.sweep` - sweep is performed.
/// - `cubos.collisions.broad` - broad phase collision detection.
/// - `cubos.collisions` - collisions are resolved.
/// - `cubos.collisions.setup` - new colliders are setup.
/// - `cubos.collisions.broad` - broad phase candidate pairs are generated.
///
/// ## Dependencies
/// - @ref transform-plugin
Expand Down
6 changes: 3 additions & 3 deletions engine/samples/collisions/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <cubos/core/gl/debug.hpp>
#include <cubos/core/log.hpp>

#include <cubos/engine/collisions/broad_phase_collisions.hpp>
#include <cubos/engine/collisions/broad_phase/candidates.hpp>
#include <cubos/engine/collisions/collider.hpp>
#include <cubos/engine/collisions/plugin.hpp>
#include <cubos/engine/collisions/shapes/box.hpp>
Expand Down Expand Up @@ -108,12 +108,12 @@ static void updateTransform(Write<State> state, Read<Input> input, Query<Write<P
bPos->vec += glm::vec3{0.0F, 0.0F, -0.01F};
}

static void updateCollided(Query<Read<Collider>> query, Write<State> state, Read<BroadPhaseCollisions> collisions)
static void updateCollided(Query<Read<Collider>> query, Write<State> state, Read<BroadPhaseCandidates> candidates)
{
for (auto [entity, collider] : query)
{
for (const auto& [collider1, collider2] :
collisions->candidates(BroadPhaseCollisions::CollisionType::BoxCapsule))
candidates->candidates(BroadPhaseCandidates::CollisionType::BoxCapsule))
{
if (collider1 == entity || collider2 == entity)
{
Expand Down
Loading

0 comments on commit db4adfa

Please sign in to comment.