1use na::RealField;
2use std::vec::IntoIter;
3
4use crate::bounding_volume::AABB;
5use crate::math::Point;
6use crate::pipeline::broad_phase::BroadPhase;
7use crate::pipeline::object::{CollisionGroups, CollisionObjectRef, CollisionObjectSet};
8use crate::query::{PointQuery, Ray, RayCast, RayIntersection};
9
10pub fn interferences_with_ray<'a, 'b, N, Objects>(
14 objects: &'a Objects,
15 broad_phase: &'a (impl BroadPhase<N, AABB<N>, Objects::CollisionObjectHandle> + ?Sized),
16 ray: &'b Ray<N>,
17 max_toi: N,
18 groups: &'b CollisionGroups,
19) -> InterferencesWithRay<'a, 'b, N, Objects>
20where
21 N: RealField + Copy,
22 Objects: CollisionObjectSet<N>,
23{
24 let mut handles = Vec::new();
25 broad_phase.interferences_with_ray(ray, max_toi, &mut handles);
26
27 InterferencesWithRay {
28 ray,
29 max_toi,
30 groups,
31 objects,
32 handles: handles.into_iter(),
33 }
34}
35
36pub struct InterferencesWithRay<'a, 'b, N: RealField + Copy, Objects: CollisionObjectSet<N>> {
38 ray: &'b Ray<N>,
39 max_toi: N,
40 objects: &'a Objects,
41 groups: &'b CollisionGroups,
42 handles: IntoIter<&'a Objects::CollisionObjectHandle>,
43}
44
45impl<'a, 'b, N: RealField + Copy, Objects> Iterator for InterferencesWithRay<'a, 'b, N, Objects>
46where
47 N: RealField + Copy,
48 Objects: CollisionObjectSet<N>,
49{
50 type Item = (
51 Objects::CollisionObjectHandle,
52 &'a Objects::CollisionObject,
53 RayIntersection<N>,
54 );
55
56 #[inline]
57 fn next(&mut self) -> Option<Self::Item> {
58 while let Some(handle) = self.handles.next() {
59 if let Some(co) = self.objects.collision_object(*handle) {
60 if co.collision_groups().can_interact_with_groups(self.groups) {
61 let inter = co.shape().toi_and_normal_with_ray(
62 &co.position(),
63 self.ray,
64 self.max_toi,
65 true,
66 );
67
68 if let Some(inter) = inter {
69 return Some((*handle, co, inter));
70 }
71 }
72 }
73 }
74
75 None
76 }
77}
78
79pub fn interferences_with_point<'a, 'b, N, Objects>(
83 objects: &'a Objects,
84 broad_phase: &'a (impl BroadPhase<N, AABB<N>, Objects::CollisionObjectHandle> + ?Sized),
85 point: &'b Point<N>,
86 groups: &'b CollisionGroups,
87) -> InterferencesWithPoint<'a, 'b, N, Objects>
88where
89 N: RealField + Copy,
90 Objects: CollisionObjectSet<N>,
91{
92 let mut handles = Vec::new();
93 broad_phase.interferences_with_point(point, &mut handles);
94
95 InterferencesWithPoint {
96 point,
97 groups,
98 objects,
99 handles: handles.into_iter(),
100 }
101}
102
103pub struct InterferencesWithPoint<'a, 'b, N: RealField + Copy, Objects: CollisionObjectSet<N>> {
105 point: &'b Point<N>,
106 objects: &'a Objects,
107 groups: &'b CollisionGroups,
108 handles: IntoIter<&'a Objects::CollisionObjectHandle>,
109}
110
111impl<'a, 'b, N: RealField + Copy, Objects> Iterator for InterferencesWithPoint<'a, 'b, N, Objects>
112where
113 N: RealField + Copy,
114 Objects: CollisionObjectSet<N>,
115{
116 type Item = (Objects::CollisionObjectHandle, &'a Objects::CollisionObject);
117
118 #[inline]
119 fn next(&mut self) -> Option<Self::Item> {
120 while let Some(handle) = self.handles.next() {
121 if let Some(co) = self.objects.collision_object(*handle) {
122 if co.collision_groups().can_interact_with_groups(self.groups)
123 && co.shape().contains_point(&co.position(), self.point)
124 {
125 return Some((*handle, co));
126 }
127 }
128 }
129
130 None
131 }
132}
133
134pub fn interferences_with_aabb<'a, 'b, N, Objects>(
138 objects: &'a Objects,
139 broad_phase: &'a (impl BroadPhase<N, AABB<N>, Objects::CollisionObjectHandle> + ?Sized),
140 aabb: &AABB<N>,
141 groups: &'b CollisionGroups,
142) -> InterferencesWithAABB<'a, 'b, N, Objects>
143where
144 N: RealField + Copy,
145 Objects: CollisionObjectSet<N>,
146{
147 let mut handles = Vec::new();
148 broad_phase.interferences_with_bounding_volume(aabb, &mut handles);
149
150 InterferencesWithAABB {
151 groups,
152 objects,
153 handles: handles.into_iter(),
154 }
155}
156
157pub struct InterferencesWithAABB<'a, 'b, N: RealField + Copy, Objects: CollisionObjectSet<N>> {
159 objects: &'a Objects,
160 groups: &'b CollisionGroups,
161 handles: IntoIter<&'a Objects::CollisionObjectHandle>,
162}
163
164impl<'a, 'b, N: RealField + Copy, Objects: CollisionObjectSet<N>> Iterator
165 for InterferencesWithAABB<'a, 'b, N, Objects>
166{
167 type Item = (Objects::CollisionObjectHandle, &'a Objects::CollisionObject);
168
169 #[inline]
170 fn next(&mut self) -> Option<Self::Item> {
171 while let Some(handle) = self.handles.next() {
172 if let Some(co) = self.objects.collision_object(*handle) {
173 if co.collision_groups().can_interact_with_groups(self.groups) {
174 return Some((*handle, co));
175 }
176 }
177 }
178
179 None
180 }
181}
182
183#[derive(Debug)]
188pub struct FirstInterferenceWithRay<'a, N: RealField + Copy, Objects: CollisionObjectSet<N>> {
189 pub handle: Objects::CollisionObjectHandle,
191 pub co: &'a Objects::CollisionObject,
193 pub inter: RayIntersection<N>,
195}
196
197pub fn first_interference_with_ray<'a, 'b, N: RealField + Copy, Objects: CollisionObjectSet<N>>(
201 objects: &'a Objects,
202 broad_phase: &'a (impl BroadPhase<N, AABB<N>, Objects::CollisionObjectHandle> + ?Sized),
203 ray: &'b Ray<N>,
204 max_toi: N,
205 groups: &'b CollisionGroups,
206) -> Option<FirstInterferenceWithRay<'a, N, Objects>> {
207 let narrow_phase = move |handle: Objects::CollisionObjectHandle, ray: &Ray<N>, max_toi: N| {
209 let co = objects.collision_object(handle)?;
210 if co.collision_groups().can_interact_with_groups(groups) {
211 let inter = co
212 .shape()
213 .toi_and_normal_with_ray(&co.position(), ray, max_toi, true);
214
215 inter.map(|inter| (handle, inter))
216 } else {
217 None
218 }
219 };
220
221 let (handle, inter) = broad_phase.first_interference_with_ray(ray, max_toi, &narrow_phase)?;
222 let co = objects.collision_object(handle)?;
223 Some(FirstInterferenceWithRay { handle, co, inter })
224}