am i a fucking genius, or what?
This commit is contained in:
parent
8bc0ea9880
commit
bfd5914b6b
@ -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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
98
src/main.rs
98
src/main.rs
@ -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;
|
||||||
|
12
src/state.rs
12
src/state.rs
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user