ncollide3d/query/point/
point_query.rs

1use crate::math::{Isometry, Point};
2use crate::shape::FeatureId;
3use na::{self, RealField};
4
5/// Description of the projection of a point on a shape.
6#[derive(Copy, Clone, Debug)]
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8pub struct PointProjection<N: RealField + Copy> {
9    /// Whether or not the point to project was inside of the shape.
10    pub is_inside: bool,
11    /// The projection result.
12    pub point: Point<N>,
13}
14
15impl<N: RealField + Copy> PointProjection<N> {
16    /// Initializes a new `PointProjection`.
17    pub fn new(is_inside: bool, point: Point<N>) -> PointProjection<N> {
18        PointProjection { is_inside, point }
19    }
20}
21
22/// Trait of objects that can be tested for point inclusion and projection.
23pub trait PointQuery<N: RealField + Copy> {
24    /// Projects a point on `self` transformed by `m`.
25    fn project_point(&self, m: &Isometry<N>, pt: &Point<N>, solid: bool) -> PointProjection<N>;
26
27    /// Computes the minimal distance between a point and `self` transformed by `m`.
28    #[inline]
29    fn distance_to_point(&self, m: &Isometry<N>, pt: &Point<N>, solid: bool) -> N {
30        let proj = self.project_point(m, pt, solid);
31        let dist = na::distance(pt, &proj.point);
32
33        if solid || !proj.is_inside {
34            dist
35        } else {
36            -dist
37        }
38    }
39
40    /// Projects a point on the boundary of `self` transformed by `m` and retuns the id of the
41    /// feature the point was projected on.
42    fn project_point_with_feature(
43        &self,
44        m: &Isometry<N>,
45        pt: &Point<N>,
46    ) -> (PointProjection<N>, FeatureId);
47
48    /// Tests if the given point is inside of `self` transformed by `m`.
49    #[inline]
50    fn contains_point(&self, m: &Isometry<N>, pt: &Point<N>) -> bool {
51        self.project_point(m, pt, false).is_inside
52    }
53}
54
55/// Returns shape-specific info in addition to generic projection information
56///
57/// One requirement for the `PointQuery` trait is to be usable as a trait
58/// object. Unfortunately this precludes us from adding an associated type to it
59/// that might allow us to return shape-specific information in addition to the
60/// general information provided in `PointProjection`. This is where
61/// `PointQueryWithLocation` comes in. It forgoes the ability to be used as a trait
62/// object in exchange for being able to provide shape-specific projection
63/// information.
64///
65/// Any shapes that implement `PointQuery` but are able to provide extra
66/// information, can implement `PointQueryWithLocation` in addition and have their
67/// `PointQuery::project_point` implementation just call out to
68/// `PointQueryWithLocation::project_point_with_location`.
69pub trait PointQueryWithLocation<N: RealField + Copy> {
70    /// Additional shape-specific projection information
71    ///
72    /// In addition to the generic projection information returned in
73    /// `PointProjection`, implementations might provide shape-specific
74    /// projection info. The type of this shape-specific information is defined
75    /// by this associated type.
76    type Location;
77
78    /// Projects a point on `self` transformed by `m`.
79    fn project_point_with_location(
80        &self,
81        m: &Isometry<N>,
82        pt: &Point<N>,
83        solid: bool,
84    ) -> (PointProjection<N>, Self::Location);
85}