Implement mouse panning and streamline keyboard movement.
[mandelwow.git] / support / camera.rs
index 1b56d7d9d5b3f9e91d61e5e1558ca8bc690d69fb..fe1398d874ee3842a0006ee668ddde8f2002c780 100644 (file)
@@ -1,43 +1,15 @@
 extern crate glutin;
 
+use glutin::ElementState::{Pressed, Released};
+use glutin::Event::{KeyboardInput, MouseMoved};
+use glutin::VirtualKeyCode;
+use support::vec3::Vec3;
+use support::vec3::norm;
+
 use std::f32;
-use std::ops::Add;
-use std::ops::AddAssign;
-use std::ops::Sub;
-use std::ops::Mul;
 
 //use glutin::Event;
-//use glutin::VirtualKeyCode;
-
-#[derive(Default, PartialEq, Debug, Clone, Copy)]
-pub struct Vec3 (f32, f32, f32);
-
-impl Add for Vec3 {
-    type Output = Vec3;
-    fn add(self, other: Vec3) -> Vec3 {
-        Vec3(self.0 + other.0, self.1 + other.1, self.2 + other.2)
-    }
-}
-
-impl AddAssign for Vec3 {
-    fn add_assign(&mut self, other: Vec3) {
-        *self = Vec3(self.0 + other.0, self.1 + other.1, self.2 + other.2)
-    }
-}
-
-impl Sub for Vec3 {
-    type Output = Vec3;
-    fn sub(self, other: Vec3) -> Vec3 {
-        Vec3(self.0 - other.0, self.1 - other.1, self.2 - other.2)
-    }
-}
-
-impl Mul<f32> for Vec3 {
-    type Output = Vec3;
-    fn mul(self, f: f32) -> Vec3 {
-        Vec3(self.0 * f, self.1 * f, self.2 * f)
-    }
-}
+//use VirtualKeyCode;
 
 #[derive(Default)]
 pub struct CameraState {
@@ -55,11 +27,11 @@ pub struct CameraState {
     turning_left: bool,
     turning_down: bool,
     turning_right: bool,
-}
 
-fn norm(v: &Vec3) -> Vec3 {
-    let len = (v.0 * v.0 + v.1 * v.1 + v.2 * v.2).sqrt();
-    Vec3(v.0 / len, v.1 / len, v.2 / len)
+    mouse_x: i32,
+    mouse_y: i32,
+    rel_x: i32,
+    rel_y: i32,
 }
 
 impl CameraState {
@@ -67,7 +39,7 @@ impl CameraState {
         CameraState {
             aspect_ratio: 1024.0 / 768.0,
             pos: Vec3(0.0, 0.0, 0.0),
-            dir: Vec3(0.0, 0.0, 1.0),
+            dir: Vec3(0.0, 0.0, -1.0),
             .. Default::default()
         }
     }
@@ -76,6 +48,10 @@ impl CameraState {
         self.pos = pos;
     }
 
+    pub fn get_pos(&self) -> Vec3 {
+        self.pos
+    }
+
     pub fn set_dir(&mut self, dir: Vec3) {
         self.dir = dir;
     }
@@ -96,7 +72,6 @@ impl CameraState {
         ]
     }
 
-
     pub fn get_view(&self) -> [[f32; 4]; 4] {
         let f = norm(&self.dir);
 
@@ -139,110 +114,111 @@ 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.01;
+
         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 -= 2; }
+        if self.turning_right { self.rel_x += 2; }
+        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 {
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Up)) => {
+            &MouseMoved(x, 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;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Up)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::Up)) => {
                 self.moving_up = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Down)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Down)) => {
                 self.moving_down = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Down)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::Down)) => {
                 self.moving_down = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Left)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Left)) => {
                 self.moving_left = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Left)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::Left)) => {
                 self.moving_left = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Right)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Right)) => {
                 self.moving_right = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Right)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::Right)) => {
                 self.moving_right = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::A)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::A)) => {
                 self.turning_left = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::A)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::A)) => {
                 self.turning_left = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::D)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::D)) => {
                 self.turning_right = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::D)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::D)) => {
                 self.turning_right = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::W)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::W)) => {
                 self.moving_forward = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::W)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::W)) => {
                 self.moving_forward = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::S)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::S)) => {
                 self.moving_backward = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::S)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::S)) => {
                 self.moving_backward = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::R)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::R)) => {
                 self.turning_up = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::R)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::R)) => {
                 self.turning_up = false;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::F)) => {
+            &KeyboardInput(Pressed, _, Some(VirtualKeyCode::F)) => {
                 self.turning_down = true;
             },
-            &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::F)) => {
+            &KeyboardInput(Released, _, Some(VirtualKeyCode::F)) => {
                 self.turning_down = false;
             },
             _ => {}