specs_camera 0.5.0

camera 2d and 3d component for specs
extern crate num_traits;
extern crate specs;
extern crate specs_bundler;
extern crate specs_camera;
extern crate specs_transform;

use num_traits::{Float, FromPrimitive};
use specs::{Builder, WorldExt,DispatcherBuilder, Join, System, World, WriteStorage};
use specs_bundler::Bundler;
use specs_camera::{Camera2D, Camera3D, CameraBundle, CameraSystem};
use specs_transform::{Transform2D, Transform3D, TransformBundle};

use std::marker::PhantomData;

#[derive(Default)]
pub struct TestSystem<T>(PhantomData<T>);

impl<'a, T> System<'a> for TestSystem<T>
where
    T: 'static + Sync + Send + Float + FromPrimitive,
{
    type SystemData = (
        WriteStorage<'a, Transform2D<T>>,
        WriteStorage<'a, Transform3D<T>>,
    );

    fn run(&mut self, (mut locals_2d, mut locals_3d): Self::SystemData) {
        for local in (&mut locals_2d).join() {
            local.position[0] = T::from_f32(1.0).unwrap();
            local.position[1] = T::from_f32(1.0).unwrap();
        }
        for local in (&mut locals_3d).join() {
            local.position[0] = T::from_f32(1.0).unwrap();
            local.position[1] = T::from_f32(1.0).unwrap();
            local.position[2] = T::from_f32(1.0).unwrap();
        }
    }
}

#[test]
fn test_camera_2d() {
    let mut world = World::new();

    let mut dispatcher = Bundler::new(&mut world, DispatcherBuilder::new())
        .bundle(TransformBundle::<f32>::default())
        .unwrap()
        .bundle(CameraBundle::<f32>::default())
        .unwrap()
        .with(
            TestSystem::<f32>::default(),
            "test_system",
            &[CameraSystem::<f32>::name()],
        )
        .build();

    world
        .create_entity()
        .with(Transform2D::<f32>::default())
        .with(Camera2D::<f32>::default().with_size(1024, 768))
        .build();

    dispatcher.dispatch(&mut world);
    dispatcher.dispatch(&mut world);

    let globals = world.read_storage::<Camera2D<f32>>();

    for global in (&globals).join() {
        assert_eq!(global.view(), &[1.0, 0.0, 0.0, 1.0, -1.0, -1.0]);
        assert_eq!(global.projection(), &[0.375, 0.0, 0.0, 0.5, 0.0, 0.0]);
    }
}

#[test]
fn test_camera_3d() {
    let mut world = World::new();

    let mut dispatcher = Bundler::new(&mut world, DispatcherBuilder::new())
        .bundle(TransformBundle::<f32>::default())
        .unwrap()
        .bundle(CameraBundle::<f32>::default())
        .unwrap()
        .with(
            TestSystem::<f32>::default(),
            "test_system",
            &[CameraSystem::<f32>::name()],
        )
        .build();

    world
        .create_entity()
        .with(Transform3D::<f32>::default())
        .with(Camera3D::<f32>::default().with_size(1024, 768))
        .build();

    dispatcher.dispatch(&mut world);
    dispatcher.dispatch(&mut world);

    let globals = world.read_storage::<Camera3D<f32>>();

    for global in (&globals).join() {
        assert_eq!(
            global.view(),
            &[1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 1.0]
        );
        assert_eq!(
            global.projection(),
            &[
                -0.16869165,
                0.0,
                0.0,
                0.0,
                0.0,
                -0.22492221,
                0.0,
                0.0,
                0.0,
                0.0,
                -1.0,
                -1.0,
                0.0,
                0.0,
                -<f32 as Float>::epsilon() * 2.0,
                0.0
            ]
        );
    }
}

#[test]
fn test_camera_2d_transform_3d() {
    let mut world = World::new();

    let mut dispatcher = Bundler::new(&mut world, DispatcherBuilder::new())
        .bundle(TransformBundle::<f32>::default())
        .unwrap()
        .bundle(CameraBundle::<f32>::default())
        .unwrap()
        .with(
            TestSystem::<f32>::default(),
            "test_system",
            &[CameraSystem::<f32>::name()],
        )
        .build();

    world
        .create_entity()
        .with(Transform3D::<f32>::default())
        .with(Camera2D::<f32>::default().with_size(1024, 768))
        .build();

    dispatcher.dispatch(&mut world);
    dispatcher.dispatch(&mut world);

    let globals = world.read_storage::<Camera2D<f32>>();

    for global in (&globals).join() {
        assert_eq!(global.view(), &[1.0, 0.0, 0.0, 1.0, -1.0, -1.0]);
        assert_eq!(global.projection(), &[0.375, 0.0, 0.0, 0.5, 0.0, 0.0]);
    }
}

#[test]
fn test_camera_3d_transform_2d() {
    let mut world = World::new();

    let mut dispatcher = Bundler::new(&mut world, DispatcherBuilder::new())
        .bundle(TransformBundle::<f32>::default())
        .unwrap()
        .bundle(CameraBundle::<f32>::default())
        .unwrap()
        .with(
            TestSystem::<f32>::default(),
            "test_system",
            &[CameraSystem::<f32>::name()],
        )
        .build();

    world
        .create_entity()
        .with(Transform2D::<f32>::default())
        .with(Camera3D::<f32>::default().with_size(1024, 768))
        .build();

    dispatcher.dispatch(&mut world);
    dispatcher.dispatch(&mut world);

    let globals = world.read_storage::<Camera3D<f32>>();

    for global in (&globals).join() {
        assert_eq!(
            global.view(),
            &[1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0]
        );
        assert_eq!(
            global.projection(),
            &[
                -0.16869165,
                0.0,
                0.0,
                0.0,
                0.0,
                -0.22492221,
                0.0,
                0.0,
                0.0,
                0.0,
                -1.0,
                -1.0,
                0.0,
                0.0,
                -<f32 as Float>::epsilon() * 2.0,
                0.0
            ]
        );
    }
}