am i a fucking genius, or what?

This commit is contained in:
aiden 2023-05-15 09:19:56 +01:00
parent 8bc0ea9880
commit bfd5914b6b
Signed by: aiden
GPG Key ID: EFA9C74AEBF806E0
3 changed files with 74 additions and 61 deletions

@ -44,27 +44,24 @@ impl Camera {
self.aspect = dimensions.width as f32 / dimensions.height as f32; self.aspect = dimensions.width as f32 / dimensions.height as f32;
} }
pub fn update(&mut self, input: &Input, dt: std::time::Duration) { pub fn update(&mut self, input: &mut Input, dt: f32) {
let dt = dt.as_secs_f32();
// Move forward/backward and left/right
let (yaw_sin, yaw_cos) = self.rot_x.0.sin_cos(); let (yaw_sin, yaw_cos) = self.rot_x.0.sin_cos();
let forward = Vector3::new(yaw_cos, 0.0, yaw_sin).normalize(); let forward = Vector3::new(yaw_cos, 0.0, yaw_sin).normalize();
let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize(); let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize();
self.position += forward * (input.amount_forward - input.amount_backward) * input.speed * dt; self.position += forward * (input.amount_forward - input.amount_backward) * (input.speed * dt);
self.position += right * (input.amount_right - input.amount_left) * input.speed * dt; self.position += right * (input.amount_right - input.amount_left) * (input.speed * dt);
// Move up/down. Since we don't use roll, we can just self.position.y += (input.amount_up - input.amount_down) * (input.speed * dt);
// modify the y coordinate directly.
self.position.y += (input.amount_up - input.amount_down) * input.speed * dt;
// Rotate let (dx, dy) = input.mouse_moved;
self.rot_x += Rad(input.rotate_horizontal) * input.sensitivity * dt; input.mouse_moved = (0.0, 0.0);
let pitch = (self.rot_y + Rad(-input.rotate_vertical) * input.sensitivity * dt).0; let dt = 1.0 / (1920.0 / 360.0);
self.rot_x += Deg(dx * input.sens * dt).into();
let pitch = Deg::from(self.rot_y) + Deg(-dy * input.sens * dt);
let frac = std::f32::consts::FRAC_PI_2 - 0.0001; let frac = std::f32::consts::FRAC_PI_2 - 0.0001;
self.rot_y = Rad(Rad::from(pitch).0.clamp(-Rad(frac).0, Rad(frac).0));
self.rot_y = Rad(pitch.clamp(-Rad(frac).0, Rad(frac).0));
} }
} }

