parry2d/query/point/
point_voxels.rs

1use crate::math::{Point, Real};
2use crate::query::{PointProjection, PointQuery};
3use crate::shape::{Cuboid, FeatureId, Voxels, VoxelsChunkRef};
4
5impl PointQuery for Voxels {
6    #[inline]
7    fn project_local_point(&self, pt: &Point<Real>, solid: bool) -> PointProjection {
8        self.chunk_bvh()
9            .project_point(pt, Real::MAX, |chunk_id, _| {
10                let chunk = self.chunk_ref(chunk_id);
11                Some(chunk.project_local_point_and_get_vox_id(pt, solid).0)
12            })
13            .unwrap()
14            .1
15             .1
16    }
17
18    #[inline]
19    fn project_local_point_and_get_feature(
20        &self,
21        pt: &Point<Real>,
22    ) -> (PointProjection, FeatureId) {
23        self.chunk_bvh()
24            .project_point_and_get_feature(pt, Real::MAX, |chunk_id, _| {
25                let chunk = self.chunk_ref(chunk_id);
26                let (proj, vox) = chunk.project_local_point_and_get_vox_id(pt, false);
27                // TODO: we need a way to return both the voxel id, and the feature on the voxel.
28                Some((proj, FeatureId::Face(vox)))
29            })
30            .unwrap()
31            .1
32             .1
33    }
34}
35
36impl<'a> VoxelsChunkRef<'a> {
37    #[inline]
38    fn project_local_point_and_get_vox_id(
39        &self,
40        pt: &Point<Real>,
41        solid: bool,
42    ) -> (PointProjection, u32) {
43        // TODO: optimize this naive implementation that just iterates on all the voxels
44        //       from this chunk.
45        let base_cuboid = Cuboid::new(self.parent.voxel_size() / 2.0);
46        let mut smallest_dist = Real::MAX;
47        let mut result = PointProjection::new(false, *pt);
48        let mut result_vox_id = 0;
49
50        for vox in self.voxels() {
51            let mut candidate = base_cuboid.project_local_point(&(pt - vox.center.coords), solid);
52            candidate.point += vox.center.coords;
53
54            let candidate_dist = (candidate.point - pt).norm();
55            if candidate_dist < smallest_dist {
56                result = candidate;
57                result_vox_id = vox.linear_id.flat_id();
58                smallest_dist = candidate_dist;
59            }
60        }
61
62        (result, result_vox_id as u32)
63    }
64}