box3d_rust/compound/
query.rs1use super::types::{get_compound_child, ChildGeometry, CompoundData};
7use crate::dynamic_tree::DEFAULT_MASK_BITS;
8use crate::geometry::{collide_mover_and_capsule, collide_mover_and_sphere, Capsule, PlaneResult};
9use crate::hull::collide_mover_and_hull;
10use crate::math_functions::{
11 add, inv_transform_point, max, min, rotate_vector, sub, transform_point, Aabb, Vec3,
12};
13use crate::mesh::collide_mover_and_mesh;
14
15pub fn query_compound(
19 compound: &CompoundData,
20 aabb: Aabb,
21 mut fcn: impl FnMut(&CompoundData, i32) -> bool,
22) {
23 compound
24 .tree
25 .query(aabb, DEFAULT_MASK_BITS, false, |_proxy_id, user_data| {
26 fcn(compound, user_data as i32)
27 });
28}
29
30pub fn collide_mover_and_compound(
32 planes: &mut [PlaneResult],
33 shape: &CompoundData,
34 mover: &Capsule,
35) -> i32 {
36 let capacity = planes.len() as i32;
37 if capacity == 0 {
38 return 0;
39 }
40
41 let mut plane_count = 0i32;
42
43 let mut aabb = Aabb {
44 lower_bound: min(mover.center1, mover.center2),
45 upper_bound: max(mover.center1, mover.center2),
46 };
47 let r = Vec3 {
48 x: mover.radius,
49 y: mover.radius,
50 z: mover.radius,
51 };
52 aabb.lower_bound = sub(aabb.lower_bound, r);
53 aabb.upper_bound = add(aabb.upper_bound, r);
54
55 shape
56 .tree
57 .query(aabb, !0u64, false, |_proxy_id, user_data| {
58 let child_index = user_data as i32;
59 let child = get_compound_child(shape, child_index);
60
61 let local_mover = Capsule {
62 center1: inv_transform_point(child.transform, mover.center1),
63 center2: inv_transform_point(child.transform, mover.center2),
64 radius: mover.radius,
65 };
66
67 let remaining = capacity - plane_count;
68 debug_assert!(remaining > 0);
69 let slot = &mut planes[plane_count as usize..];
70
71 let added = match child.geometry {
72 ChildGeometry::Capsule(ref capsule) => {
73 collide_mover_and_capsule(&mut slot[0], capsule, &local_mover)
74 }
75 ChildGeometry::Hull(hull) => {
76 collide_mover_and_hull(&mut slot[0], hull, &local_mover)
77 }
78 ChildGeometry::Mesh(ref mesh) => collide_mover_and_mesh(slot, mesh, &local_mover),
79 ChildGeometry::Sphere(ref sphere) => {
80 collide_mover_and_sphere(&mut slot[0], sphere, &local_mover)
81 }
82 };
83
84 for i in 0..added {
85 let p = &mut planes[(plane_count + i) as usize];
86 p.plane.normal = rotate_vector(child.transform.q, p.plane.normal);
87 p.point = transform_point(child.transform, p.point);
88 }
89
90 plane_count += added;
91 plane_count < capacity
92 });
93
94 plane_count
95}