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;
18pub use parry::utils::Array2;
19
20pub use parry::bounding_volume::BoundingVolume;
21pub use parry::partitioning::{Bvh, BvhBuildStrategy};
22pub use parry::query::{PointQuery, PointQueryWithLocation, RayCast, TrackedContact};
23pub use parry::shape::{SharedShape, VoxelState, VoxelType, Voxels};
24
25use crate::math::{Real, Vector};
26
27pub type Contact = parry::query::TrackedContact<ContactData>;
29pub type ContactManifold = parry::query::ContactManifold<ContactManifoldData, ContactData>;
31pub type Segment = parry::shape::Segment;
33pub type Cuboid = parry::shape::Cuboid;
35pub type Triangle = parry::shape::Triangle;
37pub type Ball = parry::shape::Ball;
39pub type Capsule = parry::shape::Capsule;
41pub type HeightField = parry::shape::HeightField;
43#[cfg(feature = "dim3")]
45pub type Cylinder = parry::shape::Cylinder;
46#[cfg(feature = "dim3")]
48pub type Cone = parry::shape::Cone;
49pub type Aabb = parry::bounding_volume::Aabb;
51pub type Ray = parry::query::Ray;
53pub type RayIntersection = parry::query::RayIntersection;
55pub type PointProjection = parry::query::PointProjection;
57pub type ShapeCastHit = parry::query::ShapeCastHit;
59pub type DefaultBroadPhase = BroadPhaseBvh;
61
62bitflags::bitflags! {
63 #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
65 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
66 pub struct CollisionEventFlags: u32 {
67 const SENSOR = 0b0001;
70 const REMOVED = 0b0010;
73 }
74}
75
76#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
77#[derive(Copy, Clone, Hash, Debug)]
78pub enum CollisionEvent {
108 Started(ColliderHandle, ColliderHandle, CollisionEventFlags),
110 Stopped(ColliderHandle, ColliderHandle, CollisionEventFlags),
112}
113
114impl CollisionEvent {
115 pub fn started(self) -> bool {
117 matches!(self, CollisionEvent::Started(..))
118 }
119
120 pub fn stopped(self) -> bool {
122 matches!(self, CollisionEvent::Stopped(..))
123 }
124
125 pub fn collider1(self) -> ColliderHandle {
127 match self {
128 Self::Started(h, _, _) | Self::Stopped(h, _, _) => h,
129 }
130 }
131
132 pub fn collider2(self) -> ColliderHandle {
134 match self {
135 Self::Started(_, h, _) | Self::Stopped(_, h, _) => h,
136 }
137 }
138
139 pub fn sensor(self) -> bool {
141 match self {
142 Self::Started(_, _, f) | Self::Stopped(_, _, f) => {
143 f.contains(CollisionEventFlags::SENSOR)
144 }
145 }
146 }
147
148 pub fn removed(self) -> bool {
150 match self {
151 Self::Started(_, _, f) | Self::Stopped(_, _, f) => {
152 f.contains(CollisionEventFlags::REMOVED)
153 }
154 }
155 }
156}
157
158#[derive(Copy, Clone, PartialEq, Debug, Default)]
159pub struct ContactForceEvent {
162 pub collider1: ColliderHandle,
164 pub collider2: ColliderHandle,
166 pub total_force: Vector,
168 pub total_force_magnitude: Real,
174 pub max_force_direction: Vector,
176 pub max_force_magnitude: Real,
178}
179
180impl ContactForceEvent {
181 pub fn from_contact_pair(dt: Real, pair: &ContactPair, total_force_magnitude: Real) -> Self {
183 let mut result = ContactForceEvent {
184 collider1: pair.collider1,
185 collider2: pair.collider2,
186 total_force_magnitude,
187 ..ContactForceEvent::default()
188 };
189
190 for m in &pair.manifolds {
191 let mut total_manifold_impulse = 0.0;
192 for pt in m.contacts() {
193 total_manifold_impulse += pt.data.impulse;
194
195 if pt.data.impulse > result.max_force_magnitude {
196 result.max_force_magnitude = pt.data.impulse;
197 result.max_force_direction = m.data.normal;
198 }
199 }
200
201 result.total_force += m.data.normal * total_manifold_impulse;
202 }
203
204 let inv_dt = crate::utils::inv(dt);
205 result.total_force *= inv_dt;
210 result.max_force_magnitude *= inv_dt;
211 result
212 }
213}
214
215pub(crate) use self::narrow_phase::ContactManifoldIndex;
216pub use parry::shape::*;
217
218#[cfg(feature = "serde-serialize")]
219pub(crate) fn default_persistent_query_dispatcher()
220-> std::sync::Arc<dyn parry::query::PersistentQueryDispatcher<ContactManifoldData, ContactData>> {
221 std::sync::Arc::new(parry::query::DefaultQueryDispatcher)
222}
223
224mod collider_components;
225mod contact_pair;
226mod interaction_graph;
227mod interaction_groups;
228mod narrow_phase;
229
230mod broad_phase_bvh;
231mod broad_phase_pair_event;
232mod collider;
233mod collider_set;
234mod mesh_converter;
235
236#[cfg(feature = "dim3")]
237mod manifold_reduction;