use super::Camera; use winit::event::*; pub struct CameraController { pub speed: f32, pub is_up_pressed: bool, pub is_down_pressed: bool, pub is_forward_pressed: bool, pub is_backward_pressed: bool, pub is_left_pressed: bool, pub is_right_pressed: bool, } impl CameraController { pub fn New(speed: f32) -> Self { Self { speed, is_up_pressed: false, is_down_pressed: false, is_forward_pressed: false, is_backward_pressed: false, is_left_pressed: false, is_right_pressed: false, } } pub fn ProcessEvents(&mut self, event: &WindowEvent) -> bool { match event { WindowEvent::KeyboardInput { input: KeyboardInput { state, virtual_keycode: Some(keycode), .. }, .. } => { let is_pressed = *state == ElementState::Pressed; match keycode { VirtualKeyCode::Space => { self.is_up_pressed = is_pressed; true } VirtualKeyCode::LShift => { self.is_down_pressed = is_pressed; true } VirtualKeyCode::W | VirtualKeyCode::Up => { self.is_forward_pressed = is_pressed; true } VirtualKeyCode::A | VirtualKeyCode::Left => { self.is_left_pressed = is_pressed; true } VirtualKeyCode::S | VirtualKeyCode::Down => { self.is_backward_pressed = is_pressed; true } VirtualKeyCode::D | VirtualKeyCode::Right => { self.is_right_pressed = is_pressed; true } _ => false, } } _ => false, } } pub fn UpdateCamera(&self, camera: &mut Camera) { use cgmath::InnerSpace; let forward = camera.target - camera.eye; let forward_norm = forward.normalize(); let forward_mag = forward.magnitude(); // Prevents glitching when camera gets too close to the // center of the scene. if self.is_forward_pressed && forward_mag > self.speed { camera.eye += forward_norm * self.speed; } if self.is_backward_pressed { camera.eye -= forward_norm * self.speed; } let right = forward_norm.cross(camera.up); // Redo radius calc in case the up/ down is pressed. let forward = camera.target - camera.eye; let forward_mag = forward.magnitude(); if self.is_right_pressed { // Rescale the distance between the target and eye so // that it doesn't change. The eye therefore still // lies on the circle made by the target and eye. camera.eye = camera.target - (forward + right * self.speed).normalize() * forward_mag; } if self.is_left_pressed { camera.eye = camera.target - (forward - right * self.speed).normalize() * forward_mag; } } }