Shorten glutin symbols in camera.
[mandelwow.git] / support / camera.rs
1 extern crate glutin;
2
3 use glutin::ElementState::{Pressed, Released};
4 use glutin::Event::KeyboardInput;
5 use glutin::VirtualKeyCode;
6 use support::vec3::Vec3;
7 use support::vec3::norm;
8
9 use std::f32;
10
11 //use glutin::Event;
12 //use VirtualKeyCode;
13
14 #[derive(Default)]
15 pub struct CameraState {
16     aspect_ratio: f32,
17     pos: Vec3,
18     dir: Vec3,
19
20     moving_up: bool,
21     moving_left: bool,
22     moving_down: bool,
23     moving_right: bool,
24     moving_forward: bool,
25     moving_backward: bool,
26     turning_up: bool,
27     turning_left: bool,
28     turning_down: bool,
29     turning_right: bool,
30 }
31
32 impl CameraState {
33     pub fn new() -> CameraState {
34         CameraState {
35             aspect_ratio: 1024.0 / 768.0,
36             pos: Vec3(0.0, 0.0, 0.0),
37             dir: Vec3(0.0, 0.0, -1.0),
38             .. Default::default()
39         }
40     }
41
42     pub fn set_pos(&mut self, pos: Vec3) {
43         self.pos = pos;
44     }
45
46     pub fn get_pos(&self) -> Vec3 {
47         self.pos
48     }
49
50     pub fn set_dir(&mut self, dir: Vec3) {
51         self.dir = dir;
52     }
53
54     pub fn get_perspective(&self) -> [[f32; 4]; 4] {
55         let fov: f32 = 3.141592 / 2.0;
56         let zfar = 1024.0;
57         let znear = 0.1;
58
59         let f = 1.0 / (fov / 2.0).tan();
60
61         // note: remember that this is column-major, so the lines of code are actually columns
62         [
63             [f / self.aspect_ratio,    0.0,              0.0              ,   0.0],
64             [         0.0         ,     f ,              0.0              ,   0.0],
65             [         0.0         ,    0.0,  (zfar+znear)/(zfar-znear)    ,   1.0],
66             [         0.0         ,    0.0, -(2.0*zfar*znear)/(zfar-znear),   0.0],
67         ]
68     }
69
70     pub fn get_view(&self) -> [[f32; 4]; 4] {
71         let f = norm(&self.dir);
72
73         let up = Vec3(0.0, 1.0, 0.0);
74
75         let s = Vec3(f.1 * up.2 - f.2 * up.1,
76                      f.2 * up.0 - f.0 * up.2,
77                      f.0 * up.1 - f.1 * up.0);
78         let sn = norm(&s);
79
80         let u = (sn.1 * f.2 - sn.2 * f.1,
81                  sn.2 * f.0 - sn.0 * f.2,
82                  sn.0 * f.1 - sn.1 * f.0);
83
84         let p = (-self.pos.0 * s.0 - self.pos.1 * s.1 - self.pos.2 * s.2,
85                  -self.pos.0 * u.0 - self.pos.1 * u.1 - self.pos.2 * u.2,
86                  -self.pos.0 * f.0 - self.pos.1 * f.1 - self.pos.2 * f.2);
87
88         // note: remember that this is column-major, so the lines of code are actually columns
89         [
90             [sn.0, u.0, f.0, 0.0],
91             [sn.1, u.1, f.1, 0.0],
92             [sn.2, u.2, f.2, 0.0],
93             [p.0,  p.1, p.2, 1.0],
94         ]
95     }
96
97     pub fn update(&mut self) {
98         let f = norm(&self.dir);
99
100         let up = Vec3(0.0, 1.0, 0.0);
101
102         let s = Vec3(f.1 * up.2 - f.2 * up.1,
103                      f.2 * up.0 - f.0 * up.2,
104                      f.0 * up.1 - f.1 * up.0);
105
106         let s = norm(&s);
107
108         let u = Vec3(s.1 * f.2 - s.2 * f.1,
109                      s.2 * f.0 - s.0 * f.2,
110                      s.0 * f.1 - s.1 * f.0);
111
112         if self.moving_up {
113             self.pos += u * 0.01;
114         }
115         if self.moving_left {
116             self.pos.0 -= s.0 * 0.01;
117             self.pos.1 -= s.1 * 0.01;
118             self.pos.2 -= s.2 * 0.01;
119         }
120         if self.moving_down {
121             self.pos.0 -= u.0 * 0.01;
122             self.pos.1 -= u.1 * 0.01;
123             self.pos.2 -= u.2 * 0.01;
124         }
125         if self.moving_right {
126             self.pos += s * 0.01;
127         }
128         if self.moving_forward {
129             self.pos += f * 0.01;
130         }
131         if self.moving_backward {
132             self.pos.0 -= f.0 * 0.01;
133             self.pos.1 -= f.1 * 0.01;
134             self.pos.2 -= f.2 * 0.01;
135         }
136         if self.turning_left {
137             let a: f32 = 0.05;
138             self.dir = Vec3(f.0 * a.cos() + f.2 * a.sin(), f.1, - f.0 * a.sin() + f.2 * a.cos());
139         }
140         if self.turning_right {
141             let a: f32 = -0.05;
142             self.dir = Vec3(f.0 * a.cos() + f.2 * a.sin(), f.1, - f.0 * a.sin() + f.2 * a.cos());
143         }
144         if self.turning_up {
145             let a: f32 = -0.05;
146             self.dir = Vec3(f.0, f.1 * a.cos() - f.2 * a.sin(), f.1 * a.sin() + f.2 * a.cos());
147         }
148         if self.turning_down {
149             let a: f32 = 0.05;
150             self.dir = Vec3(f.0, f.1 * a.cos() - f.2 * a.sin(), f.1 * a.sin() + f.2 * a.cos());
151         }
152         //println!("camera_pos = {:?}", self.pos);
153         //println!("camera_dir = {:?}", self.dir);
154     }
155
156     pub fn process_input(&mut self, event: &glutin::Event) {
157         match event {
158             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Up)) => {
159                 self.moving_up = true;
160             },
161             &KeyboardInput(Released, _, Some(VirtualKeyCode::Up)) => {
162                 self.moving_up = false;
163             },
164             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Down)) => {
165                 self.moving_down = true;
166             },
167             &KeyboardInput(Released, _, Some(VirtualKeyCode::Down)) => {
168                 self.moving_down = false;
169             },
170             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Left)) => {
171                 self.moving_left = true;
172             },
173             &KeyboardInput(Released, _, Some(VirtualKeyCode::Left)) => {
174                 self.moving_left = false;
175             },
176             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Right)) => {
177                 self.moving_right = true;
178             },
179             &KeyboardInput(Released, _, Some(VirtualKeyCode::Right)) => {
180                 self.moving_right = false;
181             },
182             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::A)) => {
183                 self.turning_left = true;
184             },
185             &KeyboardInput(Released, _, Some(VirtualKeyCode::A)) => {
186                 self.turning_left = false;
187             },
188             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::D)) => {
189                 self.turning_right = true;
190             },
191             &KeyboardInput(Released, _, Some(VirtualKeyCode::D)) => {
192                 self.turning_right = false;
193             },
194             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::W)) => {
195                 self.moving_forward = true;
196             },
197             &KeyboardInput(Released, _, Some(VirtualKeyCode::W)) => {
198                 self.moving_forward = false;
199             },
200             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::S)) => {
201                 self.moving_backward = true;
202             },
203             &KeyboardInput(Released, _, Some(VirtualKeyCode::S)) => {
204                 self.moving_backward = false;
205             },
206             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::R)) => {
207                 self.turning_up = true;
208             },
209             &KeyboardInput(Released, _, Some(VirtualKeyCode::R)) => {
210                 self.turning_up = false;
211             },
212             &KeyboardInput(Pressed, _, Some(VirtualKeyCode::F)) => {
213                 self.turning_down = true;
214             },
215             &KeyboardInput(Released, _, Some(VirtualKeyCode::F)) => {
216                 self.turning_down = false;
217             },
218             _ => {}
219         }
220     }
221 }