1#[cfg(feature = "alloc")]
4pub(crate) use self::broad_phase_bvh::DeferredBvhOptimize;
5#[cfg(feature = "alloc")]
6pub use self::broad_phase_bvh::{BroadPhaseBvh, BvhOptimizationStrategy};
7pub use self::broad_phase_pair_event::{BroadPhasePairEvent, ColliderPair};
8#[cfg(feature = "alloc")]
9pub use self::collider::{Collider, ColliderBuilder};
10#[cfg(feature = "alloc")]
11pub use self::collider_components::*;
12pub use self::collider_handle::ColliderHandle;
13#[cfg(feature = "alloc")]
14pub use self::collider_set::{ColliderSet, ModifiedColliders};
15#[cfg(feature = "alloc")]
16pub(crate) use self::contact_pair::ContactRecycleState;
17#[cfg(feature = "alloc")]
18pub(crate) use self::contact_pair::PairEventStatus;
19#[cfg(feature = "alloc")]
20pub(crate) use self::contact_pair::SOLVER_DYNAMIC_COLOR_COUNT;
21#[cfg(feature = "alloc")]
22pub(crate) use self::contact_pair::relative_pose_drift;
23#[cfg(feature = "alloc")]
24pub use self::contact_pair::{
25 ContactData, ContactId, ContactManifoldData, ContactPair, IntersectionPair, NEW_CONTACT_BIT,
26 SimdSolverContact, SolverContact, SolverContactGeneric, SolverContacts, SolverFlags, is_bouncy,
27 is_bouncy_simd,
28};
29#[cfg(feature = "alloc")]
30pub use self::interaction_graph::{
31 ColliderGraphIndex, InteractionGraph, RigidBodyGraphIndex, TemporaryInteractionIndex,
32};
33pub use self::interaction_groups::{Group, InteractionGroups, InteractionTestMode};
34#[cfg(feature = "alloc")]
35pub use self::mesh_converter::{MeshConverter, MeshConverterError};
36#[cfg(feature = "alloc")]
37pub use self::narrow_phase::NarrowPhase;
38#[cfg(feature = "alloc")]
39pub use parry::utils::Array2;
40
41pub use parry::bounding_volume::BoundingVolume;
42#[cfg(feature = "alloc")]
43pub use parry::partitioning::{Bvh, BvhBuildStrategy};
44#[cfg(feature = "alloc")]
45pub use parry::query::{PointQuery, PointQueryWithLocation, RayCast, TrackedContact};
46#[cfg(feature = "alloc")]
47pub use parry::shape::{SharedShape, VoxelState, VoxelType, Voxels};
48
49#[cfg(feature = "alloc")]
50use crate::math::{Real, Vector};
51
52#[cfg(feature = "alloc")]
54pub type Contact = parry::query::TrackedContact<ContactData>;
55#[cfg(feature = "alloc")]
57pub type ContactManifold = parry::query::ContactManifold<ContactManifoldData, ContactData>;
58pub type Segment = parry::shape::Segment;
60pub type Cuboid = parry::shape::Cuboid;
62pub type Triangle = parry::shape::Triangle;
64pub type Ball = parry::shape::Ball;
66pub type Capsule = parry::shape::Capsule;
68#[cfg(feature = "alloc")]
70pub type HeightField = parry::shape::HeightField;
71#[cfg(feature = "dim3")]
73pub type Cylinder = parry::shape::Cylinder;
74#[cfg(feature = "dim3")]
76pub type Cone = parry::shape::Cone;
77pub type Aabb = parry::bounding_volume::Aabb;
79pub type Ray = parry::query::Ray;
81pub type RayIntersection = parry::query::RayIntersection;
83pub type PointProjection = parry::query::PointProjection;
85pub type ShapeCastHit = parry::query::ShapeCastHit;
87#[cfg(feature = "alloc")]
89pub type DefaultBroadPhase = BroadPhaseBvh;
90
91bitflags::bitflags! {
92 #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
94 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
95 pub struct CollisionEventFlags: u32 {
96 const SENSOR = 0b0001;
99 const REMOVED = 0b0010;
102 }
103}
104
105#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
106#[derive(Copy, Clone, Hash, Debug)]
107pub enum CollisionEvent {
137 Started(ColliderHandle, ColliderHandle, CollisionEventFlags),
139 Stopped(ColliderHandle, ColliderHandle, CollisionEventFlags),
141}
142
143impl CollisionEvent {
144 pub fn started(self) -> bool {
146 matches!(self, CollisionEvent::Started(..))
147 }
148
149 pub fn stopped(self) -> bool {
151 matches!(self, CollisionEvent::Stopped(..))
152 }
153
154 pub fn collider1(self) -> ColliderHandle {
156 match self {
157 Self::Started(h, _, _) | Self::Stopped(h, _, _) => h,
158 }
159 }
160
161 pub fn collider2(self) -> ColliderHandle {
163 match self {
164 Self::Started(_, h, _) | Self::Stopped(_, h, _) => h,
165 }
166 }
167
168 pub fn sensor(self) -> bool {
170 match self {
171 Self::Started(_, _, f) | Self::Stopped(_, _, f) => {
172 f.contains(CollisionEventFlags::SENSOR)
173 }
174 }
175 }
176
177 pub fn removed(self) -> bool {
179 match self {
180 Self::Started(_, _, f) | Self::Stopped(_, _, f) => {
181 f.contains(CollisionEventFlags::REMOVED)
182 }
183 }
184 }
185}
186
187#[cfg(feature = "alloc")]
188#[derive(Copy, Clone, PartialEq, Debug, Default)]
189pub struct ContactForceEvent {
192 pub collider1: ColliderHandle,
194 pub collider2: ColliderHandle,
196 pub total_force: Vector,
198 pub total_force_magnitude: Real,
204 pub max_force_direction: Vector,
206 pub max_force_magnitude: Real,
208 pub started: bool,
218}
219
220#[cfg(feature = "alloc")]
221impl ContactForceEvent {
222 pub fn from_contact_pair(dt: Real, pair: &ContactPair, total_force_magnitude: Real) -> Self {
224 let mut result = ContactForceEvent {
225 collider1: pair.collider1,
226 collider2: pair.collider2,
227 total_force_magnitude,
228 started: !pair
231 .event_status
232 .contains(PairEventStatus::INITIAL_FORCE_THRESHOLD_EVENT_EMITTED),
233 ..ContactForceEvent::default()
234 };
235
236 for m in pair.solver_manifolds() {
237 let mut total_manifold_impulse = 0.0;
238 for pt in m.contacts() {
239 total_manifold_impulse += pt.data.impulse;
240
241 if pt.data.impulse > result.max_force_magnitude {
242 result.max_force_magnitude = pt.data.impulse;
243 result.max_force_direction = m.data.normal;
244 }
245 }
246
247 result.total_force += m.data.normal * total_manifold_impulse;
248 }
249
250 let inv_dt = crate::utils::inv(dt);
251 result.total_force *= inv_dt;
256 result.max_force_magnitude *= inv_dt;
257 result
258 }
259}
260
261#[cfg(feature = "alloc")]
262pub(crate) use self::narrow_phase::ContactManifoldIndex;
263#[cfg(feature = "alloc")]
264pub use parry::shape::*;
265
266#[cfg(all(feature = "serde-serialize", feature = "alloc"))]
267pub(crate) fn default_persistent_query_dispatcher()
268-> alloc::sync::Arc<dyn parry::query::PersistentQueryDispatcher<ContactManifoldData, ContactData>> {
269 alloc::sync::Arc::new(parry::query::DefaultQueryDispatcher)
270}
271
272#[cfg(feature = "alloc")]
273mod collider_components;
274mod collider_handle;
275#[cfg(feature = "alloc")]
276pub(crate) mod contact_pair;
277#[cfg(feature = "alloc")]
278mod interaction_graph;
279mod interaction_groups;
280#[cfg(feature = "alloc")]
281mod narrow_phase;
282
283#[cfg(feature = "alloc")]
284mod broad_phase_bvh;
285mod broad_phase_pair_event;
286#[cfg(feature = "alloc")]
287mod collider;
288#[cfg(feature = "alloc")]
289mod collider_set;
290#[cfg(feature = "alloc")]
291mod mesh_converter;
292
293#[cfg(all(feature = "dim3", feature = "alloc"))]
294mod manifold_reduction;
295
296#[cfg(all(feature = "dim3", feature = "alloc"))]
297mod contact_clustering;