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;
}
pub fn update(&mut self, input: &Input, dt: std::time::Duration) {
let dt = dt.as_secs_f32();
// Move forward/backward and left/right
pub fn update(&mut self, input: &mut Input, dt: f32) {
let (yaw_sin, yaw_cos) = self.rot_x.0.sin_cos();
let forward = Vector3::new(yaw_cos, 0.0, yaw_sin).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 += right * (input.amount_right - input.amount_left) * 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);
// Move up/down. Since we don't use roll, we can just
// modify the y coordinate directly.
self.position.y += (input.amount_up - input.amount_down) * input.speed * dt;
self.position.y += (input.amount_up - input.amount_down) * (input.speed * dt);
// Rotate
self.rot_x += Rad(input.rotate_horizontal) * input.sensitivity * dt;
let (dx, dy) = input.mouse_moved;
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;
self.rot_y = Rad(pitch.clamp(-Rad(frac).0, Rad(frac).0));
self.rot_y = Rad(Rad::from(pitch).0.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}};
mod state;
use std::time::Instant;
use state::State;
mod camera;
@ -17,14 +19,13 @@ pub struct Input {
amount_backward: f32,
amount_up: f32,
amount_down: f32,
rotate_horizontal: f32,
rotate_vertical: f32,
mouse_moved: (f32, f32),
speed: f32,
sensitivity: f32,
sens: f32,
}
impl Input {
pub fn new(speed: f32, sensitivity: f32) -> Self {
pub fn new(speed: f32, sens: f32) -> Self {
Self {
amount_left: 0.0,
amount_right: 0.0,
@ -32,10 +33,9 @@ impl Input {
amount_backward: 0.0,
amount_up: 0.0,
amount_down: 0.0,
rotate_horizontal: 0.0,
rotate_vertical: 0.0,
mouse_moved: (0.0, 0.0),
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 {
fn area(size: winit::dpi::PhysicalSize<u32>) -> u32 {
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");
}
*cursor_locked = to;
return to;
}
@ -109,26 +105,40 @@ fn real_main() -> Result<(), &'static str> {
.build(&(event_loop))
.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 input = Input::new(1.0, 0.088 * 31.4);
let mut last_render_time = std::time::Instant::now();
let mut input = Input::new(1.0, 8.8 / 100.0);
let mut timer = std::time::Instant::now();
let mut total_elapsed = 0.0;
let mut timer = Instant::now();
let mut frames = 0;
let mut prev_render = Instant::now();
event_loop.run(move |event, _, flow| {
*flow = ControlFlow::Poll;
let window = state.window();
*flow = ControlFlow::Poll;
match event {
Event::Event::WindowEvent { window_id, event } if window_id == window.id() => match event {
WindowEvent::MouseInput { state, button, .. } => {
if button == MouseButton::Left && state == ElementState::Pressed && !fullscreen {
fullscreen = set_fullscreen(true, &(window));
if button == MouseButton::Left && state == ElementState::Pressed {
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 => {
*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 => {
fullscreen = set_fullscreen(false, &(window));
fullscreen = set_fullscreen(!fullscreen, &(window), &mut(cursor_locked));
}
_ => input.process_keyboard(key, state),
}
@ -158,36 +168,46 @@ fn real_main() -> Result<(), &'static str> {
}
Event::Event::DeviceEvent {
event: Event::DeviceEvent::MouseMotion { delta, }, ..
} if fullscreen => {
input.process_mouse(delta);
} if cursor_locked => {
input.mouse_moved.0 += delta.0 as f32;
input.mouse_moved.1 += delta.1 as f32;
}
Event::Event::MainEventsCleared => {
let now = std::time::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(&(input), dt);
input.rotate_horizontal = 0.0;
input.rotate_vertical = 0.0;
let mut elapsed = prev_render.elapsed().as_secs_f32();
total_elapsed += elapsed;
prev_render = Instant::now();
const TIMESTEP: f32 = 1.0 / 60.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() {
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(e) => eprintln!("{:?}", e),
_ => (),
_ => ()
};
frames += 1;
let now = std::time::Instant::now();
let time = now.duration_since(timer).as_millis();
let time = timer.elapsed().as_millis();
if time > 1000 {
timer = now;
println!("frames in the past {time}ms: {:?}", frames);
timer = Instant::now();
println!("frames in the past {time}ms: {:?}. {total_elapsed}", frames);
frames = 0;
total_elapsed = 0.0;
}
}
_ => (),
}
_ => (),
};
return;

@ -1,8 +1,5 @@
use std::time::Duration;
use cgmath::Deg;
use winit::window::Window;
use crate::Input;
use wgpu::{util::DeviceExt};
use crate::{Camera, camera::CameraUniform};
@ -19,7 +16,7 @@ pub struct State {
vertex_buffer: wgpu::Buffer,
camera: Camera,
pub camera: Camera,
camera_uniform: CameraUniform,
camera_bind_group: wgpu::BindGroup,
}
@ -72,7 +69,7 @@ impl State {
.ok_or("no srgb surface")?,
width: size.width,
height: size.height,
present_mode: caps.present_modes[0],
present_mode: wgpu::PresentMode::AutoNoVsync, // caps.present_modes[0],
alpha_mode: caps.alpha_modes[0],
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 {
entries: &[
@ -210,8 +207,7 @@ impl State {
self.camera.reconfigure(new_size);
}
pub fn update(&mut self, input: &Input, dt: Duration) {
self.camera.update(input, dt);
pub fn update(&mut self) {
self.camera_uniform.set_view_projection_matrix(&(self.queue), &(self.camera));
}