plexus 0.0.7

3D mesh generation and manipulation.
Documentation
use decorum;
use gfx;
use nalgebra::{Matrix4, Point3, Scalar, Vector4};
use num::One;
use rand::{self, Rand};
use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};

pub use self::pipeline::*;

#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub struct Color4<T>(Vector4<T>)
where
    T: Scalar;

impl<T> Color4<T>
where
    T: Scalar,
{
    pub fn new(r: T, g: T, b: T, a: T) -> Self {
        Color4(Vector4::new(r, g, b, a))
    }
}

impl<T> Color4<T>
where
    T: One + Scalar,
{
    pub fn white() -> Self {
        Color4::new(T::one(), T::one(), T::one(), T::one())
    }
}

impl<T> Color4<T>
where
    T: One + Rand + Scalar,
{
    pub fn random() -> Self {
        Color4::new(
            rand::random::<T>(),
            rand::random::<T>(),
            rand::random::<T>(),
            T::one(),
        )
    }
}

impl<T> Default for Color4<T>
where
    T: One + Scalar,
{
    fn default() -> Self {
        Color4::white()
    }
}

impl<T> Deref for Color4<T>
where
    T: Scalar,
{
    type Target = Vector4<T>;

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

impl<T> DerefMut for Color4<T>
where
    T: Scalar,
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

gfx_pipeline! {
    pipeline {
        buffer: gfx::VertexBuffer<Vertex> = (),
        transform: gfx::ConstantBuffer<Transform> = "transform",
        camera: gfx::Global<[[f32; 4]; 4]> = "u_camera",
        model: gfx::Global<[[f32; 4]; 4]> = "u_model",
        color: gfx::RenderTarget<gfx::format::Rgba8> = "f_target0",
        depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
    }
}

gfx_constant_struct! {
    Transform {
        camera: [[f32; 4]; 4] = "u_camera",
        model: [[f32; 4]; 4] = "u_model",
    }
}

impl Transform {
    pub fn new(camera: &Matrix4<f32>, model: &Matrix4<f32>) -> Self {
        #[cfg_attr(rustfmt, rustfmt_skip)]
        Transform {
            camera: [
                [camera[0], camera[4], camera[ 8], camera[12]],
                [camera[1], camera[5], camera[ 9], camera[13]],
                [camera[2], camera[6], camera[10], camera[14]],
                [camera[3], camera[7], camera[11], camera[15]],
            ],
            model: [
                [model[0], model[4], model[ 8], model[12]],
                [model[1], model[5], model[ 9], model[13]],
                [model[2], model[6], model[10], model[14]],
                [model[3], model[7], model[11], model[15]],
            ],
        }
    }
}

gfx_vertex_struct! {
    Vertex {
        position: [f32; 3] = "a_position",
        color: [f32; 4] = "a_color",
    }
}

impl Vertex {
    pub fn new(position: &Point3<f32>, color: &Color4<f32>) -> Self {
        Vertex {
            position: [position[0], position[1], position[2]],
            color: [color[0], color[1], color[2], color[3]],
        }
    }
}

impl Default for Vertex {
    fn default() -> Self {
        Vertex {
            position: Default::default(),
            color: Default::default(),
        }
    }
}

impl Eq for Vertex {}

impl Hash for Vertex {
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        decorum::hash_float_array(&self.position, state);
        decorum::hash_float_array(&self.color, state);
    }
}