#[path = "support/macros.rs"]
#[macro_use]
mod macros;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
use glam_det::{
nums::{f32x4, num_traits::*},
Affine2, Affine2x4, Affine3A, Affine3x4, DAffine2, DAffine3, DIsometry3, DMat2, DMat3, DMat4,
DPoint2, DPoint3, DPoint4, DQuat, DVec2, DVec3, DVec4, Isometry3, Isometry3x4, Mat2, Mat2x4,
Mat3, Mat3A, Mat3x4, Mat4, Mat4x4, Point2, Point2x4, Point3, Point3A, Point3x4, Point4,
Point4x4, Quat, Quatx4, UnitDQuat, UnitDVec2, UnitDVec3, UnitDVec4, UnitQuat, UnitQuatx4,
UnitVec2, UnitVec2x4, UnitVec3, UnitVec3A, UnitVec3x4, UnitVec4, UnitVec4x4, Vec2, Vec2x4,
Vec3, Vec3A, Vec3x4, Vec4, Vec4x4,
};
pub trait Deg {
fn to_radians(self) -> Self;
}
impl Deg for f32 {
fn to_radians(self) -> f32 {
f32::to_radians(self)
}
}
impl Deg for f64 {
fn to_radians(self) -> f64 {
f64::to_radians(self)
}
}
impl Deg for f32x4 {
fn to_radians(self) -> f32x4 {
f32x4::to_radians(self)
}
}
#[allow(dead_code)]
#[inline]
pub fn deg<T: Deg>(angle: T) -> T {
angle.to_radians()
}
#[allow(dead_code)]
#[inline]
pub fn rad<T>(angle: T) -> T {
angle
}
pub trait FloatCompare<Rhs: ?Sized = Self> {
#[allow(dead_code)]
fn approx_eq(&self, other: &Rhs, max_abs_diff: f32) -> bool;
fn abs_diff(&self, other: &Rhs) -> Rhs;
}
impl FloatCompare for f32 {
#[inline]
fn approx_eq(&self, other: &f32, max_abs_diff: f32) -> bool {
(self - other).abs() <= max_abs_diff
}
#[inline]
fn abs_diff(&self, other: &f32) -> f32 {
(self - other).abs()
}
}
impl FloatCompare for f32x4 {
#[inline]
fn approx_eq(&self, other: &f32x4, max_abs_diff: f32) -> bool {
(self - other).absf().le(f32x4::splat(max_abs_diff)).all()
}
#[inline]
fn abs_diff(&self, other: &f32x4) -> f32x4 {
(self - other).absf()
}
}
impl FloatCompare for f64 {
#[inline]
fn approx_eq(&self, other: &f64, max_abs_diff: f32) -> bool {
(self - other).abs() <= max_abs_diff as f64
}
#[inline]
fn abs_diff(&self, other: &f64) -> f64 {
(self - other).abs()
}
}
impl FloatCompare for Mat2 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
)
}
}
impl FloatCompare for DMat2 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as f64)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
)
}
}
impl FloatCompare for Mat2x4 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, f32x4::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
)
}
}
impl FloatCompare for Mat3 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
(self.z_axis - other.z_axis).abs(),
)
}
}
impl FloatCompare for Mat3A {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
(self.z_axis - other.z_axis).abs(),
)
}
}
impl FloatCompare for DMat3 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as f64)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
(self.z_axis - other.z_axis).abs(),
)
}
}
impl FloatCompare for Mat3x4 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, f32x4::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
(self.z_axis - other.z_axis).abs(),
)
}
}
impl FloatCompare for DMat4 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as f64)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
(self.z_axis - other.z_axis).abs(),
(self.w_axis - other.w_axis).abs(),
)
}
}
impl FloatCompare for Mat4x4 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, f32x4::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
(self.z_axis - other.z_axis).abs(),
(self.w_axis - other.w_axis).abs(),
)
}
}
impl FloatCompare for Mat4 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_cols(
(self.x_axis - other.x_axis).abs(),
(self.y_axis - other.y_axis).abs(),
(self.z_axis - other.z_axis).abs(),
(self.w_axis - other.w_axis).abs(),
)
}
}
impl FloatCompare for DAffine3 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as f64)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
matrix3: self.matrix3.abs_diff(&other.matrix3),
translation: self.translation.abs_diff(&other.translation),
}
}
}
impl FloatCompare for DAffine2 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as f64)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
matrix2: self.matrix2.abs_diff(&other.matrix2),
translation: self.translation.abs_diff(&other.translation),
}
}
}
impl FloatCompare for Affine3A {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
matrix3: self.matrix3.abs_diff(&other.matrix3),
translation: self.translation.abs_diff(&other.translation),
}
}
}
impl FloatCompare for Affine2 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
matrix2: self.matrix2.abs_diff(&other.matrix2),
translation: self.translation.abs_diff(&other.translation),
}
}
}
impl FloatCompare for Affine3x4 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, f32x4::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
matrix3: self.matrix3.abs_diff(&other.matrix3),
translation: self.translation.abs_diff(&other.translation),
}
}
}
impl FloatCompare for Affine2x4 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, f32x4::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
matrix2: self.matrix2.abs_diff(&other.matrix2),
translation: self.translation.abs_diff(&other.translation),
}
}
}
impl FloatCompare for DIsometry3 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as f64)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
rotation: self.rotation.abs_diff(&other.rotation),
translation: self.translation.abs_diff(&other.translation),
}
}
}
impl FloatCompare for Isometry3 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
rotation: self.rotation.abs_diff(&other.rotation),
translation: self.translation.abs_diff(&other.translation),
}
}
}
impl FloatCompare for Isometry3x4 {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, f32x4::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self {
rotation: self.rotation.abs_diff(&other.rotation),
translation: self.translation.abs_diff(&other.translation),
}
}
}
macro_rules! impl_float_compare_for_vec {
($vec:ident, $float:ident) => {
impl FloatCompare for $vec {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as $float)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
(*self - *other).abs()
}
}
};
}
macro_rules! impl_float_compare_for_quat {
($quat:ident, $float:ident) => {
impl FloatCompare for $quat {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as $float)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_xyzw(
(self.x - other.x).abs(),
(self.y - other.y).abs(),
(self.z - other.z).abs(),
(self.w - other.w).abs(),
)
}
}
};
}
macro_rules! impl_float_compare_for_unit_vec {
($vec:ident, $float:ident, $as_unit_fn:ident) => {
impl FloatCompare for $vec {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as $float)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
(*self - *other).$as_unit_fn().abs()
}
}
};
}
macro_rules! impl_float_compare_for_unit_quat {
($quat:ident, $float:ident) => {
impl FloatCompare for $quat {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as $float)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_xyzw_unchecked(
(self.x - other.x).abs(),
(self.y - other.y).abs(),
(self.z - other.z).abs(),
(self.w - other.w).abs(),
)
}
}
};
}
macro_rules! impl_float_compare_for_vecx4 {
($vec:ident, $float:ident) => {
impl FloatCompare for $vec {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, $float::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
(*self - *other)
}
}
};
}
macro_rules! impl_float_compare_for_quatx4 {
($vec:ident, $float:ident) => {
impl FloatCompare for $vec {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, $float::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
self - other
}
}
};
}
macro_rules! impl_float_compare_for_unit_vecx4 {
($vec:ident, $float:ident, $as_unit_fn:ident) => {
impl FloatCompare for $vec {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, $float::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
(*self - *other).$as_unit_fn()
}
}
};
}
macro_rules! impl_float_compare_for_unit_quatx4 {
($vec:ident, $float:ident) => {
impl FloatCompare for $vec {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, $float::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
Self::from_array_unchecked((self - other).to_array())
}
}
};
}
macro_rules! impl_float_compare_for_point {
($point:ident, $float:ident, $from_vec:ident) => {
impl FloatCompare for $point {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, max_abs_diff as $float)
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
$point::$from_vec(*self - *other)
}
}
};
}
macro_rules! impl_float_compare_for_pointx4 {
($point:ident, $float:ident, $from_vec:ident) => {
impl FloatCompare for $point {
#[inline]
fn approx_eq(&self, other: &Self, max_abs_diff: f32) -> bool {
self.abs_diff_eq(*other, $float::const_splat(max_abs_diff))
.all()
}
#[inline]
fn abs_diff(&self, other: &Self) -> Self {
$point::$from_vec(*self - *other)
}
}
};
}
impl_float_compare_for_vec!(Vec2, f32);
impl_float_compare_for_vec!(Vec3, f32);
impl_float_compare_for_vec!(Vec3A, f32);
impl_float_compare_for_vec!(Vec4, f32);
impl_float_compare_for_quat!(Quat, f32);
impl_float_compare_for_vec!(DVec2, f64);
impl_float_compare_for_vec!(DVec3, f64);
impl_float_compare_for_vec!(DVec4, f64);
impl_float_compare_for_quat!(DQuat, f64);
impl_float_compare_for_vecx4!(Vec2x4, f32x4);
impl_float_compare_for_vecx4!(Vec3x4, f32x4);
impl_float_compare_for_vecx4!(Vec4x4, f32x4);
impl_float_compare_for_quatx4!(Quatx4, f32x4);
impl_float_compare_for_unit_vec!(UnitVec2, f32, as_unit_vec2_unchecked);
impl_float_compare_for_unit_vec!(UnitVec3, f32, as_unit_vec3_unchecked);
impl_float_compare_for_unit_vec!(UnitVec3A, f32, as_unit_vec3a_unchecked);
impl_float_compare_for_unit_vec!(UnitVec4, f32, as_unit_vec4_unchecked);
impl_float_compare_for_unit_quat!(UnitQuat, f32);
impl_float_compare_for_unit_vec!(UnitDVec2, f64, as_unit_dvec2_unchecked);
impl_float_compare_for_unit_vec!(UnitDVec3, f64, as_unit_dvec3_unchecked);
impl_float_compare_for_unit_vec!(UnitDVec4, f64, as_unit_dvec4_unchecked);
impl_float_compare_for_unit_quat!(UnitDQuat, f64);
impl_float_compare_for_unit_vecx4!(UnitVec2x4, f32x4, as_unit_vec2x4_unchecked);
impl_float_compare_for_unit_vecx4!(UnitVec3x4, f32x4, as_unit_vec3x4_unchecked);
impl_float_compare_for_unit_vecx4!(UnitVec4x4, f32x4, as_unit_vec4x4_unchecked);
impl_float_compare_for_unit_quatx4!(UnitQuatx4, f32x4);
impl_float_compare_for_point!(Point2, f32, from_vec2);
impl_float_compare_for_point!(Point3, f32, from_vec3);
impl_float_compare_for_point!(Point3A, f32, from_vec3a);
impl_float_compare_for_point!(Point4, f32, from_vec4);
impl_float_compare_for_point!(DPoint2, f64, from_dvec2);
impl_float_compare_for_point!(DPoint3, f64, from_dvec3);
impl_float_compare_for_point!(DPoint4, f64, from_dvec4);
impl_float_compare_for_pointx4!(Point2x4, f32x4, from_vec2x4);
impl_float_compare_for_pointx4!(Point3x4, f32x4, from_vec3x4);
impl_float_compare_for_pointx4!(Point4x4, f32x4, from_vec4x4);