aboutsummaryrefslogtreecommitdiff
path: root/src/geometry
diff options
context:
space:
mode:
authorSébastien Crozet <developer@crozet.re>2022-04-28 18:24:01 +0200
committerGitHub <noreply@github.com>2022-04-28 18:24:01 +0200
commit488aad0af3f772e14fd85b27bfff6c1db5d23829 (patch)
tree4c19f613750fcd8779714915dbb752ce369a4173 /src/geometry
parent21a31bc1026d17d30b3a5ac35e6bb716dc66be6e (diff)
parent7dc038aec66783d72abda446d6251385e6ad30f4 (diff)
downloadrapier-488aad0af3f772e14fd85b27bfff6c1db5d23829.tar.gz
rapier-488aad0af3f772e14fd85b27bfff6c1db5d23829.tar.bz2
rapier-488aad0af3f772e14fd85b27bfff6c1db5d23829.zip
Merge pull request #315 from dimforge/debug-renderer
Add a basic lines-based debug-renderer
Diffstat (limited to 'src/geometry')
-rw-r--r--src/geometry/contact_pair.rs45
-rw-r--r--src/geometry/mod.rs56
-rw-r--r--src/geometry/narrow_phase.rs46
3 files changed, 112 insertions, 35 deletions
diff --git a/src/geometry/contact_pair.rs b/src/geometry/contact_pair.rs
index a75d58d..551ffde 100644
--- a/src/geometry/contact_pair.rs
+++ b/src/geometry/contact_pair.rs
@@ -1,7 +1,8 @@
-use crate::dynamics::RigidBodyHandle;
-use crate::geometry::{ColliderHandle, Contact, ContactManifold};
+use crate::dynamics::{RigidBodyHandle, RigidBodySet};
+use crate::geometry::{ColliderHandle, ColliderSet, Contact, ContactManifold};
use crate::math::{Point, Real, Vector};
use crate::pipeline::EventHandler;
+use crate::prelude::CollisionEventFlags;
use parry::query::ContactManifoldsWorkspace;
use super::CollisionEvent;
@@ -69,22 +70,36 @@ impl IntersectionPair {
pub(crate) fn emit_start_event(
&mut self,
+ bodies: &RigidBodySet,
+ colliders: &ColliderSet,
collider1: ColliderHandle,
collider2: ColliderHandle,
events: &dyn EventHandler,
) {
self.start_event_emited = true;
- events.handle_collision_event(CollisionEvent::new(collider1, collider2, true), None);
+ events.handle_collision_event(
+ bodies,
+ colliders,
+ CollisionEvent::Started(collider1, collider2, CollisionEventFlags::SENSOR),
+ None,
+ );
}
pub(crate) fn emit_stop_event(
&mut self,
+ bodies: &RigidBodySet,
+ colliders: &ColliderSet,
collider1: ColliderHandle,
collider2: ColliderHandle,
events: &dyn EventHandler,
) {
self.start_event_emited = false;
- events.handle_collision_event(CollisionEvent::new(collider1, collider2, false), None);
+ events.handle_collision_event(
+ bodies,
+ colliders,
+ CollisionEvent::Stopped(collider1, collider2, CollisionEventFlags::SENSOR),
+ None,
+ );
}
}
@@ -155,20 +170,34 @@ impl ContactPair {
deepest
}
- pub(crate) fn emit_start_event(&mut self, events: &dyn EventHandler) {
+ pub(crate) fn emit_start_event(
+ &mut self,
+ bodies: &RigidBodySet,
+ colliders: &ColliderSet,
+ events: &dyn EventHandler,
+ ) {
self.start_event_emited = true;
events.handle_collision_event(
- CollisionEvent::new(self.collider1, self.collider2, true),
+ bodies,
+ colliders,
+ CollisionEvent::Started(self.collider1, self.collider2, CollisionEventFlags::empty()),
Some(self),
);
}
- pub(crate) fn emit_stop_event(&mut self, events: &dyn EventHandler) {
+ pub(crate) fn emit_stop_event(
+ &mut self,
+ bodies: &RigidBodySet,
+ colliders: &ColliderSet,
+ events: &dyn EventHandler,
+ ) {
self.start_event_emited = false;
events.handle_collision_event(
- CollisionEvent::new(self.collider1, self.collider2, false),
+ bodies,
+ colliders,
+ CollisionEvent::Stopped(self.collider1, self.collider2, CollisionEventFlags::empty()),
Some(self),
);
}
diff --git a/src/geometry/mod.rs b/src/geometry/mod.rs
index 7733ad2..34d3707 100644
--- a/src/geometry/mod.rs
+++ b/src/geometry/mod.rs
@@ -50,27 +50,29 @@ pub type PointProjection = parry::query::PointProjection;
pub type TOI = parry::query::TOI;
pub use parry::shape::SharedShape;
+bitflags::bitflags! {
+ /// Flags providing more information regarding a collision event.
+ #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
+ pub struct CollisionEventFlags: u32 {
+ /// Flag set if at least one of the colliders involved in the
+ /// collision was a sensor when the event was fired.
+ const SENSOR = 0b0001;
+ /// Flag set if a `CollisionEvent::Stopped` was fired because
+ /// at least one of the colliders was removed.
+ const REMOVED = 0b0010;
+ }
+}
+
#[derive(Copy, Clone, Hash, Debug)]
-/// Events occurring when two colliders start or stop being in contact (or intersecting)
+/// Events occurring when two colliders start or stop colliding
pub enum CollisionEvent {
- /// Event occurring when two colliders start being in contact (or intersecting)
- Started(ColliderHandle, ColliderHandle),
- /// Event occurring when two colliders stop being in contact (or intersecting).
- ///
- /// The boolean is set to `true` of this event originates from at least one of
- /// the colliders being removed from the `ColliderSet`.
- Stopped(ColliderHandle, ColliderHandle, bool),
+ /// Event occurring when two colliders start colliding
+ Started(ColliderHandle, ColliderHandle, CollisionEventFlags),
+ /// Event occurring when two colliders stop colliding.
+ Stopped(ColliderHandle, ColliderHandle, CollisionEventFlags),
}
impl CollisionEvent {
- pub(crate) fn new(h1: ColliderHandle, h2: ColliderHandle, start: bool) -> Self {
- if start {
- Self::Started(h1, h2)
- } else {
- Self::Stopped(h1, h2, false)
- }
- }
-
/// Is this a `Started` collision event?
pub fn started(self) -> bool {
matches!(self, CollisionEvent::Started(..))
@@ -84,14 +86,32 @@ impl CollisionEvent {
/// The handle of the first collider involved in this collision event.
pub fn collider1(self) -> ColliderHandle {
match self {
- Self::Started(h, _) | Self::Stopped(h, _, _) => h,
+ Self::Started(h, _, _) | Self::Stopped(h, _, _) => h,
}
}
/// The handle of the second collider involved in this collision event.
pub fn collider2(self) -> ColliderHandle {
match self {
- Self::Started(_, h) | Self::Stopped(_, h, _) => h,
+ Self::Started(_, h, _) | Self::Stopped(_, h, _) => h,
+ }
+ }
+
+ /// Was at least one of the colliders involved in the collision a sensor?
+ pub fn sensor(self) -> bool {
+ match self {
+ Self::Started(_, _, f) | Self::Stopped(_, _, f) => {
+ f.contains(CollisionEventFlags::SENSOR)
+ }
+ }
+ }
+
+ /// Was at least one of the colliders involved in the collision removed?
+ pub fn removed(self) -> bool {
+ match self {
+ Self::Started(_, _, f) | Self::Stopped(_, _, f) => {
+ f.contains(CollisionEventFlags::REMOVED)
+ }
}
}
}
diff --git a/src/geometry/narrow_phase.rs b/src/geometry/narrow_phase.rs
index f4e8c58..3e7a13d 100644
--- a/src/geometry/narrow_phase.rs
+++ b/src/geometry/narrow_phase.rs
@@ -15,6 +15,7 @@ use crate::pipeline::{
ActiveEvents, ActiveHooks, ContactModificationContext, EventHandler, PairFilterContext,
PhysicsHooks,
};
+use crate::prelude::CollisionEventFlags;
use parry::query::{DefaultQueryDispatcher, PersistentQueryDispatcher};
use parry::utils::IsometryOpt;
use std::collections::HashMap;
@@ -317,14 +318,24 @@ impl NarrowPhase {
}
if pair.start_event_emited {
- events.handle_collision_event(CollisionEvent::Stopped(a, b, true), Some(pair));
+ events.handle_collision_event(
+ bodies,
+ colliders,
+ CollisionEvent::Stopped(a, b, CollisionEventFlags::REMOVED),
+ Some(pair),
+ );
}
}
} else {
// If there is no island, don’t wake-up bodies, but do send the Stopped collision event.
for (a, b, pair) in self.contact_graph.interactions_with(contact_graph_id) {
if pair.start_event_emited {
- events.handle_collision_event(CollisionEvent::Stopped(a, b, true), Some(pair));
+ events.handle_collision_event(
+ bodies,
+ colliders,
+ CollisionEvent::Stopped(a, b, CollisionEventFlags::REMOVED),
+ Some(pair),
+ );
}
}
}
@@ -332,7 +343,16 @@ impl NarrowPhase {
// Generate Stopped collision events for intersections.
for (a, b, pair) in self.intersection_graph.interactions_with(contact_graph_id) {
if pair.start_event_emited {
- events.handle_collision_event(CollisionEvent::Stopped(a, b, true), None);
+ events.handle_collision_event(
+ bodies,
+ colliders,
+ CollisionEvent::Stopped(
+ a,
+ b,
+ CollisionEventFlags::REMOVED | CollisionEventFlags::SENSOR,
+ ),
+ None,
+ );
}
}
@@ -495,7 +515,13 @@ impl NarrowPhase {
if (co1.flags.active_events | co2.flags.active_events)
.contains(ActiveEvents::COLLISION_EVENTS)
{
- intersection.emit_stop_event(pair.collider1, pair.collider2, events)
+ intersection.emit_stop_event(
+ bodies,
+ colliders,
+ pair.collider1,
+ pair.collider2,
+ events,
+ )
}
}
}
@@ -521,7 +547,7 @@ impl NarrowPhase {
if (co1.flags.active_events | co2.flags.active_events)
.contains(ActiveEvents::COLLISION_EVENTS)
{
- ctct.emit_stop_event(events);
+ ctct.emit_stop_event(bodies, colliders, events);
}
}
}
@@ -724,9 +750,11 @@ impl NarrowPhase {
&& had_intersection != edge.weight.intersecting
{
if edge.weight.intersecting {
- edge.weight.emit_start_event(handle1, handle2, events);
+ edge.weight
+ .emit_start_event(bodies, colliders, handle1, handle2, events);
} else {
- edge.weight.emit_stop_event(handle1, handle2, events);
+ edge.weight
+ .emit_stop_event(bodies, colliders, handle1, handle2, events);
}
}
});
@@ -928,9 +956,9 @@ impl NarrowPhase {
if pair.has_any_active_contact != had_any_active_contact {
if active_events.contains(ActiveEvents::COLLISION_EVENTS) {
if pair.has_any_active_contact {
- pair.emit_start_event(events);
+ pair.emit_start_event(bodies, colliders, events);
} else {
- pair.emit_stop_event(events);
+ pair.emit_stop_event(bodies, colliders, events);
}
}
}