parry2d/query/point/
point_voxels.rs1use 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 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 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}