3 use cgmath::{Matrix4, Vector4};
4 use cgmath::conv::array4x4;
5 use glutin::ElementState::{Pressed, Released};
6 use glutin::Event::{KeyboardInput, MouseMoved};
7 use glutin::VirtualKeyCode;
8 use std::f32::consts::PI;
9 use support::vec3::Vec3;
10 use support::vec3::norm;
18 pub struct CameraState {
28 moving_backward: bool,
41 pub fn new() -> CameraState {
43 aspect: 1280.0 / 720.0,
44 pos: Vec3(0.0, 0.0, 0.0),
45 dir: Vec3(0.0, 0.0, -1.0),
52 pub fn set_pos(&mut self, pos: Vec3) {
56 pub fn get_pos(&self) -> Vec3 {
60 pub fn set_dir(&mut self, dir: Vec3) {
64 pub fn get_persp_mat(&self) -> Matrix4<f32> {
65 let fov: f32 = PI / 2.0;
69 let f = 1.0 / (fov / 2.0).tan();
71 // note: remember that this is column-major, so the lines of code are actually columns
73 x: Vector4{ x: f / self.aspect, y: 0.0, z: 0.0, w: 0.0 },
74 y: Vector4{ x: 0.0, y: f, z: 0.0, w: 0.0 },
75 z: Vector4{ x: 0.0, y: 0.0, z: (zfar+znear)/(zfar-znear), w: 1.0 },
76 w: Vector4{ x: 0.0, y: 0.0, z: -(2.0*zfar*znear)/(zfar-znear), w: 0.0 },
80 pub fn get_view_mat(&self) -> Matrix4<f32> {
81 let f = norm(&self.dir);
83 let up = Vec3(0.0, 1.0, 0.0);
85 let s = Vec3(f.1 * up.2 - f.2 * up.1,
86 f.2 * up.0 - f.0 * up.2,
87 f.0 * up.1 - f.1 * up.0);
90 let u = (sn.1 * f.2 - sn.2 * f.1,
91 sn.2 * f.0 - sn.0 * f.2,
92 sn.0 * f.1 - sn.1 * f.0);
94 let p = (-self.pos.0 * s.0 - self.pos.1 * s.1 - self.pos.2 * s.2,
95 -self.pos.0 * u.0 - self.pos.1 * u.1 - self.pos.2 * u.2,
96 -self.pos.0 * f.0 - self.pos.1 * f.1 - self.pos.2 * f.2);
98 // note: remember that this is column-major, so the lines of code are actually columns
100 x: Vector4{ x: sn.0, y: u.0, z: f.0, w: 0.0 },
101 y: Vector4{ x: sn.1, y: u.1, z: f.1, w: 0.0 },
102 z: Vector4{ x: sn.2, y: u.2, z: f.2, w: 0.0 },
103 w: Vector4{ x: p.0, y: p.1, z: p.2, w: 1.0 },
107 pub fn get_perspview(&self) -> [[f32; 4]; 4] {
108 array4x4(self.get_persp_mat() * self.get_view_mat())
111 pub fn get_perspective(&self) -> [[f32; 4]; 4] {
112 array4x4(self.get_persp_mat())
115 pub fn get_view(&self) -> [[f32; 4]; 4] {
116 array4x4(self.get_view_mat())
119 pub fn update(&mut self) {
120 let f = norm(&self.dir);
122 let up = Vec3(0.0, 1.0, 0.0);
124 let s = Vec3(f.1 * up.2 - f.2 * up.1,
125 f.2 * up.0 - f.0 * up.2,
126 f.0 * up.1 - f.1 * up.0);
130 let u = Vec3(s.1 * f.2 - s.2 * f.1,
131 s.2 * f.0 - s.0 * f.2,
132 s.0 * f.1 - s.1 * f.0);
134 let walk_speed = 0.01;
135 let strife_speed = 0.02;
136 let pan_speed = 0.001;
139 self.pos += u * strife_speed;
141 if self.moving_down {
142 self.pos -= u * strife_speed;
144 if self.moving_left {
145 self.pos -= s * strife_speed;
147 if self.moving_right {
148 self.pos += s * strife_speed;
150 if self.moving_forward {
151 self.pos += f * walk_speed;
153 if self.moving_backward {
154 self.pos -= f * walk_speed;
157 if self.turning_left { self.rel_x -= 8; }
158 if self.turning_right { self.rel_x += 8; }
159 if self.turning_up { self.rel_y -= 2; }
160 if self.turning_down { self.rel_y += 2; }
161 let vx = -pan_speed * self.rel_x as f32;
162 let vy = -pan_speed * self.rel_y as f32;
163 self.dir = Vec3(f.0 * vx.cos() + f.2 * vx.sin(),
164 f.1 * vy.cos() - f.2 * vy.sin(),
165 f.1 * vy.sin() - f.0 * vx.sin() + f.2 * vx.cos() * vy.cos());
169 //println!("camera_pos = {:?}", self.pos);
170 //println!("camera_dir = {:?}", self.dir);
173 pub fn process_input(&mut self, event: &glutin::Event) {
175 &MouseMoved(x, y) => {
176 if self.mouse_x == -1 {
177 // Set initial absolute position.
181 self.rel_x += x - self.mouse_x;
182 self.rel_y += y - self.mouse_y;
186 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Up)) => {
187 self.moving_up = true;
189 &KeyboardInput(Released, _, Some(VirtualKeyCode::Up)) => {
190 self.moving_up = false;
192 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Down)) => {
193 self.moving_down = true;
195 &KeyboardInput(Released, _, Some(VirtualKeyCode::Down)) => {
196 self.moving_down = false;
198 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Left)) => {
199 self.moving_left = true;
201 &KeyboardInput(Released, _, Some(VirtualKeyCode::Left)) => {
202 self.moving_left = false;
204 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::Right)) => {
205 self.moving_right = true;
207 &KeyboardInput(Released, _, Some(VirtualKeyCode::Right)) => {
208 self.moving_right = false;
210 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::A)) => {
211 self.turning_left = true;
213 &KeyboardInput(Released, _, Some(VirtualKeyCode::A)) => {
214 self.turning_left = false;
216 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::D)) => {
217 self.turning_right = true;
219 &KeyboardInput(Released, _, Some(VirtualKeyCode::D)) => {
220 self.turning_right = false;
222 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::W)) => {
223 self.moving_forward = true;
225 &KeyboardInput(Released, _, Some(VirtualKeyCode::W)) => {
226 self.moving_forward = false;
228 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::S)) => {
229 self.moving_backward = true;
231 &KeyboardInput(Released, _, Some(VirtualKeyCode::S)) => {
232 self.moving_backward = false;
234 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::R)) => {
235 self.turning_up = true;
237 &KeyboardInput(Released, _, Some(VirtualKeyCode::R)) => {
238 self.turning_up = false;
240 &KeyboardInput(Pressed, _, Some(VirtualKeyCode::F)) => {
241 self.turning_down = true;
243 &KeyboardInput(Released, _, Some(VirtualKeyCode::F)) => {
244 self.turning_down = false;