@ -3,6 +3,8 @@
use {winit::{event as Event, event_loop::{ControlFlow, EventLoop}, window::WindowBuilder}, std::{cmp::Ordering, process::ExitCode}}; use {winit::{event as Event, event_loop::{ControlFlow, EventLoop}, window::WindowBuilder}, std::{cmp::Ordering, process::ExitCode}};
mod state; mod state;
use std::time::Instant;
use state::State; use state::State;
mod camera; mod camera;
@ -17,14 +19,13 @@ pub struct Input {
amount_backward: f32, amount_backward: f32,
amount_up: f32, amount_up: f32,
amount_down: f32, amount_down: f32,
rotate_horizontal: f32, mouse_moved: (f32, f32),
rotate_vertical: f32,
speed: f32, speed: f32,
sensitivity: f32, sens: f32,
} }
impl Input { impl Input {
pub fn new(speed: f32, sensitivity: f32) -> Self { pub fn new(speed: f32, sens: f32) -> Self {
Self { Self {
amount_left: 0.0, amount_left: 0.0,
amount_right: 0.0, amount_right: 0.0,
@ -32,10 +33,9 @@ impl Input {
amount_backward: 0.0, amount_backward: 0.0,
amount_up: 0.0, amount_up: 0.0,
amount_down: 0.0, amount_down: 0.0,
rotate_horizontal: 0.0, mouse_moved: (0.0, 0.0),
rotate_vertical: 0.0,
speed, speed,
sensitivity, sens,
} }
} }
@ -63,14 +63,9 @@ impl Input {
_ => () _ => ()
}; };
} }
pub fn process_mouse(&mut self, (dx, dy): (f64, f64)) {
self.rotate_horizontal = dx as f32;
self.rotate_vertical = dy as f32;
}
} }
fn set_fullscreen(to: bool, window: &Window) -> bool { fn set_fullscreen(to: bool, window: &Window, cursor_locked: &mut bool) -> bool {
if to { if to {
fn area(size: winit::dpi::PhysicalSize<u32>) -> u32 { fn area(size: winit::dpi::PhysicalSize<u32>) -> u32 {
size.width * size.height size.width * size.height
@ -99,6 +94,7 @@ fn set_fullscreen(to: bool, window: &Window) -> bool {
window.set_cursor_grab(winit::window::CursorGrabMode::None).expect("failed to unlock cursor"); window.set_cursor_grab(winit::window::CursorGrabMode::None).expect("failed to unlock cursor");
} }
*cursor_locked = to;
return to; return to;
} }
@ -109,26 +105,40 @@ fn real_main() -> Result<(), &'static str> {
.build(&(event_loop)) .build(&(event_loop))
.map_err(|_| "failed to create window")?; .map_err(|_| "failed to create window")?;
let mut fullscreen = set_fullscreen(false, &(window)); let mut cursor_locked = false;
let mut fullscreen = set_fullscreen(false, &(window), &mut(cursor_locked));
let mut state = State::new(window)?; let mut state = State::new(window)?;
let mut input = Input::new(1.0, 0.088 * 31.4); let mut input = Input::new(1.0, 8.8 / 100.0);
let mut last_render_time = std::time::Instant::now();
let mut timer = std::time::Instant::now(); let mut total_elapsed = 0.0;
let mut timer = Instant::now();
let mut frames = 0; let mut frames = 0;
let mut prev_render = Instant::now();
event_loop.run(move |event, _, flow| { event_loop.run(move |event, _, flow| {
*flow = ControlFlow::Poll;
let window = state.window(); let window = state.window();
*flow = ControlFlow::Poll;
match event { match event {
Event::Event::WindowEvent { window_id, event } if window_id == window.id() => match event { Event::Event::WindowEvent { window_id, event } if window_id == window.id() => match event {
WindowEvent::MouseInput { state, button, .. } => { WindowEvent::MouseInput { state, button, .. } => {
if button == MouseButton::Left && state == ElementState::Pressed && !fullscreen { if button == MouseButton::Left && state == ElementState::Pressed {
fullscreen = set_fullscreen(true, &(window)); if !fullscreen {
fullscreen = set_fullscreen(true, &(window), &mut(cursor_locked));
} else if !cursor_locked {
window.set_cursor_grab(winit::window::CursorGrabMode::Confined).expect("failed to lock cursor");
window.set_cursor_visible(false);
cursor_locked = true;
}
} }
} }
WindowEvent::CursorLeft { .. } if fullscreen => {
window.set_cursor_grab(winit::window::CursorGrabMode::None).expect("failed to unlock cursor");
window.set_cursor_visible(true);
cursor_locked = false;
}
WindowEvent::CloseRequested => { WindowEvent::CloseRequested => {
*flow = ControlFlow::Exit; *flow = ControlFlow::Exit;
} }
@ -147,9 +157,9 @@ fn real_main() -> Result<(), &'static str> {
.. ..
}, },
.. ..
} if fullscreen => match key { } => match key {
VirtualKeyCode::Escape if state == ElementState::Pressed => { VirtualKeyCode::Escape if state == ElementState::Pressed => {
fullscreen = set_fullscreen(false, &(window)); fullscreen = set_fullscreen(!fullscreen, &(window), &mut(cursor_locked));
} }
_ => input.process_keyboard(key, state), _ => input.process_keyboard(key, state),
} }
@ -158,36 +168,46 @@ fn real_main() -> Result<(), &'static str> {
} }
Event::Event::DeviceEvent { Event::Event::DeviceEvent {
event: Event::DeviceEvent::MouseMotion { delta, }, .. event: Event::DeviceEvent::MouseMotion { delta, }, ..
} if fullscreen => { } if cursor_locked => {
input.process_mouse(delta); input.mouse_moved.0 += delta.0 as f32;
input.mouse_moved.1 += delta.1 as f32;
} }
Event::Event::MainEventsCleared => { Event::Event::MainEventsCleared => {
let now = std::time::Instant::now(); let mut elapsed = prev_render.elapsed().as_secs_f32();
let dt = now - last_render_time; total_elapsed += elapsed;
last_render_time = now; prev_render = Instant::now();
state.update(&(input), dt);
input.rotate_horizontal = 0.0; const TIMESTEP: f32 = 1.0 / 60.0;
input.rotate_vertical = 0.0;
while elapsed >= TIMESTEP {
state.camera.update(&mut(input), TIMESTEP);
elapsed -= TIMESTEP;
}
state.camera.update(&mut(input), elapsed);
state.window().request_redraw();
}
Event::Event::RedrawRequested(_) => {
state.update();
match state.render() { match state.render() {
Err(wgpu::SurfaceError::Lost) => state.reconfigure(None), Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.reconfigure(None),
Err(wgpu::SurfaceError::OutOfMemory) => *flow = ControlFlow::ExitWithCode(1), Err(wgpu::SurfaceError::OutOfMemory) => *flow = ControlFlow::ExitWithCode(1),
Err(e) => eprintln!("{:?}", e), Err(e) => eprintln!("{:?}", e),
_ => (), _ => ()
}; };
frames += 1; frames += 1;
let time = timer.elapsed().as_millis();
let now = std::time::Instant::now();
let time = now.duration_since(timer).as_millis();
if time > 1000 { if time > 1000 {
timer = now; timer = Instant::now();
println!("frames in the past {time}ms: {:?}", frames); println!("frames in the past {time}ms: {:?}. {total_elapsed}", frames);
frames = 0; frames = 0;
total_elapsed = 0.0;
} }
} }
_ => (), _ => (),
}; };
return; return;

@ -1,8 +1,5 @@
use std::time::Duration;
use cgmath::Deg; use cgmath::Deg;
use winit::window::Window; use winit::window::Window;
use crate::Input;
use wgpu::{util::DeviceExt}; use wgpu::{util::DeviceExt};
use crate::{Camera, camera::CameraUniform}; use crate::{Camera, camera::CameraUniform};
@ -19,7 +16,7 @@ pub struct State {
vertex_buffer: wgpu::Buffer, vertex_buffer: wgpu::Buffer,
camera: Camera, pub camera: Camera,
camera_uniform: CameraUniform, camera_uniform: CameraUniform,
camera_bind_group: wgpu::BindGroup, camera_bind_group: wgpu::BindGroup,
} }
@ -72,7 +69,7 @@ impl State {
.ok_or("no srgb surface")?, .ok_or("no srgb surface")?,
width: size.width, width: size.width,
height: size.height, height: size.height,
present_mode: caps.present_modes[0], present_mode: wgpu::PresentMode::AutoNoVsync, // caps.present_modes[0],
alpha_mode: caps.alpha_modes[0], alpha_mode: caps.alpha_modes[0],
view_formats: vec![], view_formats: vec![],
} }
@ -97,7 +94,7 @@ impl State {
}) })
); );
let camera = Camera::new(size, (0.25, 1.0, 0.0), Deg(0.0), Deg(0.0)); let camera = Camera::new(size, (0.25, 1.0, 0.0), Deg(0.0), Deg(-90.0));
let camera_bind_group_layout = &(device.create_bind_group_layout(&(wgpu::BindGroupLayoutDescriptor { let camera_bind_group_layout = &(device.create_bind_group_layout(&(wgpu::BindGroupLayoutDescriptor {
entries: &[ entries: &[
@ -210,8 +207,7 @@ impl State {
self.camera.reconfigure(new_size); self.camera.reconfigure(new_size);
} }
pub fn update(&mut self, input: &Input, dt: Duration) { pub fn update(&mut self) {
self.camera.update(input, dt);
self.camera_uniform.set_view_projection_matrix(&(self.queue), &(self.camera)); self.camera_uniform.set_view_projection_matrix(&(self.queue), &(self.camera));
} }