Skip to main content

parry3d/query/intersection_test/
intersection_test_voxels_shape.rs

1use crate::math::Pose;
2use crate::query::{PersistentQueryDispatcher, ShapeIntersection};
3use crate::shape::{Cuboid, Shape, VoxelType, Voxels};
4
5/// Checks for any intersection between voxels and an arbitrary shape, both represented as a `Shape` trait-object.
6pub fn intersection_test_voxels_shape_shapes(
7    dispatcher: &dyn PersistentQueryDispatcher,
8    pos12: &Pose,
9    shape1: &dyn Shape,
10    shape2: &dyn Shape,
11) -> ShapeIntersection {
12    if let Some(voxels1) = shape1.as_voxels() {
13        intersection_test_voxels_shape(dispatcher, pos12, voxels1, shape2)
14    } else if let Some(voxels2) = shape2.as_voxels() {
15        intersection_test_voxels_shape(dispatcher, &pos12.inverse(), voxels2, shape1).swapped()
16    } else {
17        ShapeIntersection::new(false)
18    }
19}
20
21/// Checks for any intersection between voxels and an arbitrary shape.
22pub fn intersection_test_voxels_shape(
23    dispatcher: &dyn PersistentQueryDispatcher,
24    pos12: &Pose,
25    voxels1: &Voxels,
26    shape2: &dyn Shape,
27) -> ShapeIntersection {
28    let radius1 = voxels1.voxel_size() / 2.0;
29    let aabb1 = voxels1.local_aabb();
30    let aabb2_1 = shape2.compute_aabb(pos12);
31
32    if let Some(intersection_aabb1) = aabb1.intersection(&aabb2_1) {
33        for vox1 in voxels1.voxels_intersecting_local_aabb(&intersection_aabb1) {
34            let vox_type1 = vox1.state.voxel_type();
35
36            if vox_type1 == VoxelType::Empty {
37                continue;
38            }
39
40            let center1 = vox1.center;
41            let cuboid1 = Cuboid::new(radius1);
42            let cuboid_pose12 = Pose::from_translation(-center1) * pos12;
43
44            if let Ok(result) = dispatcher.intersection_test(&cuboid_pose12, &cuboid1, shape2) {
45                if result.intersecting {
46                    // `shape2` may be a composite; keep the sub-shape it reported.
47                    return ShapeIntersection::new(true)
48                        .with_subshapes(vox1.linear_id.flat_id() as u32, result.subshape2);
49                }
50            }
51        }
52    }
53
54    ShapeIntersection::new(false)
55}
56
57/// Checks for any intersection between voxels and an arbitrary shape.
58pub fn intersection_test_shape_voxels(
59    dispatcher: &dyn PersistentQueryDispatcher,
60    pos12: &Pose,
61    shape1: &dyn Shape,
62    voxels2: &Voxels,
63) -> ShapeIntersection {
64    intersection_test_voxels_shape(dispatcher, &pos12.inverse(), voxels2, shape1).swapped()
65}