use std::ops::{Add, Mul, Neg, Sub};
use mat32;
use num_traits::{Float, One, Zero};
use specs::{Component, DenseVecStorage, FlaggedStorage};
#[derive(Debug, Serialize, Deserialize)]
pub struct Transform2D<T> {
pub position: [T; 2],
pub scale: [T; 2],
pub rotation: T,
}
impl<T> Component for Transform2D<T>
where
T: 'static + Sync + Send,
{
type Storage = FlaggedStorage<Self, DenseVecStorage<Self>>;
}
impl<T> Default for Transform2D<T>
where
T: Zero + One,
{
#[inline(always)]
fn default() -> Self {
Self::new([T::zero(), T::zero()], [T::one(), T::one()], T::zero())
}
}
impl<T> Transform2D<T>
where
T: Zero + One,
{
#[inline(always)]
pub fn new(position: [T; 2], scale: [T; 2], rotation: T) -> Self {
Transform2D {
position: position,
scale: scale,
rotation: rotation,
}
}
#[inline]
pub fn with_position(mut self, position: [T; 2]) -> Self {
self.position = position;
self
}
#[inline]
pub fn with_scale(mut self, scale: [T; 2]) -> Self {
self.scale = scale;
self
}
#[inline]
pub fn with_rotation(mut self, rotation: T) -> Self {
self.rotation = rotation;
self
}
#[inline]
pub fn set_position(&mut self, position: [T; 2]) -> &mut Self {
self.position = position;
self
}
#[inline]
pub fn set_scale(&mut self, scale: [T; 2]) -> &mut Self {
self.scale = scale;
self
}
#[inline]
pub fn set_rotation(&mut self, rotation: T) -> &mut Self {
self.rotation = rotation;
self
}
#[inline(always)]
pub fn matrix(&self) -> [T; 6]
where
T: Float,
for<'a, 'b> &'a T: Mul<&'b T, Output = T>
+ Neg<Output = T>
+ Add<&'b T, Output = T>
+ Sub<&'b T, Output = T>,
{
let mut matrix = mat32::new_identity();
mat32::compose(&mut matrix, &self.position, &self.scale, &self.rotation);
matrix
}
}