From 0de4b3ccbe2e980a82d9f59aa5b2e492340cbffd Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Fri, 3 Oct 2025 15:07:14 +0200 Subject: [PATCH] tilting when moving --- gloom-rs/src/draw.rs | 37 ++++++++++++++++++++++++++++++++++--- gloom-rs/src/main.rs | 15 ++++++++------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/gloom-rs/src/draw.rs b/gloom-rs/src/draw.rs index feb7188..2cd870d 100644 --- a/gloom-rs/src/draw.rs +++ b/gloom-rs/src/draw.rs @@ -59,12 +59,14 @@ pub enum Nodes { } pub struct PlayerHelicopter { - node_index: usize + node_index: usize, + pub acceleration: glm::Vec3, + pub velocity: glm::Vec3 } impl PlayerHelicopter { pub fn new(node_index: usize) -> Self { - Self { node_index } + Self { node_index, acceleration: glm::zero(), velocity: glm::zero() } } // pub fn get_node<'a>(&self, world: &'a World) -> &'a ManuallyDrop>> { @@ -178,7 +180,36 @@ impl World { return nodes; } - pub fn update(&mut self, elapsed: f32, shader: &Shader) { + pub fn update(&mut self, elapsed: f32, delta_time: f32, shader: &Shader) { + // update player velocity + if self.player.acceleration.norm_squared() > 0.0 { + self.player.velocity += self.player.acceleration * delta_time; + } + + let drag_coefficient = 0.4f32; + self.player.velocity *= drag_coefficient.powf(delta_time); + + let velocity = self.player.velocity; + self.get_player_node_mut().position += velocity * delta_time; + + let min_velocity_threshold = 0.01; + if self.player.velocity.norm() < min_velocity_threshold { + self.player.velocity = glm::zero(); + } + + self.player.acceleration = glm::zero(); + + // magic tilt rotation magic + let rotation = self.get_player_node().rotation; + let tilt_factor = 1.0 / 60.0; + + let local_vel_x = -self.player.velocity.x * rotation.y.cos() + self.player.velocity.z * rotation.y.sin(); + let local_vel_z = self.player.velocity.x * rotation.y.sin() + self.player.velocity.z * rotation.y.cos(); + + self.get_player_node_mut().rotation.x = local_vel_z * tilt_factor; + self.get_player_node_mut().rotation.z = -local_vel_x * tilt_factor; + + let rotor_speed = 60.0; // update all helicopter positions diff --git a/gloom-rs/src/main.rs b/gloom-rs/src/main.rs index 9b1d8bb..2f841bf 100644 --- a/gloom-rs/src/main.rs +++ b/gloom-rs/src/main.rs @@ -90,7 +90,7 @@ fn main() { println!("GLSL\t: {}", util::get_gl_string(gl::SHADING_LANGUAGE_VERSION)); } - let mut world = draw::World::new(300.0, glm::perspective( + let mut world = draw::World::new(30.0, glm::perspective( window_aspect_ratio, 120.0f32, 1.0f32, @@ -136,10 +136,11 @@ fn main() { } let camera_speed = 80.0; - let player_move_speed = 60.0; + let player_move_speed = 30.0; let player_turn_speed = 1.0; let player_forward = world.get_player_node().forward(); + let player_up = world.get_player_node().up(); // Handle keyboard input if let Ok(keys) = pressed_keys.lock() { @@ -178,22 +179,22 @@ fn main() { } VirtualKeyCode::W => { - world.get_player_node_mut().position += player_forward * player_move_speed * delta_time; + world.player.acceleration = player_forward * player_move_speed; } VirtualKeyCode::A => { world.get_player_node_mut().rotation.y += player_turn_speed * delta_time; } VirtualKeyCode::S => { - world.get_player_node_mut().position -= player_forward * player_move_speed * delta_time; + world.player.acceleration = -player_forward * player_move_speed; } VirtualKeyCode::D => { world.get_player_node_mut().rotation.y -= player_turn_speed * delta_time; } VirtualKeyCode::Space => { - world.get_player_node_mut().position.y += player_move_speed * delta_time; + world.player.acceleration = player_up * player_move_speed / 2.0; } VirtualKeyCode::LShift => { - world.get_player_node_mut().position.y -= player_move_speed * delta_time; + world.player.acceleration = -player_up * player_move_speed / 2.0; } _ => { } @@ -216,7 +217,7 @@ fn main() { gl::ClearColor(40.0f32 / 256.0f32, 42.0f32 / 256.0f32, 54.0f32 / 256.0f32, 1.0); // night sky gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); - world.update(elapsed, &simple_shader); + world.update(elapsed, delta_time, &simple_shader); // Display the new color buffer on the display context.swap_buffers().unwrap(); // we use "double buffering" to avoid artifacts