diff --git a/src/bin/wireframe/main.rs b/src/bin/wireframe/main.rs index cc4591c..8688bbd 100644 --- a/src/bin/wireframe/main.rs +++ b/src/bin/wireframe/main.rs @@ -1,4 +1,4 @@ -use std::{collections::HashSet, time::Instant}; +use std::time::Instant; use glam::{mat4, vec2, vec3, vec4, Mat4, Vec3}; use glium::{ @@ -11,7 +11,6 @@ use glium::{ DrawParameters, Program, Surface, VertexBuffer, }; use winit::{ - event::ElementState, event_loop::EventLoop, keyboard::{KeyCode, PhysicalKey}, }; @@ -102,6 +101,42 @@ mod camctl { } } +mod keyctl { + use std::{collections::HashSet, iter::Sum}; + use winit::{event::ElementState, keyboard::PhysicalKey}; + + pub struct Keyboard { + pressed: HashSet, + } + + impl Keyboard { + pub fn new() -> Self { + Keyboard { + pressed: Default::default(), + } + } + + pub fn is_pressed(&self, key: PhysicalKey) -> bool { + self.pressed.contains(&key) + } + + pub fn set_key_state(&mut self, key: PhysicalKey, state: ElementState) { + match state { + ElementState::Pressed => self.pressed.insert(key), + ElementState::Released => self.pressed.remove(&key), + }; + } + + pub fn control(&self, keymap: &[(PhysicalKey, T)]) -> T { + keymap + .iter() + .copied() + .filter_map(|(key, ctl)| self.is_pressed(key).then_some(ctl)) + .sum() + } + } +} + static KEYS_MOVE: &'static [(PhysicalKey, Vec3)] = &[ (PhysicalKey::Code(KeyCode::KeyW), vec3(1., 0., 0.)), (PhysicalKey::Code(KeyCode::KeyS), vec3(-1., 0., 0.)), @@ -128,14 +163,13 @@ fn main() { .with_title("Refraction: Wireframe") .build(&event_loop); - let mut keys_pressed = HashSet::::new(); - let vs_src = include_str!("ray.v.glsl"); let fs_src = include_str!("ray.f.glsl"); let program = Program::from_source(&display, vs_src, fs_src, None).unwrap(); let scene = prepare_scene(&display); + let mut kbd = keyctl::Keyboard::new(); let mut cam = camctl::CameraLocation::new(); let mut t1 = Instant::now(); @@ -150,16 +184,8 @@ fn main() { t1 = t2; dt.as_secs_f32() }; - let v: Vec3 = KEYS_MOVE - .iter() - .filter_map(|(key, dir)| keys_pressed.contains(key).then_some(dir)) - .sum(); - let vroll: Vec3 = KEYS_ROTATE - .iter() - .filter_map(|(key, dir)| keys_pressed.contains(key).then_some(dir)) - .sum(); - cam.move_rel(100. * dt * v); - cam.rotate_rel_ypr(2. * dt * vroll); + cam.move_rel(100. * dt * kbd.control(&KEYS_MOVE)); + cam.rotate_rel_ypr(2. * dt * kbd.control(&KEYS_ROTATE)); let size = window.inner_size(); let size = vec2(size.width as f32, size.height as f32).normalize() @@ -212,10 +238,7 @@ fn main() { event, is_synthetic: _, } => { - match event.state { - ElementState::Pressed => keys_pressed.insert(event.physical_key), - ElementState::Released => keys_pressed.remove(&event.physical_key), - }; + kbd.set_key_state(event.physical_key, event.state); } WindowEvent::Resized(window_size) => {