vector-traits 0.6.2

Rust traits for 2D and 3D vector types.
Documentation
// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2023, 2025 lacklustr@protonmail.com https://github.com/eadf

// This file is part of vector-traits.

use crate::prelude::{Affine3D, GenericVector3, Plane};
use std::ops::Mul;

/// A wrapper around `macaw::Mat4` with zero runtime cost. Created to facilitate the implementation of the trait
/// `GenericVector3` for `Vec3A`. While not an ideal solution, it is the most suitable one identified.
/// Note that this type is only as aligned as `macaw::Mat4` is.
#[repr(transparent)]
#[derive(Copy, Debug, Clone, PartialEq)]
pub struct Mat4A(macaw::Mat4);

impl std::ops::Deref for Mat4A {
    type Target = macaw::Mat4;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl std::ops::DerefMut for Mat4A {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl From<macaw::Mat4> for Mat4A {
    fn from(mat: macaw::Mat4) -> Self {
        Mat4A(mat)
    }
}

impl Affine3D for Mat4A
where
    macaw::Vec3A: GenericVector3<Scalar = f32>,
{
    type Vector3 = macaw::Vec3A;
    #[inline(always)]
    fn transform_point3(&self, point: macaw::Vec3A) -> macaw::Vec3A {
        macaw::Mat4::transform_point3a(self, point)
    }

    #[inline(always)]
    fn transform_vector3(&self, vec: macaw::Vec3A) -> macaw::Vec3A {
        macaw::Mat4::transform_vector3a(self, vec)
    }

    #[inline(always)]
    fn from_cols_array(array: &[f32; 16]) -> Self {
        Mat4A(macaw::Mat4::from_cols_array(array))
    }

    #[inline(always)]
    fn identity() -> Self {
        Mat4A(macaw::Mat4::IDENTITY)
    }

    #[inline(always)]
    fn try_inverse(&self) -> Option<Self> {
        let inv = self.inverse();
        inv.is_finite().then_some(Mat4A(inv))
    }
    #[inline(always)]
    fn from_plane_to_xy(source_plane: Plane) -> Self {
        crate::trait_impl::from_plane_to_xy::<macaw::Vec3A>(source_plane)
    }
    #[inline(always)]
    fn from_translation(translation: Self::Vector3) -> Self {
        Self(macaw::Mat4::from_translation(translation.into()))
    }

    #[inline(always)]
    fn from_scale(scale: Self::Vector3) -> Self {
        Self(macaw::Mat4::from_scale(scale.into()))
    }
}

impl Mul for Mat4A {
    type Output = Self;

    #[inline(always)]
    fn mul(self, rhs: Self) -> Self {
        Mat4A(self.0 * rhs.0)
    }
}