vrust 0.0.1

VRust game engine
use std::sync::Arc;
use super::super::super::math::number::Float;
use super::super::super::math::matrix::Mat4x4;
use super::super::super::math::vector::Vec3;
use super::super::super::system::file::File;
use super::super::super::util::cell::DebugCell;
use super::{Basic, Camera};

pub struct Perspective<E>
where
    E: Float,
{
    b: Basic<E>,
    fov: E,
    near: E,
    far: E,
    p: Mat4x4<E>,
    vp: Mat4x4<E>,
}

impl<E> Perspective<E>
where
    E: Float,
{
    pub fn new(f: &Arc<DebugCell<File>>, ratio: E) -> Self {
        let fov = f.borrow_mut().read_type();
        let near = f.borrow_mut().read_type();
        let far = f.borrow_mut().read_type();
        let b = Basic::new(f, ratio);
        let p = Mat4x4::pers(fov, b.a, near, far);
        let vp = &p * b.get_view();
        Perspective {
            b: b,
            fov: fov,
            near: near,
            far: far,
            p: p,
            vp: vp,
        }
    }
}

impl<E> Camera<E> for Perspective<E>
where
    E: Float,
{
    fn travel(&mut self, d: &Vec3<E>) {
        self.b.travel(d);
        self.vp = &self.p * self.b.get_view();
    }
    fn place(&mut self, l: &Vec3<E>) {
        self.b.place(l);
        self.vp = &self.p * self.b.get_view();
    }
    fn rotate_local_x(&mut self) {
        self.b.rotate_local_x();
        self.vp = &self.p * self.b.get_view();
    }
    fn rotate_local_y(&mut self) {
        self.b.rotate_local_y();
        self.vp = &self.p * self.b.get_view();
    }
    fn rotate_local_z(&mut self) {
        self.b.rotate_local_z();
        self.vp = &self.p * self.b.get_view();
    }
    fn rotate(&mut self, axis: &Vec3<E>) {
        self.b.rotate(axis);
        self.vp = &self.p * self.b.get_view();
    }
    fn side(&mut self) {
        self.b.side();
        self.vp = &self.p * self.b.get_view();
    }
    fn forward(&mut self) {
        self.b.forward();
        self.vp = &self.p * self.b.get_view();
    }
    fn set_viewport(&mut self, w: E, h: E) {
        self.b.a = w / h;
        self.p = Mat4x4::pers(self.fov, self.b.a, self.near, self.far);
        self.vp = &self.p * self.b.get_view();
    }
    fn set_fild_of_view(&mut self, f: E) {
        self.fov = f;
        self.p = Mat4x4::pers(self.fov, self.b.a, self.near, self.far);
        self.vp = &self.p * self.b.get_view();
    }
    fn set_range(&mut self, s: E, e: E) {
        self.far = e;
        self.near = s;
        self.p = Mat4x4::pers(self.fov, self.b.a, self.near, self.far);
        self.vp = &self.p * self.b.get_view();
    }
    fn get_view(&self) -> &Mat4x4<E> {
        self.b.get_view()
    }
    fn get_view_projection(&self) -> &Mat4x4<E> {
        &self.vp
    }
    fn look_at(&mut self, eye: &Vec3<E>, at: &Vec3<E>, up: &Vec3<E>) {
        self.b.look_at(eye, at, up);
        self.vp = &self.p * self.b.get_view();
    }
    fn set_rotation_speed(&mut self, speed: E) {
        self.b.set_rotation_speed(speed);
    }
    fn set_speed(&mut self, speed: E) {
        self.b.set_speed(speed);
    }
}