use glam_det::nums::num_traits::*;
use glam_det::{Dot, Isometry3, Point3, UnitVec3, UnitVec3x4, Vec3};
pub use phys_geom::shape::InfinitePlane;
use crate::traits::*;
const NORMAL: UnitVec3 = UnitVec3::Y;
pub trait InfinitePlaneExt {
fn distance(&self, p: Point3) -> f32;
}
impl InfinitePlaneExt for InfinitePlane {
#[inline]
fn distance(&self, p: Point3) -> f32 {
p.as_vec3().dot(NORMAL)
}
}
impl ContainsPoint for InfinitePlane {
#[inline]
fn contains_point_with_threshold(&self, local_point: Point3, threshold: f32) -> ContainsResult {
let distance = local_point.y;
let abs_distance = distance.absf();
if abs_distance < threshold {
ContainsResult::Surface
} else if distance > 0.0 {
ContainsResult::Outside
} else {
ContainsResult::Inside
}
}
}
impl SignedDistanceToPoint for InfinitePlane {
#[inline]
fn signed_distance_to_point(&self, local_point: Point3) -> f32 {
self.distance(local_point)
}
}
impl MinkowskiSupport for InfinitePlane {
#[allow(unused)]
fn support_point(&self, direction: Vec3, transform: &Isometry3) -> MinkowskiSupportResult {
todo!("issue #1197") }
}
impl Expansion for InfinitePlane {
#[inline]
fn max_radius_and_max_angular_expansion(&self) -> (f32, f32) {
(0f32, 0f32)
}
}
#[derive(Default, Debug)]
pub struct InfinitePlaneWide {}
impl InfinitePlaneWide {
pub const NORMAL: UnitVec3x4 = UnitVec3x4::Y;
}
impl BaseShapeWide for InfinitePlaneWide {
type TShape = InfinitePlane;
}
macro_rules! impl_infinite_plane_wide {
($($num:tt),*) => {
$(
impl CreateShapeWide<$num> for InfinitePlaneWide {
fn create<'a>(_iter: impl Iterator<Item=&'a Self::TShape> + Clone) -> Self where Self::TShape: 'a {
InfinitePlaneWide::default()
}
}
)*
};
}
impl_infinite_plane_wide!(1, 2, 3, 4);
#[cfg(test)]
mod tests {
use approx_det::assert_relative_eq;
use glam_det::Point3;
use wasm_bindgen_test::*;
use crate::traits::*;
use crate::{InfinitePlane, Shape, ShapeContainer};
#[test]
#[wasm_bindgen_test]
fn test_contains_point_and_distance() {
let _ = env_logger::builder().is_test(true).try_init();
let container = ShapeContainer::default();
let infinite_plane =
Shape::InfinitePlane(InfinitePlane::default()).into_shape_ref(&container);
macro_rules! test_both {
($point:expr, $res:expr, $distance:expr) => {
assert_eq!(infinite_plane.contains_point($point), $res);
assert_relative_eq!(infinite_plane.signed_distance_to_point($point), $distance);
};
}
test_both!(
Point3::new(0.0f32, 0.0f32, 0.0f32),
ContainsResult::Surface,
0.0f32
);
test_both!(
Point3::new(1.0f32, 0.0f32, 0.0f32),
ContainsResult::Surface,
0.0f32
);
test_both!(
Point3::new(1.0f32, 1.0f32, 0.0f32),
ContainsResult::Outside,
1.0f32
);
test_both!(
Point3::new(1.0f32, -1.0f32, 0.0f32),
ContainsResult::Inside,
-1.0f32
);
}
#[test]
#[wasm_bindgen_test]
fn test_compute_expand() {
let _ = env_logger::builder().is_test(true).try_init();
let shape = InfinitePlane::default();
let (max_radius, max_angular_expansion) = shape.max_radius_and_max_angular_expansion();
assert_relative_eq!(max_radius, 0f32);
assert_relative_eq!(max_angular_expansion, 0f32);
}
}