bevy_rapier3d/plugin/
narrow_phase.rs1use crate::math::{Real, Vect};
2use crate::plugin::context::{RapierContextColliders, RapierContextSimulation, RapierRigidBodySet};
3use bevy::prelude::*;
4use rapier::geometry::{Contact, ContactManifold, ContactPair, SolverContact, SolverFlags};
5
6impl RapierContextSimulation {
7 pub fn contact_pairs_with<'a, 'b: 'a>(
13 &'a self,
14 context_colliders: &'b RapierContextColliders,
15 rigidbody_set: &'b RapierRigidBodySet,
16 collider: Entity,
17 ) -> impl Iterator<Item = ContactPairView<'a>> {
18 context_colliders
19 .entity2collider
20 .get(&collider)
21 .into_iter()
22 .flat_map(|h| {
23 self.narrow_phase
24 .contact_pairs_with(*h)
25 .map(|raw| ContactPairView {
26 context_colliders,
27 rigidbody_set,
28 raw,
29 })
30 })
31 }
32
33 pub fn intersection_pairs_with<'a, 'b: 'a>(
40 &'a self,
41 rapier_colliders: &'b RapierContextColliders,
42 collider: Entity,
43 ) -> impl Iterator<Item = (Entity, Entity, bool)> + 'a {
44 rapier_colliders
45 .entity2collider
46 .get(&collider)
47 .into_iter()
48 .flat_map(|h| {
49 self.narrow_phase
50 .intersection_pairs_with(*h)
51 .filter_map(|(h1, h2, inter)| {
52 let e1 = rapier_colliders.collider_entity(h1);
53 let e2 = rapier_colliders.collider_entity(h2);
54 match (e1, e2) {
55 (Some(e1), Some(e2)) => Some((e1, e2, inter)),
56 _ => None,
57 }
58 })
59 })
60 }
61
62 pub fn contact_pair<'a, 'b: 'a>(
68 &'a self,
69 context_colliders: &'b RapierContextColliders,
70 rigidbody_set: &'b RapierRigidBodySet,
71 collider1: Entity,
72 collider2: Entity,
73 ) -> Option<ContactPairView<'a>> {
74 let h1 = context_colliders.entity2collider.get(&collider1)?;
75 let h2 = context_colliders.entity2collider.get(&collider2)?;
76 self.narrow_phase
77 .contact_pair(*h1, *h2)
78 .map(|raw| ContactPairView {
79 context_colliders,
80 rigidbody_set,
81 raw,
82 })
83 }
84
85 pub fn intersection_pair(
90 &self,
91 rapier_colliders: &RapierContextColliders,
92 collider1: Entity,
93 collider2: Entity,
94 ) -> Option<bool> {
95 let h1 = rapier_colliders.entity2collider.get(&collider1)?;
96 let h2 = rapier_colliders.entity2collider.get(&collider2)?;
97 self.narrow_phase.intersection_pair(*h1, *h2)
98 }
99
100 pub fn contact_pairs<'a, 'b: 'a>(
102 &'a self,
103 context_colliders: &'b RapierContextColliders,
104 rigidbody_set: &'b RapierRigidBodySet,
105 ) -> impl Iterator<Item = ContactPairView<'a>> {
106 self.narrow_phase
107 .contact_pairs()
108 .map(|raw| ContactPairView {
109 context_colliders,
110 rigidbody_set,
111 raw,
112 })
113 }
114
115 pub fn intersection_pairs<'a, 'b: 'a>(
117 &'a self,
118 rapier_colliders: &'b RapierContextColliders,
119 ) -> impl Iterator<Item = (Entity, Entity, bool)> + 'a {
120 self.narrow_phase
121 .intersection_pairs()
122 .filter_map(|(h1, h2, inter)| {
123 let e1 = rapier_colliders.collider_entity(h1);
124 let e2 = rapier_colliders.collider_entity(h2);
125 match (e1, e2) {
126 (Some(e1), Some(e2)) => Some((e1, e2, inter)),
127 _ => None,
128 }
129 })
130 }
131}
132
133pub struct ContactManifoldView<'a> {
135 rigidbody_set: &'a RapierRigidBodySet,
136 pub raw: &'a ContactManifold,
138}
139
140impl ContactManifoldView<'_> {
141 pub fn num_points(&self) -> usize {
143 self.raw.points.len()
144 }
145
146 pub fn point(&self, i: usize) -> Option<ContactView<'_>> {
148 self.raw.points.get(i).map(|raw| ContactView { raw })
149 }
150
151 pub fn points(&self) -> impl ExactSizeIterator<Item = ContactView<'_>> {
153 self.raw.points.iter().map(|raw| ContactView { raw })
154 }
155
156 pub fn local_n1(&self) -> Vect {
158 self.raw.local_n1.into()
159 }
160
161 pub fn local_n2(&self) -> Vect {
163 self.raw.local_n2.into()
164 }
165
166 pub fn subshape1(&self) -> u32 {
170 self.raw.subshape1
171 }
172
173 pub fn subshape2(&self) -> u32 {
177 self.raw.subshape2
178 }
179
180 pub fn rigid_body1(&self) -> Option<Entity> {
182 self.raw
183 .data
184 .rigid_body1
185 .and_then(|h| self.rigidbody_set.rigid_body_entity(h))
186 }
187
188 pub fn rigid_body2(&self) -> Option<Entity> {
190 self.raw
191 .data
192 .rigid_body2
193 .and_then(|h| self.rigidbody_set.rigid_body_entity(h))
194 }
195
196 pub fn solver_flags(&self) -> SolverFlags {
198 self.raw.data.solver_flags
199 }
200
201 pub fn normal(&self) -> Vect {
203 self.raw.data.normal.into()
204 }
205
206 pub fn num_solver_contacts(&self) -> usize {
208 self.raw.data.solver_contacts.len()
209 }
210
211 pub fn solver_contact(&self, i: usize) -> Option<SolverContactView<'_>> {
213 self.raw
214 .data
215 .solver_contacts
216 .get(i)
217 .map(|raw| SolverContactView { raw })
218 }
219
220 pub fn solver_contacts(&self) -> impl ExactSizeIterator<Item = SolverContactView<'_>> {
222 self.raw
223 .data
224 .solver_contacts
225 .iter()
226 .map(|raw| SolverContactView { raw })
227 }
228
229 pub fn relative_dominance(&self) -> i16 {
231 self.raw.data.relative_dominance
232 }
233
234 pub fn user_data(&self) -> u32 {
236 self.raw.data.user_data
237 }
238}
239
240impl ContactManifoldView<'_> {
241 pub fn find_deepest_contact(&self) -> Option<ContactView<'_>> {
243 self.raw
244 .find_deepest_contact()
245 .map(|raw| ContactView { raw })
246 }
247}
248
249pub struct ContactView<'a> {
251 pub raw: &'a Contact,
253}
254
255impl ContactView<'_> {
256 pub fn local_p1(&self) -> Vect {
258 self.raw.local_p1.into()
259 }
260
261 pub fn local_p2(&self) -> Vect {
263 self.raw.local_p2.into()
264 }
265
266 pub fn dist(&self) -> Real {
268 self.raw.dist
269 }
270
271 pub fn fid1(&self) -> u32 {
273 self.raw.fid1.0
274 }
275
276 pub fn fid2(&self) -> u32 {
278 self.raw.fid2.0
279 }
280
281 pub fn impulse(&self) -> Real {
285 self.raw.data.impulse
286 }
287
288 #[cfg(feature = "dim2")]
291 pub fn tangent_impulse(&self) -> Real {
292 self.raw.data.tangent_impulse.x
293 }
294
295 #[cfg(feature = "dim3")]
298 pub fn tangent_impulse(&self) -> [Real; 2] {
299 self.raw.data.tangent_impulse.into()
300 }
301}
302
303pub struct SolverContactView<'a> {
305 pub raw: &'a SolverContact,
307}
308
309impl SolverContactView<'_> {
310 pub fn point(&self) -> Vect {
312 self.raw.point.into()
313 }
314 pub fn dist(&self) -> Real {
317 self.raw.dist
318 }
319 pub fn friction(&self) -> Real {
321 self.raw.friction
322 }
323 pub fn restitution(&self) -> Real {
325 self.raw.restitution
326 }
327 pub fn tangent_velocity(&self) -> Vect {
332 self.raw.tangent_velocity.into()
333 }
334 pub fn is_new(&self) -> bool {
336 self.raw.is_new == 1.0
337 }
338}
339
340pub struct ContactPairView<'a> {
342 context_colliders: &'a RapierContextColliders,
343 rigidbody_set: &'a RapierRigidBodySet,
344 pub raw: &'a ContactPair,
346}
347
348impl ContactPairView<'_> {
349 pub fn collider1(&self) -> Option<Entity> {
351 self.context_colliders.collider_entity(self.raw.collider1)
352 }
353
354 pub fn collider2(&self) -> Option<Entity> {
356 self.context_colliders.collider_entity(self.raw.collider2)
357 }
358
359 pub fn manifolds_len(&self) -> usize {
361 self.raw.manifolds.len()
362 }
363
364 pub fn manifold(&self, i: usize) -> Option<ContactManifoldView<'_>> {
366 self.raw.manifolds.get(i).map(|raw| ContactManifoldView {
367 rigidbody_set: self.rigidbody_set,
368 raw,
369 })
370 }
371
372 pub fn manifolds(&self) -> impl ExactSizeIterator<Item = ContactManifoldView<'_>> {
374 self.raw.manifolds.iter().map(|raw| ContactManifoldView {
375 rigidbody_set: self.rigidbody_set,
376 raw,
377 })
378 }
379
380 pub fn has_any_active_contact(&self) -> bool {
382 self.raw.has_any_active_contact
383 }
384
385 pub fn find_deepest_contact(&self) -> Option<(ContactManifoldView<'_>, ContactView<'_>)> {
393 self.raw.find_deepest_contact().map(|(manifold, contact)| {
394 (
395 ContactManifoldView {
396 rigidbody_set: self.rigidbody_set,
397 raw: manifold,
398 },
399 ContactView { raw: contact },
400 )
401 })
402 }
403}