1pub use self::broad_phase_bvh::{BroadPhaseBvh, BvhOptimizationStrategy};
4pub use self::broad_phase_pair_event::{BroadPhasePairEvent, ColliderPair};
5pub use self::collider::{Collider, ColliderBuilder};
6pub use self::collider_components::*;
7pub use self::collider_set::{ColliderSet, ModifiedColliders};
8pub use self::contact_pair::{
9 ContactData, ContactManifoldData, ContactPair, IntersectionPair, SimdSolverContact,
10 SolverContact, SolverFlags,
11};
12pub use self::interaction_graph::{
13 ColliderGraphIndex, InteractionGraph, RigidBodyGraphIndex, TemporaryInteractionIndex,
14};
15pub use self::interaction_groups::{Group, InteractionGroups, InteractionTestMode};
16pub use self::mesh_converter::{MeshConverter, MeshConverterError};
17pub use self::narrow_phase::NarrowPhase;
18
19pub use parry::bounding_volume::BoundingVolume;
20pub use parry::partitioning::{Bvh, BvhBuildStrategy};
21pub use parry::query::{PointQuery, PointQueryWithLocation, RayCast, TrackedContact};
22pub use parry::shape::{SharedShape, VoxelState, VoxelType, Voxels};
23
24use crate::math::{Real, Vector};
25
26pub type Contact = parry::query::TrackedContact<ContactData>;
28pub type ContactManifold = parry::query::ContactManifold<ContactManifoldData, ContactData>;
30pub type Segment = parry::shape::Segment;
32pub type Cuboid = parry::shape::Cuboid;
34pub type Triangle = parry::shape::Triangle;
36pub type Ball = parry::shape::Ball;
38pub type Capsule = parry::shape::Capsule;
40pub type HeightField = parry::shape::HeightField;
42#[cfg(feature = "dim3")]
44pub type Cylinder = parry::shape::Cylinder;
45#[cfg(feature = "dim3")]
47pub type Cone = parry::shape::Cone;
48pub type Aabb = parry::bounding_volume::Aabb;
50pub type Ray = parry::query::Ray;
52pub type RayIntersection = parry::query::RayIntersection;
54pub type PointProjection = parry::query::PointProjection;
56pub type ShapeCastHit = parry::query::ShapeCastHit;
58pub type DefaultBroadPhase = BroadPhaseBvh;
60
61bitflags::bitflags! {
62 #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
64 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
65 pub struct CollisionEventFlags: u32 {
66 const SENSOR = 0b0001;
69 const REMOVED = 0b0010;
72 }
73}
74
75#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
76#[derive(Copy, Clone, Hash, Debug)]
77pub enum CollisionEvent {
107 Started(ColliderHandle, ColliderHandle, CollisionEventFlags),
109 Stopped(ColliderHandle, ColliderHandle, CollisionEventFlags),
111}
112
113impl CollisionEvent {
114 pub fn started(self) -> bool {
116 matches!(self, CollisionEvent::Started(..))
117 }
118
119 pub fn stopped(self) -> bool {
121 matches!(self, CollisionEvent::Stopped(..))
122 }
123
124 pub fn collider1(self) -> ColliderHandle {
126 match self {
127 Self::Started(h, _, _) | Self::Stopped(h, _, _) => h,
128 }
129 }
130
131 pub fn collider2(self) -> ColliderHandle {
133 match self {
134 Self::Started(_, h, _) | Self::Stopped(_, h, _) => h,
135 }
136 }
137
138 pub fn sensor(self) -> bool {
140 match self {
141 Self::Started(_, _, f) | Self::Stopped(_, _, f) => {
142 f.contains(CollisionEventFlags::SENSOR)
143 }
144 }
145 }
146
147 pub fn removed(self) -> bool {
149 match self {
150 Self::Started(_, _, f) | Self::Stopped(_, _, f) => {
151 f.contains(CollisionEventFlags::REMOVED)
152 }
153 }
154 }
155}
156
157#[derive(Copy, Clone, PartialEq, Debug, Default)]
158pub struct ContactForceEvent {
161 pub collider1: ColliderHandle,
163 pub collider2: ColliderHandle,
165 pub total_force: Vector<Real>,
167 pub total_force_magnitude: Real,
173 pub max_force_direction: Vector<Real>,
175 pub max_force_magnitude: Real,
177}
178
179impl ContactForceEvent {
180 pub fn from_contact_pair(dt: Real, pair: &ContactPair, total_force_magnitude: Real) -> Self {
182 let mut result = ContactForceEvent {
183 collider1: pair.collider1,
184 collider2: pair.collider2,
185 total_force_magnitude,
186 ..ContactForceEvent::default()
187 };
188
189 for m in &pair.manifolds {
190 let mut total_manifold_impulse = 0.0;
191 for pt in m.contacts() {
192 total_manifold_impulse += pt.data.impulse;
193
194 if pt.data.impulse > result.max_force_magnitude {
195 result.max_force_magnitude = pt.data.impulse;
196 result.max_force_direction = m.data.normal;
197 }
198 }
199
200 result.total_force += m.data.normal * total_manifold_impulse;
201 }
202
203 let inv_dt = crate::utils::inv(dt);
204 result.total_force *= inv_dt;
209 result.max_force_magnitude *= inv_dt;
210 result
211 }
212}
213
214pub(crate) use self::narrow_phase::ContactManifoldIndex;
215pub use parry::shape::*;
216
217#[cfg(feature = "serde-serialize")]
218pub(crate) fn default_persistent_query_dispatcher()
219-> std::sync::Arc<dyn parry::query::PersistentQueryDispatcher<ContactManifoldData, ContactData>> {
220 std::sync::Arc::new(parry::query::DefaultQueryDispatcher)
221}
222
223mod collider_components;
224mod contact_pair;
225mod interaction_graph;
226mod interaction_groups;
227mod narrow_phase;
228
229mod broad_phase_bvh;
230mod broad_phase_pair_event;
231mod collider;
232mod collider_set;
233mod mesh_converter;