use crate::math::{Isometry, Point};
use crate::shape::FeatureId;
use na::{self, RealField};
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PointProjection<N: RealField + Copy> {
pub is_inside: bool,
pub point: Point<N>,
}
impl<N: RealField + Copy> PointProjection<N> {
pub fn new(is_inside: bool, point: Point<N>) -> PointProjection<N> {
PointProjection { is_inside, point }
}
}
pub trait PointQuery<N: RealField + Copy> {
fn project_point(&self, m: &Isometry<N>, pt: &Point<N>, solid: bool) -> PointProjection<N>;
#[inline]
fn distance_to_point(&self, m: &Isometry<N>, pt: &Point<N>, solid: bool) -> N {
let proj = self.project_point(m, pt, solid);
let dist = na::distance(pt, &proj.point);
if solid || !proj.is_inside {
dist
} else {
-dist
}
}
fn project_point_with_feature(
&self,
m: &Isometry<N>,
pt: &Point<N>,
) -> (PointProjection<N>, FeatureId);
#[inline]
fn contains_point(&self, m: &Isometry<N>, pt: &Point<N>) -> bool {
self.project_point(m, pt, false).is_inside
}
}
pub trait PointQueryWithLocation<N: RealField + Copy> {
type Location;
fn project_point_with_location(
&self,
m: &Isometry<N>,
pt: &Point<N>,
solid: bool,
) -> (PointProjection<N>, Self::Location);
}