specs_camera 0.3.6

camera 2d and 3d component for specs
Documentation
use std::ops::{Add, Div, Mul, Neg, Sub};

use mat32;
use num_traits::{Float, FromPrimitive};

use specs::{Component, VecStorage};

pub struct Camera2D<T> {
    ortho_size: T,
    projection: [T; 6],
    view: [T; 6],
}

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

impl<T> Default for Camera2D<T>
where
    T: Float + FromPrimitive,
{
    #[inline(always)]
    fn default() -> Self {
        Camera2D {
            ortho_size: T::from_usize(2).unwrap(),
            projection: mat32::new_identity(),
            view: mat32::new_identity(),
        }
    }
}

impl<T> Camera2D<T>
where
    T: Float + FromPrimitive,
    for<'a, 'b> &'a T: Sub<&'b T, Output = T>
        + Add<&'b T, Output = T>
        + Div<&'b T, Output = T>
        + Mul<&'b T, Output = T>
        + Neg<Output = T>,
{
    #[inline(always)]
    pub fn new() -> Self {
        Self::default()
    }

    #[inline(always)]
    pub fn ortho_size(&self) -> T {
        self.ortho_size
    }
    #[inline(always)]
    pub fn set_ortho_size(&mut self, ortho_size: T) {
        self.ortho_size = ortho_size;
    }

    #[inline(always)]
    pub fn projection(&self) -> &[T; 6] {
        &self.projection
    }

    #[inline(always)]
    pub fn view(&self) -> &[T; 6] {
        &self.view
    }

    #[inline]
    pub fn update_view(&mut self, matrix: &[T; 6]) {
        mat32::inv(&mut self.view, matrix);
    }

    #[inline]
    pub fn update_projection(&mut self, width: usize, height: usize) {
        let w = T::from_usize(width).unwrap();
        let h = T::from_usize(height).unwrap();
        let w_gt_h = &w > &h;
        let aspect = if w_gt_h { &w / &h } else { &h / &w };
        let ortho_size_aspect = &self.ortho_size * &aspect;
        let r = if w_gt_h {
            ortho_size_aspect
        } else {
            self.ortho_size
        };
        let l = -&r;
        let t = if w_gt_h {
            self.ortho_size
        } else {
            ortho_size_aspect
        };
        let b = -&t;
        mat32::orthographic(&mut self.projection, &t, &r, &b, &l);
    }
}