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