X-Git-Url: https://codewiz.org/gitweb?p=mandelwow.git;a=blobdiff_plain;f=support%2Fcamera.rs;h=25b1e7292b9fb54b92c0bcdb775e052e9f437074;hp=10ad1f0086d17e396a3f5a6075443f80be39e2ed;hb=HEAD;hpb=b1f47d18bd76c1d1475f992f021e714289f4b79a;ds=sidebyside diff --git a/support/camera.rs b/support/camera.rs index 10ad1f0..25b1e72 100644 --- a/support/camera.rs +++ b/support/camera.rs @@ -1,16 +1,15 @@ -extern crate glutin; - -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 glutin::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, @@ -24,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), + dir: Vec3(0.0, 0.0, -1.0), + mouse_x: -1, + mouse_y: -1, .. Default::default() } } @@ -40,28 +46,31 @@ impl CameraState { self.pos = pos; } + pub fn get_pos(&self) -> Vec3 { + self.pos + } + pub fn set_dir(&mut self, dir: Vec3) { 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 { + 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 { let f = norm(&self.dir); let up = Vec3(0.0, 1.0, 0.0); @@ -80,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) { @@ -103,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 { - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Up)) => { - self.moving_up = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Up)) => { - self.moving_up = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Down)) => { - self.moving_down = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Down)) => { - self.moving_down = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Left)) => { - self.moving_left = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Left)) => { - self.moving_left = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Right)) => { - self.moving_right = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::Right)) => { - self.moving_right = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::A)) => { - self.turning_left = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::A)) => { - self.turning_left = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::D)) => { - self.turning_right = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::D)) => { - self.turning_right = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::W)) => { - self.moving_forward = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::W)) => { - self.moving_forward = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::S)) => { - self.moving_backward = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::S)) => { - self.moving_backward = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::R)) => { - self.turning_up = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::VirtualKeyCode::R)) => { - self.turning_up = false; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::F)) => { - self.turning_down = true; - }, - &glutin::Event::KeyboardInput(glutin::ElementState::Released, _, Some(glutin::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, + _ => (), + } + }, + _ => (), } } }