use glam_det::{Isometry3, UnitQuat, Vec3};
use super::traits::OverlapTest;
use crate::traits::MinkowskiSupport;
use crate::{ConvexHull, ConvexHullId, InfinitePlane, ShapeContainer};
pub(super) fn convex_hull_infinite_plane_overlap_test(
a: ConvexHullId,
_: InfinitePlane,
speculative_margin: f32,
offset_b_to_a: Vec3,
orientation_a: UnitQuat,
orientation_b: UnitQuat,
container: Option<&ShapeContainer>,
) -> bool {
let transform_a = Isometry3::from_rotation_translation(orientation_a, Vec3::ZERO);
let transform_b = Isometry3::from_rotation_translation(orientation_b, offset_b_to_a);
let a_to_b_transform = transform_b.inverse() * transform_a;
let container = container.expect("ShapeContainer is required for ConvexHull");
let convex_a = container.get::<ConvexHull>(a).expect("invalid shape id");
let direction = Vec3::NEG_Y;
let convex_in_b_support = convex_a.support_point(direction, &a_to_b_transform);
let support_point_in_b = convex_in_b_support.point;
if support_point_in_b.y <= speculative_margin {
return true;
}
false
}
impl OverlapTest<InfinitePlane> for ConvexHullId {
#[inline]
fn overlap_test(
&self,
target: &InfinitePlane,
offset_target: Vec3,
orientation: UnitQuat,
orientation_target: UnitQuat,
container: Option<&ShapeContainer>,
) -> bool {
convex_hull_infinite_plane_overlap_test(
*self,
*target,
0.0001_f32,
offset_target,
orientation,
orientation_target,
container,
)
}
}
#[cfg(test)]
mod tests {
use glam_det::Vec3;
use wasm_bindgen_test::wasm_bindgen_test;
use super::*;
use crate::overlap::test_overlap_test::test_overlap_test;
use crate::shapes::CuboidExt;
use crate::{ConvexHull, Cuboid, ShapeContainer};
#[test]
#[wasm_bindgen_test]
fn test_convex_hull_infinite_plane() {
let _ = env_logger::builder().is_test(true).try_init();
let b = InfinitePlane::default();
let a = Cuboid::new(Vec3::splat(4.0));
let points_a = (0..8).map(|i| a.get_vertex(i)).collect::<Vec<_>>();
let a = ConvexHull::new_unchecked(&points_a);
let mut container = ShapeContainer::default();
let a = container.add(a);
assert!(test_overlap_test(
&a,
&b,
Vec3::new(0.0, 2.0, 0.0),
UnitQuat::IDENTITY,
UnitQuat::IDENTITY,
Some(&container)
));
assert!(test_overlap_test(
&a,
&b,
Vec3::new(0.0, 2.1, 0.0),
UnitQuat::IDENTITY,
UnitQuat::IDENTITY,
Some(&container)
));
assert!(!test_overlap_test(
&a,
&b,
Vec3::new(0.0, -2.1, 0.0),
UnitQuat::IDENTITY,
UnitQuat::IDENTITY,
Some(&container)
));
assert!(test_overlap_test(
&a,
&b,
Vec3::new(0.0, 0.0, 0.0),
UnitQuat::IDENTITY,
UnitQuat::IDENTITY,
Some(&container)
));
assert!(test_overlap_test(
&a,
&b,
Vec3::new(2.1, 0.0, 2.1),
UnitQuat::IDENTITY,
UnitQuat::IDENTITY,
Some(&container)
));
assert!(!test_overlap_test(
&a,
&b,
Vec3::new(0.0, -2.85, 0.0),
UnitQuat::from_euler_default(45f32.to_radians(), 0f32.to_radians(), 0f32.to_radians(),),
UnitQuat::from_euler_default(45f32.to_radians(), 0f32.to_radians(), 0f32.to_radians(),),
Some(&container)
));
assert!(!test_overlap_test(
&a,
&b,
Vec3::new(0.0, -4.1, 0.0),
UnitQuat::from_euler_default(45f32.to_radians(), 0f32.to_radians(), 0f32.to_radians(),),
UnitQuat::IDENTITY,
Some(&container)
));
}
}