Skip to content

Commit

Permalink
refactor: shape agnostic aabb update
Browse files Browse the repository at this point in the history
  • Loading branch information
luishfonseca committed Oct 4, 2023
1 parent c5a680c commit 5c202b5
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 32 deletions.
5 changes: 5 additions & 0 deletions engine/include/cubos/engine/collisions/collider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ namespace cubos::engine
bool fresh = true; ///< Whether the collider is fresh. This is an hack and should be done in ECS.
ColliderAABB localAABB; ///< Local space AABB of the collider.
ColliderAABB worldAABB; ///< World space AABB of the collider.

/// @brief Margin of the collider.
///
/// When the collider shape has sharp edges, a margin is needed.
float margin = 0.0F;
};
} // namespace cubos::engine
7 changes: 0 additions & 7 deletions engine/include/cubos/engine/collisions/shapes/box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,5 @@ namespace cubos::engine
struct [[cubos::component("cubos/box_collision_shape", VecStorage)]] BoxCollisionShape
{
cubos::core::geom::Box shape; ///< Box shape.

/// @brief Margin of the collider. Needed for collision stability.
///
/// The collider margin avoids collision errors by rounding off sharp corners. It is
/// absolute so the collider's transform won't affect it. Shouldn't be changed without good
/// reason, as it's preferable to scale down the collider shape to account for it.
float margin = 0.04F;
};
} // namespace cubos::engine
3 changes: 2 additions & 1 deletion engine/samples/collisions/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ static void updateCollided(Query<Read<Collider>> query, Write<State> state, Read
{
if (collider1 == entity || collider2 == entity)
{
CUBOS_WARN("Collision detected!");
state->collided = true;
break;
}
Expand Down Expand Up @@ -148,7 +149,7 @@ int main()
cubos.startupSystem(addColliders);

cubos.system(updateTransform).before("cubos.transform.update");
cubos.system(updateCollided).tagged("updated").after("cubos.collisions");
cubos.system(updateCollided).tagged("updated").after("cubos.collisions.broad");
cubos.system(render).after("updated");

cubos.run();
Expand Down
24 changes: 14 additions & 10 deletions engine/src/cubos/engine/collisions/broad_phase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ using cubos::engine::ColliderAABB;

using CollisionType = BroadPhaseCollisions::CollisionType;

void updateBoxAABBs(Query<Read<LocalToWorld>, Read<BoxCollisionShape>, Write<Collider>> query)
void setupBoxAABBs(Query<Read<BoxCollisionShape>, Write<Collider>> query)
{
for (auto [entity, localToWorld, shape, collider] : query)
for (auto [entity, shape, collider] : query)
{
if (collider->fresh)
{
Expand All @@ -15,7 +15,18 @@ void updateBoxAABBs(Query<Read<LocalToWorld>, Read<BoxCollisionShape>, Write<Col
collider->localAABB = ColliderAABB{diag[0], diag[1]};
collider->fresh = false;
}
}
}

void setupCapsuleAABBs(Query<Read<CapsuleCollisionShape>, Write<Collider>> query)
{
(void)query;
}

void updateAABBs(Query<Read<LocalToWorld>, Write<Collider>> query)
{
for (auto [entity, localToWorld, collider] : query)
{
// Get the 4 points of the collider.
glm::vec3 corners[4];
collider->localAABB.box().corners4(corners);
Expand All @@ -40,20 +51,13 @@ void updateBoxAABBs(Query<Read<LocalToWorld>, Read<BoxCollisionShape>, Write<Col
max = glm::max(max, glm::abs(rotatedCorners[3]));

// Add the collider's margin.
max += glm::vec3{shape->margin};
max += glm::vec3{collider->margin};

// Set the AABB.
collider->worldAABB = ColliderAABB{translation - max, translation + max};
}
}

void updateCapsuleAABBs(Query<Read<LocalToWorld>, Read<CapsuleCollisionShape>, Read<Collider>> query,
Write<BroadPhaseCollisions> collisions)
{
(void)query;
(void)collisions;
}

void updateMarkers(Query<Read<Collider>> query, Write<BroadPhaseCollisions> collisions)
{
// TODO: This is parallelizable.
Expand Down
16 changes: 9 additions & 7 deletions engine/src/cubos/engine/collisions/broad_phase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,24 @@ void trackNewEntities(Query<Read<S>, OptRead<Collider>> query, Write<BroadPhaseC
{
// TODO: This is a bit of a hack. We should detect newly added colliders instead of using them as a marker.

for (auto [entity, shape, aabb] : query)
for (auto [entity, shape, collider] : query)
{
if (!aabb)
if (!collider)
{
commands.add(entity, Collider{});
collisions->addEntity(entity);
}
}
}

/// @brief Updates the AABBs of all box colliders.
void updateBoxAABBs(Query<Read<LocalToWorld>, Read<BoxCollisionShape>, Write<Collider>> query);
/// @brief Setups the AABBs of all box colliders.
void setupBoxAABBs(Query<Read<BoxCollisionShape>, Write<Collider>> query);

/// @brief Updates the AABBs of all capsule colliders.
void updateCapsuleAABBs(Query<Read<LocalToWorld>, Read<CapsuleCollisionShape>, Read<Collider>> query,
Write<BroadPhaseCollisions> collisions);
/// @brief Setups the AABBs of all capsule colliders.
void setupCapsuleAABBs(Query<Read<CapsuleCollisionShape>, Write<Collider>> query);

/// @brief Updates the AABBs of all colliders.
void updateAABBs(Query<Read<LocalToWorld>, Write<Collider>> query);

/// @brief Updates the sweep markers of all colliders.
void updateMarkers(Query<Read<Collider>> query, Write<BroadPhaseCollisions> collisions);
Expand Down
15 changes: 8 additions & 7 deletions engine/src/cubos/engine/collisions/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ void cubos::engine::collisionsPlugin(Cubos& cubos)

cubos.system(trackNewEntities<BoxCollisionShape>).tagged("cubos.collisions.missing");
cubos.system(trackNewEntities<CapsuleCollisionShape>).tagged("cubos.collisions.missing");
cubos.tag("cubos.collisions.missing").before("cubos.collisions.aabb");
cubos.tag("cubos.collisions.missing").before("cubos.collisions.aabb.setup");

cubos.system(updateBoxAABBs).tagged("cubos.collisions.aabb");
cubos.system(updateCapsuleAABBs).tagged("cubos.collisions.aabb");
cubos.tag("cubos.collisions.aabb").after("cubos.transform.update");
cubos.system(setupBoxAABBs).tagged("cubos.collisions.aabb.setup");
cubos.system(setupCapsuleAABBs).tagged("cubos.collisions.aabb.setup");
cubos.system(updateAABBs)
.after("cubos.collisions.aabb.setup")
.after("cubos.transform.update")
.before("cubos.collisions.broad.markers");

cubos.system(updateMarkers).tagged("cubos.collisions.broad.markers").after("cubos.collisions.aabb");
cubos.system(updateMarkers).tagged("cubos.collisions.broad.markers");
cubos.system(sweep).tagged("cubos.collisions.broad.sweep").after("cubos.collisions.broad.markers");
cubos.system(findPairs).tagged("cubos.collisions.broad").after("cubos.collisions.broad.sweep");

cubos.tag("cubos.collisions.broad").before("cubos.collisions");
}

0 comments on commit 5c202b5

Please sign in to comment.