specs_transform 0.5.0

transform 2d and 3d component for specs
use std::ops::{Deref, DerefMut};

use mat4;
use num_traits::{One, Zero};

use specs::{Component, DenseVecStorage, FlaggedStorage};

#[derive(Debug, Serialize, Deserialize)]
pub struct GlobalTransform3D<T>(pub [T; 16]);

impl<T> Component for GlobalTransform3D<T>
where
    T: 'static + Sync + Send,
{
    type Storage = FlaggedStorage<Self, DenseVecStorage<Self>>;
}

impl<T> From<[T; 16]> for GlobalTransform3D<T> {
    #[inline(always)]
    fn from(matrix: [T; 16]) -> Self {
        GlobalTransform3D(matrix)
    }
}

impl<T> Default for GlobalTransform3D<T>
where
    T: One + Zero,
{
    #[inline(always)]
    fn default() -> Self {
        Self::from(mat4::new_identity())
    }
}

impl<T> GlobalTransform3D<T>
where
    T: One + Zero,
{
    #[inline(always)]
    pub fn new() -> Self {
        Self::default()
    }
}

impl<T> GlobalTransform3D<T> {
    #[inline(always)]
    pub fn matrix(&self) -> &[T; 16] {
        &self.0
    }
    #[inline(always)]
    pub fn matrix_mut(&mut self) -> &mut [T; 16] {
        &mut self.0
    }
}

impl<T> AsRef<[T; 16]> for GlobalTransform3D<T> {
    #[inline(always)]
    fn as_ref(&self) -> &[T; 16] {
        self.matrix()
    }
}
impl<T> AsMut<[T; 16]> for GlobalTransform3D<T> {
    #[inline(always)]
    fn as_mut(&mut self) -> &mut [T; 16] {
        self.matrix_mut()
    }
}

impl<T> Deref for GlobalTransform3D<T> {
    type Target = [T; 16];

    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        self.as_ref()
    }
}
impl<T> DerefMut for GlobalTransform3D<T> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.as_mut()
    }
}