Skip to content

Commit

Permalink
feat(collisions): emit event on collision
Browse files Browse the repository at this point in the history
  • Loading branch information
luishfonseca committed Nov 12, 2023
1 parent eb22748 commit 6ac6f55
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
23 changes: 23 additions & 0 deletions engine/include/cubos/engine/collisions/collision_event.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// @file
/// @brief Event @ref cubos::engine::CollisionEvent.
/// @ingroup collisions-plugin

#pragma once

#include <glm/vec3.hpp>

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

namespace cubos::engine
{
/// @brief Represents a collision event.
/// @ingroup collisions-plugin
struct CollisionEvent
{
cubos::core::ecs::Entity entity; ///< Entity involved in the collision.
cubos::core::ecs::Entity other; ///< Other entity involved in the collision.
float penetration; ///< Penetration depth of the collision.
glm::vec3 position; ///< Position of contact on the surface of the entity.
glm::vec3 normal; ///< Normal of contact on the surface of the entity.
};
}; // namespace cubos::engine
54 changes: 54 additions & 0 deletions engine/src/cubos/engine/collisions/plugin.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#include "broad_phase/plugin.hpp"

#include <cubos/core/ecs/system/event/writer.hpp>
#include <cubos/core/ecs/system/query.hpp>

#include <cubos/engine/collisions/broad_phase/candidates.hpp>
#include <cubos/engine/collisions/collider.hpp>
#include <cubos/engine/collisions/collision_event.hpp>
#include <cubos/engine/collisions/plugin.hpp>
#include <cubos/engine/collisions/shapes/box.hpp>
#include <cubos/engine/collisions/shapes/capsule.hpp>
#include <cubos/engine/transform/plugin.hpp>

using cubos::core::ecs::EventWriter;
using cubos::core::ecs::Query;
using cubos::core::ecs::Read;
using cubos::core::ecs::Write;
Expand Down Expand Up @@ -51,16 +55,66 @@ static void setupNewCapsulesSystem(Query<Read<CapsuleCollisionShape>, Write<Coll
}
}

/// TODO: This is a temporary system should be removed once narrow phase is implemented.
static void emitCollisionEventSystem(Query<Read<Collider>> query, Read<BroadPhaseCandidates> candidates,
EventWriter<CollisionEvent> events)
{
for (const auto& [ent1, ent2] : candidates->candidates(BroadPhaseCandidates::CollisionType::BoxBox))
{
auto [collider1] = query[ent1].value();
auto [collider2] = query[ent2].value();

auto c1 = collider1->worldAABB.center();
auto b1 = collider1->worldAABB.box();

auto c2 = collider2->worldAABB.center();
auto b2 = collider2->worldAABB.box();

auto d = c2 - c1;
auto p = (b2.halfSize + b1.halfSize) - glm::abs(d);

auto s = glm::sign(d);

float penetration = 0.0F;
glm::vec3 normal{0.0F};
glm::vec3 pos{0.0F};

if (p.x < p.y && p.x < p.z)
{
penetration = p.x;
normal.x = s.x;
pos.x = c1.x + (b1.halfSize.x * s.x);
}
else if (p.y < p.x && p.y < p.z)
{
penetration = p.y;
normal.y = s.y;
pos.y = c1.y + (b1.halfSize.y * s.y);
}
else
{
penetration = p.z;
normal.z = s.z;
pos.z = c1.z + (b1.halfSize.z * s.z);
}

events.push(CollisionEvent{ent1, ent2, penetration, normal, pos});
}
}

void cubos::engine::collisionsPlugin(Cubos& cubos)
{
cubos.addPlugin(transformPlugin);

cubos.addPlugin(broadPhaseCollisionsPlugin);

cubos.addEvent<CollisionEvent>();

cubos.addComponent<Collider>();
cubos.addComponent<BoxCollisionShape>();
cubos.addComponent<CapsuleCollisionShape>();

cubos.system(setupNewBoxesSystem).tagged("cubos.collisions.setup");
cubos.system(setupNewCapsulesSystem).tagged("cubos.collisions.setup");
cubos.system(emitCollisionEventSystem).tagged("cubos.collisions").after("cubos.collisions.setup");
}

0 comments on commit 6ac6f55

Please sign in to comment.