diff options
| author | Sébastien Crozet <developer@crozet.re> | 2022-04-28 18:24:01 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-28 18:24:01 +0200 |
| commit | 488aad0af3f772e14fd85b27bfff6c1db5d23829 (patch) | |
| tree | 4c19f613750fcd8779714915dbb752ce369a4173 | |
| parent | 21a31bc1026d17d30b3a5ac35e6bb716dc66be6e (diff) | |
| parent | 7dc038aec66783d72abda446d6251385e6ad30f4 (diff) | |
| download | rapier-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
37 files changed, 1890 insertions, 197 deletions
@@ -14,12 +14,13 @@ resolver = "2" #parry3d-f64 = { path = "../parry/crates/parry3d-f64" } # nalgebra = { path = "../nalgebra" } + #kiss3d = { git = "https://github.com/sebcrozet/kiss3d" } #nalgebra = { git = "https://github.com/dimforge/nalgebra", branch = "dev" } -parry2d = { git = "https://github.com/dimforge/parry", branch = "split-and-qbvh" } -parry3d = { git = "https://github.com/dimforge/parry", branch = "split-and-qbvh" } -parry2d-f64 = { git = "https://github.com/dimforge/parry", branch = "split-and-qbvh" } -parry3d-f64 = { git = "https://github.com/dimforge/parry", branch = "split-and-qbvh" } +parry2d = { git = "https://github.com/dimforge/parry", branch = "master" } +parry3d = { git = "https://github.com/dimforge/parry", branch = "master" } +parry2d-f64 = { git = "https://github.com/dimforge/parry", branch = "master" } +parry3d-f64 = { git = "https://github.com/dimforge/parry", branch = "master" } [profile.release] #debug = true diff --git a/crates/rapier2d-f64/Cargo.toml b/crates/rapier2d-f64/Cargo.toml index 44a86bd..f0a85d9 100644 --- a/crates/rapier2d-f64/Cargo.toml +++ b/crates/rapier2d-f64/Cargo.toml @@ -28,6 +28,7 @@ simd-is-enabled = [ "vec_map" ] wasm-bindgen = [ "instant/wasm-bindgen" ] serde-serialize = [ "nalgebra/serde-serialize", "parry2d-f64/serde-serialize", "serde", "bit-vec/serde", "arrayvec/serde" ] enhanced-determinism = [ "simba/libm_force", "parry2d-f64/enhanced-determinism", "indexmap" ] +debug-render = [ ] # Feature used for debugging only. debug-disable-legitimate-fe-exceptions = [ ] diff --git a/crates/rapier2d/Cargo.toml b/crates/rapier2d/Cargo.toml index ad79f12..172c3c8 100644 --- a/crates/rapier2d/Cargo.toml +++ b/crates/rapier2d/Cargo.toml @@ -28,6 +28,7 @@ simd-is-enabled = [ "vec_map" ] wasm-bindgen = [ "instant/wasm-bindgen" ] serde-serialize = [ "nalgebra/serde-serialize", "parry2d/serde-serialize", "serde", "bit-vec/serde", "arrayvec/serde" ] enhanced-determinism = [ "simba/libm_force", "parry2d/enhanced-determinism", "indexmap" ] +debug-render = [ ] # Feature used for debugging only. debug-disable-legitimate-fe-exceptions = [ ] diff --git a/crates/rapier3d-f64/Cargo.toml b/crates/rapier3d-f64/Cargo.toml index 1b8c1dc..6cdf20f 100644 --- a/crates/rapier3d-f64/Cargo.toml +++ b/crates/rapier3d-f64/Cargo.toml @@ -28,6 +28,7 @@ simd-is-enabled = [ "vec_map" ] wasm-bindgen = [ "instant/wasm-bindgen" ] serde-serialize = [ "nalgebra/serde-serialize", "parry3d-f64/serde-serialize", "serde", "bit-vec/serde" ] enhanced-determinism = [ "simba/libm_force", "parry3d-f64/enhanced-determinism" ] +debug-render = [] # Feature used for debugging only. debug-disable-legitimate-fe-exceptions = [ ] diff --git a/crates/rapier3d/Cargo.toml b/crates/rapier3d/Cargo.toml index 4aae73a..7f4896d 100644 --- a/crates/rapier3d/Cargo.toml +++ b/crates/rapier3d/Cargo.toml @@ -28,6 +28,7 @@ simd-is-enabled = [ "vec_map" ] wasm-bindgen = [ "instant/wasm-bindgen" ] serde-serialize = [ "nalgebra/serde-serialize", "parry3d/serde-serialize", "serde", "bit-vec/serde" ] enhanced-determinism = [ "simba/libm_force", "parry3d/enhanced-determinism" ] +debug-render = [ ] # Feature used for debugging only. debug-disable-legitimate-fe-exceptions = [ ] diff --git a/crates/rapier_testbed2d-f64/Cargo.toml b/crates/rapier_testbed2d-f64/Cargo.toml index cfa0f42..c29a1ea 100644 --- a/crates/rapier_testbed2d-f64/Cargo.toml +++ b/crates/rapier_testbed2d-f64/Cargo.toml @@ -38,20 +38,21 @@ bincode = "1" Inflector = "0.11" md5 = "0.7" -bevy_egui = "0.10" -bevy_ecs = "0.6" +bevy_egui = "0.13" +bevy_ecs = "0.7" +#bevy_prototype_debug_lines = "0.7" # Dependencies for native only. [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -bevy = {version = "0.6", default-features = false, features = ["bevy_winit", "render", "x11"]} +bevy = {version = "0.7", default-features = false, features = ["bevy_winit", "render", "x11"]} # Dependencies for WASM only. [target.'cfg(target_arch = "wasm32")'.dependencies] -bevy = {version = "0.6", default-features = false, features = ["bevy_winit", "render"]} +bevy = {version = "0.7", default-features = false, features = ["bevy_winit", "render"]} #bevy_webgl2 = "0.5" [dependencies.rapier] package = "rapier2d-f64" path = "../rapier2d-f64" version = "0.12.0-alpha.1" -features = [ "serde-serialize" ] +features = [ "serde-serialize", "debug-render" ] diff --git a/crates/rapier_testbed2d/Cargo.toml b/crates/rapier_testbed2d/Cargo.toml index 6b0430a..d1a21a7 100644 --- a/crates/rapier_testbed2d/Cargo.toml +++ b/crates/rapier_testbed2d/Cargo.toml @@ -38,20 +38,21 @@ bincode = "1" Inflector = "0.11" md5 = "0.7" -bevy_egui = "0.10" -bevy_ecs = "0.6" +bevy_egui = "0.13" +bevy_ecs = "0.7" +#bevy_prototype_debug_lines = "0.7" # Dependencies for native only. [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -bevy = {version = "0.6", default-features = false, features = ["bevy_winit", "render", "x11"]} +bevy = {version = "0.7", default-features = false, features = ["bevy_winit", "render", "x11"]} # Dependencies for WASM only. [target.'cfg(target_arch = "wasm32")'.dependencies] -bevy = {version = "0.6", default-features = false, features = ["bevy_winit", "render"]} +bevy = {version = "0.7", default-features = false, features = ["bevy_winit", "render"]} #bevy_webgl2 = "0.5" [dependencies.rapier] package = "rapier2d" path = "../rapier2d" version = "0.12.0-alpha.1" -features = [ "serde-serialize" ] +features = [ "serde-serialize", "debug-render" ] diff --git a/crates/rapier_testbed3d-f64/Cargo.toml b/crates/rapier_testbed3d-f64/Cargo.toml index dfd0fbd..a08338b 100644 --- a/crates/rapier_testbed3d-f64/Cargo.toml +++ b/crates/rapier_testbed3d-f64/Cargo.toml @@ -36,20 +36,21 @@ md5 = "0.7" Inflector = "0.11" serde = { version = "1", features = [ "derive" ] } -bevy_egui = "0.10" -bevy_ecs = "0.6" +bevy_egui = "0.13" +bevy_ecs = "0.7" +#bevy_prototype_debug_lines = { version = "0.7", features = [ "3d" ] } # Dependencies for native only. [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -bevy = {version = "0.6", default-features = false, features = ["bevy_winit", "render", "x11"]} +bevy = {version = "0.7", default-features = false, features = ["bevy_winit", "render", "x11"]} # Dependencies for WASM only. [target.'cfg(target_arch = "wasm32")'.dependencies] -bevy = {version = "0.6", default-features = false, features = ["bevy_winit", "render"]} +bevy = {version = "0.7", default-features = false, features = ["bevy_winit", "render"]} #bevy_webgl2 = "0.5" [dependencies.rapier] package = "rapier3d-f64" path = "../rapier3d-f64" version = "0.12.0-alpha.1" -features = [ "serde-serialize" ]
\ No newline at end of file +features = [ "serde-serialize", "debug-render" ]
\ No newline at end of file diff --git a/crates/rapier_testbed3d/Cargo.toml b/crates/rapier_testbed3d/Cargo.toml index 89a050f..a258938 100644 --- a/crates/rapier_testbed3d/Cargo.toml +++ b/crates/rapier_testbed3d/Cargo.toml @@ -40,20 +40,21 @@ md5 = "0.7" Inflector = "0.11" serde = { version = "1", features = [ "derive" ] } -bevy_egui = "0.10" -bevy_ecs = "0.6" +bevy_egui = "0.13" +bevy_ecs = "0.7" +#bevy_prototype_debug_lines = { version = "0.7", features = [ "3d" ] } # Dependencies for native only. [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -bevy = {version = "0.6", default-features = false, features = ["bevy_winit", "render", "x11"]} +bevy = {version = "0.7", default-features = false, features = ["bevy_winit", "render", "x11"]} # Dependencies for WASM only. [target.'cfg(target_arch = "wasm32")'.dependencies] -bevy = {version = "0.6", default-features = false, features = ["bevy_winit", "render"]} +bevy = {version = "0.7", default-features = false, features = ["bevy_winit", "render"]} #bevy_webgl2 = "0.5" [dependencies.rapier] package = "rapier3d" path = "../rapier3d" version = "0.12.0-alpha.1" -features = [ "serde-serialize" ]
\ No newline at end of file +features = [ "serde-serialize", "debug-render" ]
\ No newline at end of file diff --git a/examples3d/joints3.rs b/examples3d/joints3.rs index b5dc984..f7c6cb3 100644 --- a/examples3d/joints3.rs +++ b/examples3d/joints3.rs @@ -578,33 +578,33 @@ fn do_init_world(testbed: &mut Testbed, use_articulations: bool) { let mut impulse_joints = ImpulseJointSet::new(); let mut multibody_joints = MultibodyJointSet::new(); - // create_prismatic_joints( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // point![20.0, 5.0, 0.0], - // 4, - // use_articulations, - // ); - // create_actuated_prismatic_joints( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // point![25.0, 5.0, 0.0], - // 4, - // use_articulations, - // ); - // create_revolute_joints( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // point![20.0, 0.0, 0.0], - // 3, - // use_articulations, - // ); + create_prismatic_joints( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + point![20.0, 5.0, 0.0], + 4, + use_articulations, + ); + create_actuated_prismatic_joints( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + point![25.0, 5.0, 0.0], + 4, + use_articulations, + ); + create_revolute_joints( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + point![20.0, 0.0, 0.0], + 3, + use_articulations, + ); create_revolute_joints_with_limits( &mut bodies, &mut colliders, @@ -613,57 +613,57 @@ fn do_init_world(testbed: &mut Testbed, use_articulations: bool) { point![34.0, 0.0, 0.0], use_articulations, ); - // create_fixed_joints( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // point![0.0, 10.0, 0.0], - // 10, - // use_articulations, - // ); - // create_actuated_revolute_joints( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // point![20.0, 10.0, 0.0], - // 6, - // use_articulations, - // ); - // create_actuated_spherical_joints( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // point![13.0, 10.0, 0.0], - // 3, - // use_articulations, - // ); - // create_spherical_joints( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // 15, - // use_articulations, - // ); - // create_spherical_joints_with_limits( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // point![-5.0, 0.0, 0.0], - // use_articulations, - // ); - // create_coupled_joints( - // &mut bodies, - // &mut colliders, - // &mut impulse_joints, - // &mut multibody_joints, - // point![0.0, 20.0, 0.0], - // use_articulations, - // ); + create_fixed_joints( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + point![0.0, 10.0, 0.0], + 10, + use_articulations, + ); + create_actuated_revolute_joints( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + point![20.0, 10.0, 0.0], + 6, + use_articulations, + ); + create_actuated_spherical_joints( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + point![13.0, 10.0, 0.0], + 3, + use_articulations, + ); + create_spherical_joints( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + 15, + use_articulations, + ); + create_spherical_joints_with_limits( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + point![-5.0, 0.0, 0.0], + use_articulations, + ); + create_coupled_joints( + &mut bodies, + &mut colliders, + &mut impulse_joints, + &mut multibody_joints, + point![0.0, 20.0, 0.0], + use_articulations, + ); /* * Set up the testbed. diff --git a/src/dynamics/ccd/ccd_solver.rs b/src/dynamics/ccd/ccd_solver.rs index 77a1ff7..bdde135 100644 --- a/src/dynamics/ccd/ccd_solver.rs +++ b/src/dynamics/ccd/ccd_solver.rs @@ -4,7 +4,7 @@ use crate::geometry::{ColliderParent, ColliderSet, CollisionEvent, NarrowPhase}; use crate::math::Real; use crate::parry::utils::SortedPair; use crate::pipeline::{EventHandler, QueryPipeline, QueryPipelineMode}; -use crate::prelude::ActiveEvents; +use crate::prelude::{ActiveEvents, CollisionEventFlags}; use parry::query::{DefaultQueryDispatcher, QueryDispatcher}; use parry::utils::hashmap::HashMap; use std::collections::BinaryHeap; @@ -529,8 +529,18 @@ impl CCDSolver { .contains(ActiveEvents::COLLISION_EVENTS) { // Emit one intersection-started and one intersection-stopped event. - events.handle_collision_event(CollisionEvent::Started(toi.c1, toi.c2), None); - events.handle_collision_event(CollisionEvent::Stopped(toi.c1, toi.c2, false), None); + events.handle_collision_event( + bodies, + colliders, + CollisionEvent::Started(toi.c1, toi.c2, CollisionEventFlags::SENSOR), + None, + ); + events.handle_collision_event( + bodies, + colliders, + CollisionEvent::Stopped(toi.c1, toi.c2, CollisionEventFlags::SENSOR), + None, + ); } } diff --git a/src/dynamics/integration_parameters.rs b/src/dynamics/integration_parameters.rs index 84c8117..6a86a2a 100644 --- a/src/dynamics/integration_parameters.rs +++ b/src/dynamics/integration_parameters.rs @@ -93,12 +93,12 @@ impl IntegrationParameters { /// The ERP coefficient, multiplied by the inverse timestep length. pub fn erp_inv_dt(&self) -> Real { - self.erp / self.dt + self.erp * self.inv_dt() } /// The joint ERP coefficient, multiplied by the inverse timestep length. pub fn joint_erp_inv_dt(&self) -> Real { - self.joint_erp / self.dt + self.joint_erp * self.inv_dt() } /// The CFM factor to be used in the constraints resolution. diff --git a/src/dynamics/joint/multibody_joint/multibody_joint_set.rs b/src/dynamics/joint/multibody_joint/multibody_joint_set.rs index 748530f..06dff5d 100644 --- a/src/dynamics/joint/multibody_joint/multibody_joint_set.rs +++ b/src/dynamics/joint/multibody_joint/multibody_joint_set.rs @@ -299,10 +299,20 @@ impl MultibodyJointSet { } /// Gets a mutable reference to the multibody identified by its `handle`. + pub fn get_mut(&mut self, handle: MultibodyJointHandle) -> Option<(&mut Multibody, usize)> { + let link = self.rb2mb.get(handle.0)?; + let multibody = self.multibodies.get_mut(link.multibody.0)?; + Some((multibody, link.id)) + } + + /// Gets a mutable reference to the multibody identified by its `handle`. + /// + /// This method will bypass any modification-detection automatically done by the MultibodyJointSet. pub fn get_mut_internal( &mut self, handle: MultibodyJointHandle, ) -> Option<(&mut Multibody, usize)> { + // TODO: modification tracking? let link = self.rb2mb.get(handle.0)?; let multibody = self.multibodies.get_mut(link.multibody.0)?; Some((multibody, link.id)) diff --git a/src/dynamics/rigid_body.rs b/src/dynamics/rigid_body.rs index cf52c1f..24e9754 100644 --- a/src/dynamics/rigid_body.rs +++ b/src/dynamics/rigid_body.rs @@ -305,20 +305,26 @@ impl RigidBody { self.ccd.ccd_active } - /// Sets the rigid-body's initial mass properties. + /// Sets the rigid-body's additional mass properties. /// /// If `wake_up` is `true` then the rigid-body will be woken up if it was /// put to sleep because it did not move for a while. #[inline] - pub fn set_mass_properties(&mut self, props: MassProperties, wake_up: bool) { - if self.mprops.local_mprops != props { - if self.is_dynamic() && wake_up { - self.wake_up(true); - } + pub fn set_additional_mass_properties(&mut self, props: MassProperties, wake_up: bool) { + if let Some(add_mprops) = &mut self.mprops.additional_local_mprops { + self.mprops.local_mprops += props; + self.mprops.local_mprops -= **add_mprops; + **add_mprops = props; + } else { + self.mprops.additional_local_mprops = Some(Box::new(props)); + self.mprops.local_mprops += props; + } - self.mprops.local_mprops = props; - self.update_world_mass_properties(); + if self.is_dynamic() && wake_up { + self.wake_up(true); } + + self.update_world_mass_properties(); } /// The handles of colliders attached to this rigid body. 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, |
