parry3d_f64/query/visitors/
composite_point_containment_test.rs1use crate::bounding_volume::SimdAabb;
2use crate::math::{Point, Real, SimdReal, SIMD_WIDTH};
3use crate::partitioning::{SimdVisitStatus, SimdVisitor};
4use crate::query::point::point_query::PointQuery;
5use crate::shape::TypedSimdCompositeShape;
6use crate::utils::IsometryOpt;
7use simba::simd::{SimdBool as _, SimdValue};
8
9pub struct CompositePointContainmentTest<'a, S: 'a> {
11 pub shape: &'a S,
13 pub point: &'a Point<Real>,
15 pub found: bool,
17}
18
19impl<'a, S> CompositePointContainmentTest<'a, S> {
20 pub fn new(shape: &'a S, point: &'a Point<Real>) -> Self {
23 Self {
24 shape,
25 point,
26 found: false,
27 }
28 }
29}
30
31impl<S: TypedSimdCompositeShape> SimdVisitor<S::PartId, SimdAabb>
32 for CompositePointContainmentTest<'_, S>
33{
34 #[inline]
35 fn visit(
36 &mut self,
37 bv: &SimdAabb,
38 b: Option<[Option<&S::PartId>; SIMD_WIDTH]>,
39 ) -> SimdVisitStatus {
40 let simd_point: Point<SimdReal> = Point::splat(*self.point);
41 let mask = bv.contains_local_point(&simd_point);
42
43 if let Some(data) = b {
44 let bitmask = mask.bitmask();
45
46 for (ii, data) in data.into_iter().enumerate() {
47 if (bitmask & (1 << ii)) != 0 {
48 let Some(data) = data else { continue };
49 self.shape.map_typed_part_at(*data, |part_pos, obj, _| {
50 if obj.contains_local_point(&part_pos.inverse_transform_point(self.point)) {
51 self.found = true;
52 }
53 });
54
55 if self.found {
56 return SimdVisitStatus::ExitEarly;
57 }
58 }
59 }
60 }
61
62 SimdVisitStatus::MaybeContinue(mask)
63 }
64}