Fix benchmarks for latest glium/glutin API
[mandelwow.git] / support / camera.rs
index 67beeacd19f8ed48418281e2e1a42571ba8d98f2..25b1e7292b9fb54b92c0bcdb775e052e9f437074 100644 (file)
@@ -1,19 +1,15 @@
-extern crate glutin;
-
-use glutin::ElementState::{Pressed, Released};
-use glutin::Event::KeyboardInput;
-use glutin::VirtualKeyCode;
-use support::vec3::Vec3;
-use support::vec3::norm;
-
+use cgmath::{Matrix4, Vector4};
+use cgmath::conv::array4x4;
+use glium;
+use glium::glutin::event::{ ElementState, VirtualKeyCode, WindowEvent };
 use std::f32;
-
-//use glutin::Event;
-//use VirtualKeyCode;
+use std::f32::consts::PI;
+use crate::support::vec3::Vec3;
+use crate::support::vec3::norm;
 
 #[derive(Default)]
 pub struct CameraState {
-    aspect_ratio: f32,
+    aspect: f32,
     pos: Vec3,
     dir: Vec3,
 
@@ -27,14 +23,21 @@ pub struct CameraState {
     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()
         }
     }
@@ -51,23 +54,23 @@ impl CameraState {
         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);
@@ -86,12 +89,24 @@ impl CameraState {
                  -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) {
@@ -109,113 +124,81 @@ impl CameraState {
                      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) {
+    pub fn process_input(&mut self, event: &WindowEvent) {
+        //println!("camera event={:?}", event);
         match event {
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Up)) => {
-                self.moving_up = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::Up)) => {
-                self.moving_up = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Down)) => {
-                self.moving_down = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::Down)) => {
-                self.moving_down = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Left)) => {
-                self.moving_left = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::Left)) => {
-                self.moving_left = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Right)) => {
-                self.moving_right = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::Right)) => {
-                self.moving_right = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::A)) => {
-                self.turning_left = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::A)) => {
-                self.turning_left = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::D)) => {
-                self.turning_right = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::D)) => {
-                self.turning_right = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::W)) => {
-                self.moving_forward = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::W)) => {
-                self.moving_forward = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::S)) => {
-                self.moving_backward = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::S)) => {
-                self.moving_backward = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::R)) => {
-                self.turning_up = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::R)) => {
-                self.turning_up = false;
-            },
-            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::F)) => {
-                self.turning_down = true;
-            },
-            &KeyboardInput(Released, _, Some(VirtualKeyCode::F)) => {
-                self.turning_down = false;
-            },
-            _ => {}
+            WindowEvent::CursorMoved { position, .. }  => {
+                let (x, y) = (position.x as i32, position.y as i32);
+                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;
+            }
+            WindowEvent::KeyboardInput { input, .. } => {
+                let pressed = input.state == ElementState::Pressed;
+                let key = match input.virtual_keycode {
+                    Some(key) => key,
+                    None => return,
+                };
+                match key {
+                    VirtualKeyCode::Left => self.moving_left = pressed,
+                    VirtualKeyCode::Right => self.moving_right = pressed,
+                    VirtualKeyCode::Up => self.moving_up = pressed,
+                    VirtualKeyCode::Down => self.moving_down = pressed,
+                    VirtualKeyCode::W => self.moving_forward = pressed,
+                    VirtualKeyCode::S => self.moving_backward = pressed,
+                    VirtualKeyCode::A => self.turning_left = pressed,
+                    VirtualKeyCode::D => self.turning_right = pressed,
+                    VirtualKeyCode::R => self.turning_up = pressed,
+                    VirtualKeyCode::F => self.turning_down = pressed,
+                    _ => (),
+                }
+            },
+            _ => (),
         }
     }
 }