1pub mod kinematic_body;
5
6pub mod static_body;
8
9pub mod trigger_area;
11
12pub mod contact;
14
15use super::Mask;
16use crate::{
17 object::{kinematic_body::KinematicBody, static_body::StaticBody},
18 world::aabb::Aabb,
19};
20use alloc::sync::Arc;
21use bvh_arena::VolumeHandle;
22use parry::{
23 math::{Isometry, Real, Vector},
24 query::{self, Contact, ShapeCastHit, ShapeCastOptions},
25 shape::Shape,
26};
27
28const MASK_ALL: Mask = Mask::MAX;
30
31pub trait Object {
33 type Payload;
34
35 fn set_handle(&mut self, handle: VolumeHandle);
37
38 fn unset_handle(&mut self);
40
41 fn handle(&self) -> Option<VolumeHandle>;
43
44 fn shape(&self) -> &dyn Shape;
46
47 fn isometry(&self) -> &Isometry<Real>;
49
50 fn aabb(&self) -> Aabb;
52
53 fn payload(&self) -> &Self::Payload;
55
56 fn payload_mut(&mut self) -> &mut Self::Payload;
58
59 #[inline]
61 fn layer(&self) -> Mask {
62 MASK_ALL
63 }
64
65 #[inline]
67 fn mask(&self) -> Mask {
68 MASK_ALL
69 }
70
71 #[inline]
73 fn velocity(&self) -> Vector<Real> {
74 Vector::default()
75 }
76
77 #[inline]
79 fn as_kinematic(&self) -> Option<&KinematicBody<Self::Payload>> {
80 None
81 }
82
83 #[inline]
85 fn as_static(&self) -> Option<&StaticBody<Self::Payload>> {
86 None
87 }
88}
89
90struct CommonData<P> {
92 handle: Option<VolumeHandle>,
94
95 shape: Arc<dyn Shape>,
97
98 isometry: Isometry<Real>,
100
101 payload: P,
103}
104
105impl<P> CommonData<P> {
106 #[inline]
108 pub fn new(shape: Arc<dyn Shape>, isometry: Isometry<Real>, payload: P) -> Self {
109 CommonData {
110 handle: None,
111 shape,
112 isometry,
113 payload,
114 }
115 }
116}
117
118impl<P> Object for CommonData<P> {
119 type Payload = P;
120
121 #[inline]
123 fn set_handle(&mut self, handle: VolumeHandle) {
124 self.handle = Some(handle);
125 }
126
127 #[inline]
129 fn unset_handle(&mut self) {
130 self.handle = None;
131 }
132
133 #[inline]
135 fn handle(&self) -> Option<VolumeHandle> {
136 self.handle
137 }
138
139 #[inline]
141 fn shape(&self) -> &dyn Shape {
142 self.shape.as_ref()
143 }
144
145 #[inline]
147 fn isometry(&self) -> &Isometry<f32> {
148 &self.isometry
149 }
150
151 #[inline]
153 fn aabb(&self) -> Aabb {
154 Aabb::new(self.shape.compute_aabb(&self.isometry), MASK_ALL, MASK_ALL)
155 }
156
157 #[inline]
159 fn payload(&self) -> &Self::Payload {
160 &self.payload
161 }
162
163 #[inline]
165 fn payload_mut(&mut self) -> &mut Self::Payload {
166 &mut self.payload
167 }
168}
169
170#[inline]
172pub fn intersects<A, B>(a: &A, b: &B) -> bool
173where
174 A: Object,
175 B: Object,
176{
177 query::intersection_test(a.isometry(), a.shape(), b.isometry(), b.shape()).unwrap_or(false)
178}
179
180#[inline]
182pub fn contacts<A, B>(a: &A, b: &B, prediction: Real) -> Option<Contact>
183where
184 A: Object,
185 B: Object,
186{
187 query::contact(a.isometry(), a.shape(), b.isometry(), b.shape(), prediction).unwrap_or(None)
188}
189
190#[inline]
192pub fn collides<A, B>(a: &A, b: &B, options: ShapeCastOptions) -> Option<ShapeCastHit>
193where
194 A: Object,
195 B: Object,
196{
197 query::cast_shapes(
198 a.isometry(),
199 &a.velocity(),
200 a.shape(),
201 b.isometry(),
202 &b.velocity(),
203 b.shape(),
204 options,
205 )
206 .unwrap_or(None)
207}