parry3d_f64/query/visitors/
bounding_volume_intersections_visitor.rs1use crate::bounding_volume::{Aabb, SimdAabb};
2use crate::math::SIMD_WIDTH;
3use crate::partitioning::{SimdVisitStatus, SimdVisitor};
4use core::marker::PhantomData;
5use simba::simd::SimdBool as _;
6
7pub struct BoundingVolumeIntersectionsVisitor<T, F> {
9 bv: SimdAabb,
10 callback: F,
11 _phantom: PhantomData<T>,
12}
13
14impl<T, F> BoundingVolumeIntersectionsVisitor<T, F>
15where
16 F: FnMut(&T) -> bool,
17{
18 #[inline]
20 pub fn new(bv: &Aabb, callback: F) -> BoundingVolumeIntersectionsVisitor<T, F> {
21 BoundingVolumeIntersectionsVisitor {
22 bv: SimdAabb::splat(*bv),
23 callback,
24 _phantom: PhantomData,
25 }
26 }
27}
28
29impl<T, F> SimdVisitor<T, SimdAabb> for BoundingVolumeIntersectionsVisitor<T, F>
30where
31 F: FnMut(&T) -> bool,
32{
33 #[inline]
34 fn visit(&mut self, bv: &SimdAabb, b: Option<[Option<&T>; SIMD_WIDTH]>) -> SimdVisitStatus {
35 let mask = bv.intersects(&self.bv);
36
37 if let Some(data) = b {
38 let bitmask = mask.bitmask();
39
40 for (ii, data) in data.iter().enumerate() {
41 if (bitmask & (1 << ii)) != 0 {
42 let Some(data) = data else { continue };
43 if !(self.callback)(data) {
44 return SimdVisitStatus::ExitEarly;
45 }
46 }
47 }
48 }
49
50 SimdVisitStatus::MaybeContinue(mask)
51 }
52}