Compare commits

..

No commits in common. "df2134a8a5d56cb179ef3639f4567fe2eb640cca" and "26b77941596bffb3c396dffb9af9a453b26abb67" have entirely different histories.

View File

@ -1,6 +1,6 @@
use std::time::Instant;
use std::{collections::HashSet, time::Instant};
use glam::{mat4, vec2, vec3, vec4, Mat4, Vec3};
use glam::{mat4, vec2, vec3, vec4, Mat4, Quat, Vec2, Vec3};
use glium::{
backend::{glutin::SimpleWindowBuilder, Facade},
glutin::config::ConfigTemplateBuilder,
@ -11,6 +11,7 @@ use glium::{
DrawParameters, Program, Surface, VertexBuffer,
};
use winit::{
event::ElementState,
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
};
@ -28,6 +29,40 @@ struct Vertex {
}
implement_vertex!(Vertex, position);
struct DragCtl<S> {
state: S,
ctl: Option<(Vec2, S)>,
}
impl<S: Copy> DragCtl<S> {
pub fn new(state: S) -> Self {
Self { state, ctl: None }
}
pub fn state(&self) -> S {
self.state
}
pub fn on_button(&mut self, pos: Vec2, state: ElementState) {
match state {
ElementState::Pressed => {
if self.ctl.is_none() {
self.ctl = Some((pos, self.state));
}
}
ElementState::Released => {
self.ctl = None;
}
}
}
pub fn on_move(&mut self, pos: Vec2, f: impl FnOnce(S, Vec2) -> S) {
if let Some((old_pos, old_state)) = self.ctl {
self.state = f(old_state, pos - old_pos);
}
}
}
struct Wireframe {
color: Vec3,
mode: PrimitiveType,
@ -68,93 +103,6 @@ fn prepare_scene(display: &impl Facade) -> Vec<Wireframe> {
.collect()
}
mod camctl {
use glam::{vec3, Mat4, Quat, Vec3};
pub struct CameraLocation {
pos: Vec3,
rot: Quat,
}
impl CameraLocation {
pub fn new() -> CameraLocation {
let rot = Quat::from_euler(glam::EulerRot::ZYX, std::f32::consts::FRAC_PI_4, 0., 0.);
let pos = rot * vec3(-200., 0., 50.);
CameraLocation { pos, rot }
}
pub fn view_mtx(&self) -> Mat4 {
Mat4::from_quat(self.rot.inverse()) * Mat4::from_translation(-self.pos)
}
pub fn move_rel(&mut self, offset: Vec3) {
self.pos += self.rot * offset;
}
pub fn rotate_rel_ypr(&mut self, ypr: Vec3) {
self.rotate_rel_quat(Quat::from_euler(glam::EulerRot::XYZ, ypr.x, ypr.y, ypr.z));
}
pub fn rotate_rel_quat(&mut self, rot: Quat) {
self.rot *= rot;
}
}
}
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.)),
(PhysicalKey::Code(KeyCode::KeyA), vec3(0., 1., 0.)),
(PhysicalKey::Code(KeyCode::KeyD), vec3(0., -1., 0.)),
(PhysicalKey::Code(KeyCode::Space), vec3(0., 0., 1.)),
(PhysicalKey::Code(KeyCode::ShiftLeft), vec3(0., 0., -1.)),
];
static KEYS_ROTATE: &'static [(PhysicalKey, Vec3)] = &[
(PhysicalKey::Code(KeyCode::Numpad9), vec3(1., 0., 0.)),
(PhysicalKey::Code(KeyCode::Numpad7), vec3(-1., 0., 0.)),
(PhysicalKey::Code(KeyCode::Numpad5), vec3(0., 1., 0.)),
(PhysicalKey::Code(KeyCode::Numpad8), vec3(0., -1., 0.)),
(PhysicalKey::Code(KeyCode::Numpad4), vec3(0., 0., 1.)),
(PhysicalKey::Code(KeyCode::Numpad6), vec3(0., 0., -1.)),
];
fn main() {
let event_loop = EventLoop::builder().build().unwrap();
let cfg = ConfigTemplateBuilder::new().with_multisampling(8);
@ -163,14 +111,19 @@ 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 rot = Quat::from_euler(glam::EulerRot::ZYX, std::f32::consts::FRAC_PI_4, 0., 0.);
let mut cur_pos = vec2(0., 0.);
let mut cam_pos = rot * vec3(-200., 0., 50.);
let mut cam_rot = DragCtl::new(rot);
let mut t1 = Instant::now();
#[allow(deprecated)]
@ -184,8 +137,27 @@ fn main() {
t1 = t2;
dt.as_secs_f32()
};
cam.move_rel(100. * dt * kbd.control(&KEYS_MOVE));
cam.rotate_rel_ypr(2. * dt * kbd.control(&KEYS_ROTATE));
let v: Vec3 = {
let ctl_left = keys_pressed.contains(&PhysicalKey::Code(KeyCode::KeyA));
let ctl_right = keys_pressed.contains(&PhysicalKey::Code(KeyCode::KeyD));
let ctl_fwd = keys_pressed.contains(&PhysicalKey::Code(KeyCode::KeyW));
let ctl_bwd = keys_pressed.contains(&PhysicalKey::Code(KeyCode::KeyS));
let ctl_up = keys_pressed.contains(&PhysicalKey::Code(KeyCode::Space));
let ctl_down =
keys_pressed.contains(&PhysicalKey::Code(KeyCode::ShiftLeft));
[
(ctl_left, vec3(0., 1., 0.)),
(ctl_right, vec3(0., -1., 0.)),
(ctl_fwd, vec3(1., 0., 0.)),
(ctl_bwd, vec3(-1., 0., 0.)),
(ctl_up, vec3(0., 0., 1.)),
(ctl_down, vec3(0., 0., -1.)),
]
.into_iter()
.filter_map(|(ctl, dir)| ctl.then_some(dir))
.sum()
};
cam_pos += 100. * dt * (cam_rot.state() * v);
let size = window.inner_size();
let size = vec2(size.width as f32, size.height as f32).normalize()
@ -198,7 +170,10 @@ fn main() {
vec4(0., 1., 0., 0.),
vec4(0., 0., 0., 1.),
);
let view = my_to_gl * cam.view_mtx();
let view = my_to_gl
* Mat4::from_quat(cam_rot.state().inverse())
* Mat4::from_translation(-cam_pos);
let mut target = display.draw();
target.clear_color(0.0, 0.0, 0.0, 0.0);
@ -233,12 +208,37 @@ fn main() {
target.finish().unwrap();
}
WindowEvent::MouseInput {
device_id: _,
state,
button,
} => match button {
winit::event::MouseButton::Right => cam_rot.on_button(cur_pos, state),
_ => {}
},
WindowEvent::CursorMoved {
device_id: _,
position,
} => {
let size = window.inner_size();
let size = vec2(size.width as f32, size.height as f32);
cur_pos = vec2(position.x as f32, position.y as f32) / size.length();
cam_rot.on_move(cur_pos, |init, off| {
window.request_redraw();
init * Quat::from_euler(glam::EulerRot::ZYX, 2. * off.x, -2. * off.y, 0.)
});
}
WindowEvent::KeyboardInput {
device_id: _,
event,
is_synthetic: _,
} => {
kbd.set_key_state(event.physical_key, event.state);
match event.state {
ElementState::Pressed => keys_pressed.insert(event.physical_key),
ElementState::Released => keys_pressed.remove(&event.physical_key),
};
}
WindowEvent::Resized(window_size) => {