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}