pub mod mat4a;
#[cfg(test)]
mod tests;
pub mod vec2a;
use crate::{
glam,
prelude::{
glam_ext::{Mat4A, Vec2A},
*,
},
};
use approx::{AbsDiffEq, UlpsEq};
use std::{borrow::Borrow, fmt::Debug};
macro_rules! impl_aabb2 {
($struct_name:ident, $vec_type:ty, $scalar_type:ty) => {
#[derive(Debug, Copy, Clone)]
pub struct $struct_name {
min: $vec_type,
max: $vec_type,
}
impl Default for $struct_name {
fn default() -> Self {
Self {
min: <$vec_type>::splat(<$scalar_type>::INFINITY),
max: <$vec_type>::splat(<$scalar_type>::NEG_INFINITY),
}
}
}
impl crate::prelude::Aabb2 for $struct_name {
type Vector = $vec_type;
fn from_point(point: Self::Vector) -> Self {
Self {
min: point,
max: point,
}
}
#[inline(always)]
fn from_corners(min: Self::Vector, max: Self::Vector) -> Self {
let mut rv = Self { min: max, max };
rv.add_point(min);
rv
}
#[inline(always)]
fn from_center_and_half_extents(
center: Self::Vector,
half_extents: Self::Vector,
) -> Self {
Self {
min: center - half_extents,
max: center + half_extents,
}
}
#[inline(always)]
fn from_center_and_size(center: Self::Vector, size: Self::Vector) -> Self {
let half_extents =
size / <<Self as crate::prelude::Aabb2>::Vector as HasXY>::Scalar::TWO;
Self::from_center_and_half_extents(center, half_extents)
}
fn from_points<I>(points: I) -> Self
where
I: IntoIterator,
I::Item: Borrow<Self::Vector>,
{
let mut aabb = Self::default();
for point in points {
let point = *point.borrow();
aabb.min = aabb.min.min(point);
aabb.max = aabb.max.max(point);
}
aabb
}
#[inline(always)]
fn max(&self) -> Self::Vector {
self.max
}
#[inline(always)]
fn min(&self) -> Self::Vector {
self.min
}
#[inline(always)]
fn add_point(&mut self, pos: Self::Vector) {
self.max = self.max.max(pos);
self.min = self.min.min(pos);
}
#[inline(always)]
fn is_empty(&self) -> bool {
self.max.x < self.min.x
}
#[inline(always)]
fn add_aabb(&mut self, other: &Self) {
self.max = self.max.max(other.max);
self.min = self.min.min(other.min);
}
#[inline(always)]
fn fast_pad(&mut self, delta: Self::Vector) {
self.max += delta;
self.min -= delta;
}
#[inline]
fn pad(&mut self, delta: Self::Vector) {
let center = self.center();
let half_extent: Self::Vector = (self.max - self.min)
/ <<Self as crate::prelude::Aabb2>::Vector as HasXY>::Scalar::TWO;
let new_half_extent: Self::Vector = (half_extent + delta);
let new_half_extent = new_half_extent.max(Self::Vector::ZERO);
self.max = center + new_half_extent;
self.min = center - new_half_extent;
}
#[inline(always)]
fn contains_point_inclusive(&self, point: Self::Vector) -> bool {
point.x >= self.min.x
&& point.x <= self.max.x
&& point.y >= self.min.y
&& point.y <= self.max.y
}
#[inline(always)]
fn center(&self) -> Self::Vector {
(self.max + self.min) * 0.5
}
#[inline(always)]
fn extents(&self) -> (Self::Vector, Self::Vector, Self::Vector) {
(self.min, self.max, self.max - self.min)
}
#[inline(always)]
fn contains_aabb_inclusive(&self, other: &Self) -> bool {
self.min.x <= other.min.x
&& other.max.x <= self.max.x
&& self.min.y <= other.min.y
&& other.max.y <= self.max.y
}
#[inline(always)]
fn convex_hull(&self) -> Vec<Self::Vector> {
crate::trait_impl::aabb_to_vec::<$struct_name>(*self)
}
#[inline(always)]
fn apply<F>(&mut self, f: F)
where
F: Fn(Self::Vector) -> Self::Vector,
{
if !self.is_empty() {
let new_min = f(self.min);
let new_max = f(self.max);
self.min = new_min.min(new_max);
self.max = new_max.max(new_min);
}
}
}
impl From<$struct_name> for Vec<$vec_type> {
#[inline(always)]
fn from(other: $struct_name) -> Self {
crate::trait_impl::aabb_to_vec(other)
}
}
impl PartialEq for $struct_name
where
$struct_name: crate::prelude::Aabb2,
{
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
crate::trait_impl::aabb2_partial_eq(self, other)
}
}
};
}
impl_aabb2!(DAabb2, glam::DVec2, f64);
impl_aabb2!(Aabb2A, Vec2A, f32);
impl_aabb2!(Aabb2, glam::Vec2, f32);
macro_rules! impl_aabb3 {
($struct_name:ident, $vec_type:ty, $scalar_type:ty) => {
#[derive(Debug, Copy, Clone)]
pub struct $struct_name {
min: $vec_type,
max: $vec_type,
}
impl Default for $struct_name {
fn default() -> Self {
Self {
min: <$vec_type>::splat(<$scalar_type>::INFINITY),
max: <$vec_type>::splat(<$scalar_type>::NEG_INFINITY),
}
}
}
impl crate::prelude::Aabb3 for $struct_name {
type Vector = $vec_type;
fn from_point(point: Self::Vector) -> Self {
Self {
min: point,
max: point,
}
}
#[inline(always)]
fn from_corners(min: Self::Vector, max: Self::Vector) -> Self {
let mut rv = Self { min: max, max };
rv.add_point(min);
rv
}
#[inline(always)]
fn from_center_and_half_extents(
center: Self::Vector,
half_extents: Self::Vector,
) -> Self {
Self {
min: center - half_extents,
max: center + half_extents,
}
}
#[inline(always)]
fn from_center_and_size(center: Self::Vector, size: Self::Vector) -> Self {
let half_extents = size / 2.0;
Self::from_center_and_half_extents(center, half_extents)
}
fn from_points<I>(points: I) -> Self
where
I: IntoIterator,
I::Item: Borrow<Self::Vector>,
{
let mut aabb = Self::default();
for point in points {
let point = *point.borrow();
aabb.min = aabb.min.min(point);
aabb.max = aabb.max.max(point);
}
aabb
}
#[inline(always)]
fn max(&self) -> Self::Vector {
self.max
}
#[inline(always)]
fn min(&self) -> Self::Vector {
self.min
}
#[inline(always)]
fn add_point(&mut self, pos: Self::Vector) {
self.max = self.max.max(pos);
self.min = self.min.min(pos);
}
#[inline(always)]
fn is_empty(&self) -> bool {
self.max.x < self.min.x
}
#[inline(always)]
fn add_aabb(&mut self, other: &Self) {
self.max = self.max.max(other.max);
self.min = self.min.min(other.min);
}
#[inline(always)]
fn fast_pad(&mut self, delta: Self::Vector) {
self.max += delta;
self.min -= delta;
}
#[inline]
fn pad(&mut self, delta: Self::Vector) {
let center = self.center();
let half_extent = (self.max - self.min) * 0.5;
let new_half_extent = (half_extent + delta).max(Self::Vector::ZERO);
self.max = center + new_half_extent;
self.min = center - new_half_extent;
}
#[inline(always)]
fn contains_point_inclusive(&self, point: Self::Vector) -> bool {
point.x >= self.min.x
&& point.x <= self.max.x
&& point.y >= self.min.y
&& point.y <= self.max.y
&& point.z >= self.min.z
&& point.z <= self.max.z
}
#[inline(always)]
fn center(&self) -> Self::Vector {
(self.max + self.min) * 0.5
}
#[inline(always)]
fn extents(&self) -> (Self::Vector, Self::Vector, Self::Vector) {
(self.min, self.max, self.max - self.min)
}
#[inline(always)]
fn contains_aabb_inclusive(&self, other: &Self) -> bool {
self.min.x <= other.min.x
&& other.max.x <= self.max.x
&& self.min.y <= other.min.y
&& other.max.y <= self.max.y
&& self.min.z <= other.min.z
&& other.max.z <= self.max.z
}
#[inline(always)]
fn get_plane(&self) -> Option<Plane> {
Plane::get_plane::<Self>(self)
}
#[inline(always)]
fn get_plane_relaxed(&self, epsilon: $scalar_type, max_ulps: u32) -> Option<Plane> {
Plane::get_plane_relaxed::<$vec_type>(self, epsilon, max_ulps)
}
#[inline(always)]
fn apply<F>(&mut self, f: F)
where
F: Fn(Self::Vector) -> Self::Vector,
{
if !self.is_empty() {
let new_min = f(self.min);
let new_max = f(self.max);
self.min = new_min.min(new_max);
self.max = new_max.max(new_min);
}
}
}
impl PartialEq for $struct_name
where
$struct_name: crate::prelude::Aabb3,
{
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
crate::trait_impl::aabb3_partial_eq(self, other)
}
}
};
}
impl_aabb3!(DAabb3, glam::DVec3, f64);
impl_aabb3!(Aabb3A, glam::Vec3A, f32);
impl_aabb3!(Aabb3, glam::Vec3, f32);
macro_rules! impl_vector2 {
($vec2_type:ty, $scalar_type:ty, $vec3_type:ty, $affine_type:ty, $aabb_type:ty) => {
impl HasXY for $vec2_type {
type Scalar = $scalar_type;
#[inline(always)]
fn new_2d(x: Self::Scalar, y: Self::Scalar) -> Self {
<$vec2_type>::new(x, y)
}
#[inline(always)]
fn x(self) -> Self::Scalar {
self.x
}
#[inline(always)]
fn set_x(&mut self, val: Self::Scalar) {
self.x = val
}
#[inline(always)]
fn x_mut(&mut self) -> &mut Self::Scalar {
&mut self.x
}
#[inline(always)]
fn y(self) -> Self::Scalar {
self.y
}
#[inline(always)]
fn set_y(&mut self, val: Self::Scalar) {
self.y = val
}
#[inline(always)]
fn y_mut(&mut self) -> &mut Self::Scalar {
&mut self.y
}
}
impl GenericVector2 for $vec2_type {
const ZERO: Self = <$vec2_type>::ZERO;
const ONE: Self = <$vec2_type>::ONE;
type Vector3 = $vec3_type;
type Affine = $affine_type;
type Aabb = $aabb_type;
#[inline(always)]
fn new(x: Self::Scalar, y: Self::Scalar) -> Self {
<$vec2_type>::new(x, y)
}
#[inline(always)]
fn splat(value: Self::Scalar) -> Self {
<$vec2_type>::splat(value)
}
#[inline(always)]
fn to_3d(self, z: Self::Scalar) -> Self::Vector3 {
<$vec3_type>::new(self.x, self.y, z)
}
#[inline(always)]
fn magnitude(self) -> Self::Scalar {
self.length()
}
#[inline(always)]
fn magnitude_sq(self) -> Self::Scalar {
self.length_squared()
}
#[inline(always)]
fn dot(self, rhs: Self) -> Self::Scalar {
<$vec2_type>::dot(self, rhs)
}
#[inline(always)]
fn perp_dot(self, rhs: Self) -> Self::Scalar {
self.perp_dot(rhs)
}
#[inline(always)]
fn normalize(self) -> Self {
<$vec2_type>::normalize(self)
}
#[inline(always)]
fn try_normalize(self, epsilon: Self::Scalar) -> Option<Self> {
let l_sq = self.length_squared();
(l_sq > epsilon * epsilon).then(|| self / l_sq.sqrt())
}
#[inline(always)]
fn distance(self, rhs: Self) -> Self::Scalar {
<$vec2_type>::distance(self, rhs)
}
#[inline(always)]
fn distance_sq(self, rhs: Self) -> Self::Scalar {
<$vec2_type>::distance_squared(self, rhs)
}
#[inline(always)]
fn min(self, rhs: Self) -> Self {
<$vec2_type>::min(self, rhs)
}
#[inline(always)]
fn max(self, rhs: Self) -> Self {
<$vec2_type>::max(self, rhs)
}
#[inline(always)]
fn clamp(self, min: Self, max: Self) -> Self {
<$vec2_type>::clamp(self, min, max)
}
#[inline(always)]
fn is_finite(self) -> bool {
self.x.is_finite() && self.y.is_finite()
}
}
};
}
macro_rules! impl_approx2 {
($vec_type:ty) => {
impl Approx for $vec_type {
#[inline(always)]
fn is_ulps_eq(
self,
other: Self,
epsilon: <Self::Scalar as AbsDiffEq>::Epsilon,
max_ulps: u32,
) -> bool {
self.x().ulps_eq(&other.x(), epsilon, max_ulps)
&& self.y().ulps_eq(&other.y(), epsilon, max_ulps)
}
#[inline(always)]
fn is_abs_diff_eq(
self,
other: Self,
epsilon: <Self::Scalar as AbsDiffEq>::Epsilon,
) -> bool {
self.x().abs_diff_eq(&other.x(), epsilon)
&& self.y().abs_diff_eq(&other.y(), epsilon)
}
}
};
}
impl_vector2!(glam::Vec2, f32, glam::Vec3, glam::Mat3, Aabb2);
impl_approx2!(glam::Vec2);
impl_vector2!(glam::DVec2, f64, glam::DVec3, glam::DMat3, DAabb2);
impl_approx2!(glam::DVec2);
macro_rules! impl_vector3 {
($vec3_type:ty, $scalar_type:ty, $vec2_type:ty, $affine_type:ty, $aabb_type:ty) => {
impl HasXY for $vec3_type {
type Scalar = $scalar_type;
fn new_2d(x: Self::Scalar, y: Self::Scalar) -> Self {
<$vec3_type>::new(x, y, Self::Scalar::ZERO)
}
#[inline(always)]
fn x(self) -> Self::Scalar {
self.x
}
#[inline(always)]
fn set_x(&mut self, val: Self::Scalar) {
self.x = val
}
#[inline(always)]
fn x_mut(&mut self) -> &mut Self::Scalar {
&mut self.x
}
#[inline(always)]
fn y(self) -> Self::Scalar {
self.y
}
#[inline(always)]
fn set_y(&mut self, val: Self::Scalar) {
self.y = val
}
#[inline(always)]
fn y_mut(&mut self) -> &mut Self::Scalar {
&mut self.y
}
}
impl HasXYZ for $vec3_type {
#[inline(always)]
fn new_3d(x: Self::Scalar, y: Self::Scalar, z: Self::Scalar) -> Self {
<$vec3_type>::new(x, y, z)
}
#[inline(always)]
fn z(self) -> Self::Scalar {
self.z
}
#[inline(always)]
fn set_z(&mut self, val: Self::Scalar) {
self.z = val
}
#[inline(always)]
fn z_mut(&mut self) -> &mut Self::Scalar {
&mut self.z
}
}
impl GenericVector3 for $vec3_type {
const ZERO: Self = <$vec3_type>::ZERO;
const ONE: Self = <$vec3_type>::ONE;
type Affine = $affine_type;
type Aabb = $aabb_type;
type Vector2 = $vec2_type;
#[inline(always)]
fn new(x: Self::Scalar, y: Self::Scalar, z: Self::Scalar) -> Self {
<$vec3_type>::new(x, y, z)
}
#[inline(always)]
fn to_2d(self) -> Self::Vector2 {
<$vec2_type>::new(self.x, self.y)
}
#[inline(always)]
fn splat(value: Self::Scalar) -> Self {
<$vec3_type>::splat(value)
}
#[inline(always)]
fn magnitude(self) -> Self::Scalar {
<$vec3_type>::length(self)
}
#[inline(always)]
fn magnitude_sq(self) -> Self::Scalar {
<$vec3_type>::length_squared(self)
}
#[inline(always)]
fn normalize(self) -> Self {
<$vec3_type>::normalize(self)
}
#[inline(always)]
fn try_normalize(self, epsilon: Self::Scalar) -> Option<Self> {
let l_sq = self.length_squared();
(l_sq > epsilon * epsilon).then(|| self / l_sq.sqrt())
}
#[inline(always)]
fn dot(self, rhs: Self) -> Self::Scalar {
<$vec3_type>::dot(self, rhs)
}
#[inline(always)]
fn cross(self, rhs: Self) -> Self {
<$vec3_type>::cross(self, rhs)
}
#[inline(always)]
fn distance(self, rhs: Self) -> Self::Scalar {
<$vec3_type>::distance(self, rhs)
}
#[inline(always)]
fn distance_sq(self, rhs: Self) -> Self::Scalar {
<$vec3_type>::distance_squared(self, rhs)
}
#[inline(always)]
fn min(self, rhs: Self) -> Self {
<$vec3_type>::min(self, rhs)
}
#[inline(always)]
fn max(self, rhs: Self) -> Self {
<$vec3_type>::max(self, rhs)
}
#[inline(always)]
fn clamp(self, min: Self, max: Self) -> Self {
<$vec3_type>::clamp(self, min, max)
}
#[inline(always)]
fn is_finite(self) -> bool {
self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
}
}
};
}
macro_rules! impl_approx3 {
($vec_type:ty) => {
impl Approx for $vec_type {
#[inline(always)]
fn is_ulps_eq(
self,
other: Self,
epsilon: <Self::Scalar as AbsDiffEq>::Epsilon,
max_ulps: u32,
) -> bool {
self.x.ulps_eq(&other.x, epsilon, max_ulps)
&& self.y.ulps_eq(&other.y, epsilon, max_ulps)
&& self.z.ulps_eq(&other.z, epsilon, max_ulps)
}
#[inline(always)]
fn is_abs_diff_eq(
self,
other: Self,
epsilon: <Self::Scalar as AbsDiffEq>::Epsilon,
) -> bool {
self.x.abs_diff_eq(&other.x, epsilon)
&& self.y.abs_diff_eq(&other.y, epsilon)
&& self.z.abs_diff_eq(&other.z, epsilon)
}
}
};
}
impl_vector3!(glam::Vec3, f32, glam::Vec2, glam::Mat4, Aabb3);
impl_approx3!(glam::Vec3);
impl_vector3!(glam::DVec3, f64, glam::DVec2, glam::DMat4, DAabb3);
impl_approx3!(glam::DVec3);
impl_approx2!(Vec2A);
impl HasXY for glam::Vec3A {
type Scalar = f32;
#[inline(always)]
fn new_2d(x: Self::Scalar, y: Self::Scalar) -> Self {
glam::vec3a(x, y, Self::Scalar::ZERO)
}
#[inline(always)]
fn x(self) -> Self::Scalar {
self.x
}
#[inline(always)]
fn x_mut(&mut self) -> &mut Self::Scalar {
&mut self.x
}
#[inline(always)]
fn set_x(&mut self, val: Self::Scalar) {
self.x = val;
}
#[inline(always)]
fn y(self) -> Self::Scalar {
self.y
}
#[inline(always)]
fn y_mut(&mut self) -> &mut Self::Scalar {
&mut self.y
}
#[inline(always)]
fn set_y(&mut self, val: Self::Scalar) {
self.y = val
}
}
impl HasXYZ for glam::Vec3A {
#[inline(always)]
fn new_3d(x: Self::Scalar, y: Self::Scalar, z: Self::Scalar) -> Self {
glam::vec3a(x, y, z)
}
#[inline(always)]
fn z(self) -> Self::Scalar {
self.z
}
#[inline(always)]
fn z_mut(&mut self) -> &mut Self::Scalar {
&mut self.z
}
#[inline(always)]
fn set_z(&mut self, val: Self::Scalar) {
self.z = val
}
}
impl GenericVector3 for glam::Vec3A {
const ZERO: Self = glam::Vec3A::ZERO;
const ONE: Self = glam::Vec3A::ONE;
type Vector2 = Vec2A;
type Aabb = Aabb3A;
type Affine = Mat4A;
#[inline(always)]
fn new(x: Self::Scalar, y: Self::Scalar, z: Self::Scalar) -> Self {
glam::Vec3A::new(x, y, z)
}
#[inline(always)]
fn splat(value: Self::Scalar) -> Self {
Self::new(value, value, value)
}
#[inline(always)]
fn to_2d(self) -> Self::Vector2 {
Vec2A(glam::vec2(self.x, self.y))
}
#[inline(always)]
fn magnitude(self) -> Self::Scalar {
self.length()
}
#[inline(always)]
fn magnitude_sq(self) -> Self::Scalar {
self.length_squared()
}
#[inline(always)]
fn dot(self, other: Self) -> Self::Scalar {
self.dot(other)
}
#[inline(always)]
fn cross(self, rhs: Self) -> Self {
self.cross(rhs)
}
#[inline(always)]
fn normalize(self) -> Self {
self.normalize()
}
#[inline(always)]
fn try_normalize(self, epsilon: Self::Scalar) -> Option<Self> {
let l_sq = self.length_squared();
(l_sq > epsilon * epsilon).then(|| self / l_sq.sqrt())
}
#[inline(always)]
fn distance(self, other: Self) -> Self::Scalar {
self.distance(other)
}
#[inline(always)]
fn distance_sq(self, rhs: Self) -> Self::Scalar {
self.distance_squared(rhs)
}
#[inline(always)]
fn min(self, rhs: Self) -> Self {
glam::Vec3A::min(self, rhs)
}
#[inline(always)]
fn max(self, rhs: Self) -> Self {
glam::Vec3A::max(self, rhs)
}
#[inline(always)]
fn clamp(self, min: Self, max: Self) -> Self {
glam::Vec3A::clamp(self, min, max)
}
fn is_finite(self) -> bool {
self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
}
}
impl_approx3!(glam::Vec3A);
macro_rules! impl_matrix3 {
($mat_type:ty, $vec_type:ty, $vec_type_p1:ty, $scalar_type:ty) => {
impl Affine2D for $mat_type
where
$vec_type: GenericVector2<Scalar = $scalar_type> + HasXY,
{
type Vector2 = $vec_type;
#[inline(always)]
fn from_cols_array(array: &[$scalar_type; 9]) -> Self {
<$mat_type>::from_cols_array(array)
}
#[inline(always)]
fn identity() -> Self {
<$mat_type>::IDENTITY
}
#[inline(always)]
fn transform_vector2(&self, point: $vec_type) -> $vec_type {
<$mat_type>::transform_vector2(self, point)
}
#[inline(always)]
fn transform_point2(&self, point: $vec_type) -> $vec_type {
<$mat_type>::transform_point2(self, point)
}
#[inline(always)]
fn try_inverse(&self) -> Option<Self> {
let inv = self.inverse();
inv.is_finite().then_some(inv)
}
}
};
}
impl_matrix3!(glam::Mat3, glam::Vec2, glam::Vec3, f32);
impl_matrix3!(glam::DMat3, glam::DVec2, glam::DVec3, f64);
impl Affine2D for glam::Mat3A
where
Vec2A: GenericVector2<Scalar = f32> + HasXY,
{
type Vector2 = Vec2A;
#[inline(always)]
fn from_cols_array(array: &[f32; 9]) -> Self {
glam::Mat3A::from_cols_array(array)
}
#[inline(always)]
fn identity() -> Self {
glam::Mat3A::IDENTITY
}
#[inline(always)]
fn transform_vector2(&self, point: Vec2A) -> Vec2A {
Vec2A(glam::Mat3A::transform_vector2(self, *point))
}
#[inline(always)]
fn transform_point2(&self, point: Vec2A) -> Vec2A {
Vec2A(glam::Mat3A::transform_point2(self, *point))
}
#[inline(always)]
fn try_inverse(&self) -> Option<Self> {
let inverse = glam::Mat3A::inverse(self);
inverse.is_finite().then_some(inverse)
}
}
macro_rules! impl_matrix4 {
($mat_type:ty, $vec_type:ty, $scalar_type:ty) => {
impl Affine3D for $mat_type
where
$vec_type: GenericVector3<Scalar = $scalar_type>,
{
type Vector3 = $vec_type;
#[inline(always)]
fn from_cols_array(array: &[$scalar_type; 16]) -> Self {
<$mat_type>::from_cols_array(array)
}
#[inline(always)]
fn identity() -> Self {
<$mat_type>::IDENTITY
}
#[inline(always)]
fn transform_vector3(&self, vec: $vec_type) -> $vec_type {
<$mat_type>::transform_vector3(self, vec)
}
#[inline(always)]
fn transform_point3(&self, point: $vec_type) -> $vec_type {
<$mat_type>::transform_point3(self, point)
}
#[inline(always)]
fn try_inverse(&self) -> Option<Self> {
let inverse = self.inverse();
inverse.is_finite().then_some(inverse)
}
#[inline(always)]
fn from_plane_to_xy(source_plane: Plane) -> Self {
crate::trait_impl::from_plane_to_xy::<$vec_type>(source_plane)
}
#[inline(always)]
fn from_translation(translation: Self::Vector3) -> Self {
<$mat_type>::from_translation(translation)
}
#[inline(always)]
fn from_scale(scale: Self::Vector3) -> Self {
<$mat_type>::from_scale(scale)
}
}
};
}
impl_matrix4!(glam::Mat4, glam::Vec3, f32);
impl_matrix4!(glam::DMat4, glam::DVec3, f64);
impl SimdUpgradable for glam::Vec3 {
type Simd = glam::Vec3A;
#[inline(always)]
fn to_simd(self) -> Self::Simd {
self.to_vec3a()
}
#[inline(always)]
fn from_simd(simd: Self::Simd) -> Self {
simd.to_vec3()
}
}
impl SimdUpgradable for glam::DVec3 {
type Simd = glam::DVec3;
#[inline(always)]
fn to_simd(self) -> Self::Simd {
self
}
#[inline(always)]
fn from_simd(simd: Self::Simd) -> Self {
simd
}
}