Encapsulate keyboard handling
This commit is contained in:
parent
69e711811b
commit
df2134a8a5
|
|
@ -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<PhysicalKey>,
|
||||
}
|
||||
|
||||
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<T: Copy + Sum>(&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::<PhysicalKey>::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) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user