parry3d_f64/partitioning/qbvh/utils.rs
1use crate::bounding_volume::Aabb;
2use crate::math::{Point, Real};
3
4pub fn split_indices_wrt_dim<'a>(
5 indices: &'a mut [usize],
6 aabbs: &[Aabb],
7 split_point: &Point<Real>,
8 dim: usize,
9 enable_fallback_split: bool,
10) -> (&'a mut [usize], &'a mut [usize]) {
11 let mut icurr = 0;
12 let mut ilast = indices.len();
13
14 // The loop condition we can just do 0..indices.len()
15 // instead of the test icurr < ilast because we know
16 // we will iterate exactly once per index.
17 for _ in 0..indices.len() {
18 let i = indices[icurr];
19 let center = aabbs[i].center();
20
21 if center[dim] > split_point[dim] {
22 ilast -= 1;
23 indices.swap(icurr, ilast);
24 } else {
25 icurr += 1;
26 }
27 }
28
29 if enable_fallback_split && (icurr == 0 || icurr == indices.len()) {
30 // We don't want to return one empty set. But
31 // this can happen if all the coordinates along the
32 // given dimension are equal.
33 // In this is the case, we just split in the middle.
34 let half = indices.len() / 2;
35 indices.split_at_mut(half)
36 } else {
37 indices.split_at_mut(icurr)
38 }
39}