extern crate glutin;
+use cgmath::{Matrix4, Vector4};
+use cgmath::conv::array4x4;
use glutin::ElementState::{Pressed, Released};
-use glutin::Event::KeyboardInput;
+use glutin::Event::{KeyboardInput, MouseMoved};
use glutin::VirtualKeyCode;
+use std::f32::consts::PI;
use support::vec3::Vec3;
use support::vec3::norm;
#[derive(Default)]
pub struct CameraState {
- aspect_ratio: f32,
+ aspect: f32,
pos: Vec3,
dir: Vec3,
turning_left: bool,
turning_down: bool,
turning_right: bool,
+
+ mouse_x: i32,
+ mouse_y: i32,
+ rel_x: i32,
+ rel_y: i32,
}
impl CameraState {
pub fn new() -> CameraState {
CameraState {
- aspect_ratio: 1024.0 / 768.0,
+ aspect: 1280.0 / 720.0,
pos: Vec3(0.0, 0.0, 0.0),
dir: Vec3(0.0, 0.0, -1.0),
+ mouse_x: -1,
+ mouse_y: -1,
.. Default::default()
}
}
self.dir = dir;
}
- pub fn get_perspective(&self) -> [[f32; 4]; 4] {
- let fov: f32 = 3.141592 / 2.0;
+ pub fn get_persp_mat(&self) -> Matrix4<f32> {
+ let fov: f32 = PI / 2.0;
let zfar = 1024.0;
let znear = 0.1;
let f = 1.0 / (fov / 2.0).tan();
// note: remember that this is column-major, so the lines of code are actually columns
- [
- [f / self.aspect_ratio, 0.0, 0.0 , 0.0],
- [ 0.0 , f , 0.0 , 0.0],
- [ 0.0 , 0.0, (zfar+znear)/(zfar-znear) , 1.0],
- [ 0.0 , 0.0, -(2.0*zfar*znear)/(zfar-znear), 0.0],
- ]
+ Matrix4 {
+ x: Vector4{ x: f / self.aspect, y: 0.0, z: 0.0, w: 0.0 },
+ y: Vector4{ x: 0.0, y: f, z: 0.0, w: 0.0 },
+ z: Vector4{ x: 0.0, y: 0.0, z: (zfar+znear)/(zfar-znear), w: 1.0 },
+ w: Vector4{ x: 0.0, y: 0.0, z: -(2.0*zfar*znear)/(zfar-znear), w: 0.0 },
+ }
}
- pub fn get_view(&self) -> [[f32; 4]; 4] {
+ pub fn get_view_mat(&self) -> Matrix4<f32> {
let f = norm(&self.dir);
let up = Vec3(0.0, 1.0, 0.0);
-self.pos.0 * f.0 - self.pos.1 * f.1 - self.pos.2 * f.2);
// note: remember that this is column-major, so the lines of code are actually columns
- [
- [sn.0, u.0, f.0, 0.0],
- [sn.1, u.1, f.1, 0.0],
- [sn.2, u.2, f.2, 0.0],
- [p.0, p.1, p.2, 1.0],
- ]
+ Matrix4{
+ x: Vector4{ x: sn.0, y: u.0, z: f.0, w: 0.0 },
+ y: Vector4{ x: sn.1, y: u.1, z: f.1, w: 0.0 },
+ z: Vector4{ x: sn.2, y: u.2, z: f.2, w: 0.0 },
+ w: Vector4{ x: p.0, y: p.1, z: p.2, w: 1.0 },
+ }
+ }
+
+ pub fn get_perspview(&self) -> [[f32; 4]; 4] {
+ array4x4(self.get_persp_mat() * self.get_view_mat())
+ }
+
+ pub fn get_perspective(&self) -> [[f32; 4]; 4] {
+ array4x4(self.get_persp_mat())
+ }
+
+ pub fn get_view(&self) -> [[f32; 4]; 4] {
+ array4x4(self.get_view_mat())
}
pub fn update(&mut self) {
s.2 * f.0 - s.0 * f.2,
s.0 * f.1 - s.1 * f.0);
+ let walk_speed = 0.01;
+ let strife_speed = 0.02;
+ let pan_speed = 0.001;
+
if self.moving_up {
- self.pos += u * 0.01;
- }
- if self.moving_left {
- self.pos.0 -= s.0 * 0.01;
- self.pos.1 -= s.1 * 0.01;
- self.pos.2 -= s.2 * 0.01;
+ self.pos += u * strife_speed;
}
if self.moving_down {
- self.pos.0 -= u.0 * 0.01;
- self.pos.1 -= u.1 * 0.01;
- self.pos.2 -= u.2 * 0.01;
+ self.pos -= u * strife_speed;
+ }
+ if self.moving_left {
+ self.pos -= s * strife_speed;
}
if self.moving_right {
- self.pos += s * 0.01;
+ self.pos += s * strife_speed;
}
if self.moving_forward {
- self.pos += f * 0.01;
+ self.pos += f * walk_speed;
}
if self.moving_backward {
- self.pos.0 -= f.0 * 0.01;
- self.pos.1 -= f.1 * 0.01;
- self.pos.2 -= f.2 * 0.01;
- }
- if self.turning_left {
- let a: f32 = 0.05;
- self.dir = Vec3(f.0 * a.cos() + f.2 * a.sin(), f.1, - f.0 * a.sin() + f.2 * a.cos());
- }
- if self.turning_right {
- let a: f32 = -0.05;
- self.dir = Vec3(f.0 * a.cos() + f.2 * a.sin(), f.1, - f.0 * a.sin() + f.2 * a.cos());
- }
- if self.turning_up {
- let a: f32 = -0.05;
- self.dir = Vec3(f.0, f.1 * a.cos() - f.2 * a.sin(), f.1 * a.sin() + f.2 * a.cos());
- }
- if self.turning_down {
- let a: f32 = 0.05;
- self.dir = Vec3(f.0, f.1 * a.cos() - f.2 * a.sin(), f.1 * a.sin() + f.2 * a.cos());
+ self.pos -= f * walk_speed;
}
+
+ if self.turning_left { self.rel_x -= 8; }
+ if self.turning_right { self.rel_x += 8; }
+ if self.turning_up { self.rel_y -= 2; }
+ if self.turning_down { self.rel_y += 2; }
+ let vx = -pan_speed * self.rel_x as f32;
+ let vy = -pan_speed * self.rel_y as f32;
+ self.dir = Vec3(f.0 * vx.cos() + f.2 * vx.sin(),
+ f.1 * vy.cos() - f.2 * vy.sin(),
+ f.1 * vy.sin() - f.0 * vx.sin() + f.2 * vx.cos() * vy.cos());
+ self.rel_x = 0;
+ self.rel_y = 0;
+
//println!("camera_pos = {:?}", self.pos);
//println!("camera_dir = {:?}", self.dir);
}
pub fn process_input(&mut self, event: &glutin::Event) {
match event {
+ &MouseMoved(x, y) => {
+ if self.mouse_x == -1 {
+ // Set initial absolute position.
+ self.mouse_x = x;
+ self.mouse_y = y;
+ }
+ self.rel_x += x - self.mouse_x;
+ self.rel_y += y - self.mouse_y;
+ self.mouse_x = x;
+ self.mouse_y = y;
+ }
&KeyboardInput(Pressed, _, Some(VirtualKeyCode::Up)) => {
self.moving_up = true;
},