aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--Cargo.toml9
-rw-r--r--crates/rapier2d-f64/Cargo.toml1
-rw-r--r--crates/rapier2d/Cargo.toml1
-rw-r--r--crates/rapier3d-f64/Cargo.toml1
-rw-r--r--crates/rapier3d/Cargo.toml1
-rw-r--r--crates/rapier_testbed2d-f64/Cargo.toml11
-rw-r--r--crates/rapier_testbed2d/Cargo.toml11
-rw-r--r--crates/rapier_testbed3d-f64/Cargo.toml11
-rw-r--r--crates/rapier_testbed3d/Cargo.toml11
-rw-r--r--examples3d/joints3.rs156
-rw-r--r--src/dynamics/ccd/ccd_solver.rs16
-rw-r--r--src/dynamics/integration_parameters.rs4
-rw-r--r--src/dynamics/joint/multibody_joint/multibody_joint_set.rs10
-rw-r--r--src/dynamics/rigid_body.rs22
-rw-r--r--src/geometry/contact_pair.rs45
-rw-r--r--src/geometry/mod.rs56
-rw-r--r--src/geometry/narrow_phase.rs46
-rw-r--r--src/pipeline/debug_render_pipeline/debug_render_backend.rs83
-rw-r--r--src/pipeline/debug_render_pipeline/debug_render_pipeline.rs481
-rw-r--r--src/pipeline/debug_render_pipeline/debug_render_style.rs60
-rw-r--r--src/pipeline/debug_render_pipeline/mod.rs8
-rw-r--r--src/pipeline/debug_render_pipeline/outlines.rs36
-rw-r--r--src/pipeline/event_handler.rs30
-rw-r--r--src/pipeline/mod.rs9
-rw-r--r--src/pipeline/physics_pipeline.rs11
-rw-r--r--src_testbed/camera2d.rs6
-rw-r--r--src_testbed/camera3d.rs6
-rw-r--r--src_testbed/debug_render.rs72
-rw-r--r--src_testbed/lib.rs2
-rw-r--r--src_testbed/lines/debuglines.wgsl49
-rw-r--r--src_testbed/lines/debuglines2d.wgsl31
-rw-r--r--src_testbed/lines/mod.rs373
-rw-r--r--src_testbed/lines/render_dim.rs335
-rw-r--r--src_testbed/objects/node.rs36
-rw-r--r--src_testbed/physx_backend.rs2
-rw-r--r--src_testbed/testbed.rs41
-rw-r--r--src_testbed/ui.rs4
37 files changed, 1890 insertions, 197 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 3e732d5..5704e55 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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,