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