#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "aabb")]
mod aabb;
use core::borrow::Borrow;
#[cfg(feature = "aabb")]
pub use aabb::Aabb;
pub trait Collides<S = Self> {
#[must_use]
fn collides(&self, other: impl Borrow<S>) -> bool;
#[must_use]
fn collides_any<'a, T>(&self, others: impl IntoIterator<Item = T>) -> bool
where
T: Borrow<S> + 'a,
{
others.into_iter().any(|other| self.collides(other))
}
}
pub trait Penetration<S = Self> {
#[must_use]
fn penetration(&self, other: impl Borrow<S>) -> Option<[f32; 2]>;
#[must_use]
fn max_penetration<'a, T>(&self, others: impl IntoIterator<Item = T>) -> Option<[f32; 2]>
where
T: Borrow<S> + 'a,
{
let mut max_magnitude = f32::MIN;
let mut max = None;
others
.into_iter()
.filter_map(move |other| self.penetration(other))
.for_each(|p| {
let magnitude = abs(p[0]) + abs(p[1]);
if magnitude > max_magnitude {
max_magnitude = magnitude;
max = Some(p);
}
});
max
}
}
#[cfg(feature = "std")]
fn abs(v: f32) -> f32 {
v.abs()
}
#[cfg(all(not(feature = "std"), feature = "libm"))]
fn abs(v: f32) -> f32 {
libm::fabsf(v)
}
#[cfg(all(not(feature = "std"), not(feature = "libm")))]
fn abs(v: f32) -> f32 {
f32::from_bits(v.to_bits() & 0x7fff_ffff)
}