parry3d/query/point/
point_heightfield.rs

1use crate::bounding_volume::Aabb;
2use crate::math::{Point, Real, Vector};
3use crate::query::{PointProjection, PointQuery, PointQueryWithLocation};
4use crate::shape::{FeatureId, HeightField, TrianglePointLocation};
5#[cfg(not(feature = "std"))]
6use na::ComplexField; // For sqrt.
7
8impl PointQuery for HeightField {
9    fn project_local_point_with_max_dist(
10        &self,
11        pt: &Point<Real>,
12        solid: bool,
13        max_dist: Real,
14    ) -> Option<PointProjection> {
15        let aabb = Aabb::new(pt - Vector::repeat(max_dist), pt + Vector::repeat(max_dist));
16        let mut sq_smallest_dist = Real::MAX;
17        let mut best_proj = None;
18
19        self.map_elements_in_local_aabb(&aabb, &mut |_, triangle| {
20            let proj = triangle.project_local_point(pt, solid);
21            let sq_dist = na::distance_squared(pt, &proj.point);
22
23            if sq_dist < sq_smallest_dist {
24                sq_smallest_dist = sq_dist;
25
26                if sq_dist.sqrt() <= max_dist {
27                    best_proj = Some(proj);
28                }
29            }
30        });
31
32        best_proj
33    }
34
35    #[inline]
36    fn project_local_point(&self, point: &Point<Real>, _: bool) -> PointProjection {
37        let mut smallest_dist = Real::MAX;
38        let mut best_proj = PointProjection::new(false, *point);
39
40        #[cfg(feature = "dim2")]
41        let iter = self.segments();
42        #[cfg(feature = "dim3")]
43        let iter = self.triangles();
44        for elt in iter {
45            let proj = elt.project_local_point(point, false);
46            let dist = na::distance_squared(point, &proj.point);
47
48            if dist < smallest_dist {
49                smallest_dist = dist;
50                best_proj = proj;
51            }
52        }
53
54        best_proj
55    }
56
57    #[inline]
58    fn project_local_point_and_get_feature(
59        &self,
60        point: &Point<Real>,
61    ) -> (PointProjection, FeatureId) {
62        // TODO: compute the feature properly.
63        (self.project_local_point(point, false), FeatureId::Unknown)
64    }
65
66    // TODO: implement distance_to_point too?
67
68    #[inline]
69    fn contains_local_point(&self, _point: &Point<Real>) -> bool {
70        false
71    }
72}
73
74impl PointQueryWithLocation for HeightField {
75    type Location = (usize, TrianglePointLocation);
76
77    #[inline]
78    fn project_local_point_and_get_location(
79        &self,
80        _point: &Point<Real>,
81        _: bool,
82    ) -> (PointProjection, Self::Location) {
83        unimplemented!()
84    }
85}