plexus 0.0.10

3D mesh generation and manipulation.
Documentation
#![allow(derive_hash_xor_eq)]

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[ 1], camera[ 2], camera[ 3]],
                [camera[ 4], camera[ 5], camera[ 6], camera[ 7]],
                [camera[ 8], camera[ 9], camera[10], camera[11]],
                [camera[12], camera[13], camera[14], camera[15]],
            ],
            model: [
                [model[ 0], model[ 1], model[ 2], model[ 3]],
                [model[ 4], model[ 5], model[ 6], model[ 7]],
                [model[ 8], model[ 9], model[10], model[11]],
                [model[12], model[13], model[14], 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);
    }
}