From fd62f3e89d48ddd347cc15750e87ec908ea3f859 Mon Sep 17 00:00:00 2001 From: Andrew Pritchard Date: Thu, 5 Sep 2019 18:24:22 +0800 Subject: [PATCH] Revert "Exponential interpolation for linear damping" This reverts commit 94b9f50efa502ea872c71dea62db71b19be60069. --- common/src/sys/phys.rs | 65 +++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index d816d21871..42ebc978c5 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -11,14 +11,8 @@ use { }; const GRAVITY: f32 = 9.81 * 4.0; - -// Friction values used for linear damping. They are unitless quantities. The -// value of these quantities must be between zero and one. They represent the -// amount an object will slow down within 1/60th of a second. Eg. if the frction -// is 0.01, and the speed is 1.0, then after 1/60th of a second the speed will -// be 0.99. after 1 second the speed will be 0.54, which is 0.99 ^ 60. -const FRIC_GROUND: f32 = 0.125; -const FRIC_AIR: f32 = 0.0125; +const FRIC_GROUND: f32 = 0.15; +const FRIC_AIR: f32 = 0.015; // Integrates forces, calculates the new velocity based off of the old velocity // dt = delta time @@ -26,16 +20,10 @@ const FRIC_AIR: f32 = 0.0125; // damp = linear damping // Friction is a type of damping. fn integrate_forces(dt: f32, mut lv: Vec3, grav: f32, damp: f32) -> Vec3 { - // this is not linear damping, because it is proportional to the original - // velocity this "linear" damping in in fact, quite exponential. and thus - // must be interpolated accordingly - let linear_damp = if damp < 1.0 { - (1.0 - damp).powf(dt * 60.0) - } else { - 0.0 - }; - lv.z = (lv.z - grav * dt).max(-50.0); + + let linear_damp = (1.0 - dt * damp).max(0.0); + lv * linear_damp } @@ -73,7 +61,7 @@ impl<'a> System<'a> for Sys { let mut event_emitter = event_bus.emitter(); // Apply movement inputs - for (entity, scale, _b, mut pos, mut vel, _ori) in ( + for (entity, scale, b, mut pos, mut vel, mut ori) in ( &entities, scales.maybe(), &bodies, @@ -86,6 +74,16 @@ impl<'a> System<'a> for Sys { let mut physics_state = physics_states.get(entity).cloned().unwrap_or_default(); let scale = scale.map(|s| s.0).unwrap_or(1.0); + // Integrate forces + // Friction is assumed to be a constant dependent on location + let friction = 50.0 + * if physics_state.on_ground { + FRIC_GROUND + } else { + FRIC_AIR + }; + vel.0 = integrate_forces(dt.0, vel.0, GRAVITY, friction); + // Basic collision with terrain let player_rad = 0.3 * scale; // half-width of the player's AABB let player_height = 1.5 * scale; @@ -99,27 +97,6 @@ impl<'a> System<'a> for Sys { .flatten() .flatten(); - let old_vel = vel.clone(); - // Integrate forces - // Friction is assumed to be a constant dependent on location - let friction = if physics_state.on_ground { - FRIC_GROUND - } else { - FRIC_AIR - }; - vel.0 = integrate_forces(dt.0, vel.0, GRAVITY, friction); - - // Don't move if we're not in a loaded chunk - let pos_delta = if terrain - .get_key(terrain.pos_key(pos.0.map(|e| e.floor() as i32))) - .is_some() - { - // this is an approximation that allows - (vel.0 + old_vel.0 * 4.0) * dt.0 * 0.2 - } else { - Vec3::zero() - }; - // Function for determining whether the player at a specific position collides with the ground let collision_with = |pos: Vec3, near_iter| { for (i, j, k) in near_iter { @@ -153,6 +130,16 @@ impl<'a> System<'a> for Sys { let mut on_ground = false; let mut attempts = 0; // Don't loop infinitely here + // Don't move if we're not in a loaded chunk + let pos_delta = if terrain + .get_key(terrain.pos_key(pos.0.map(|e| e.floor() as i32))) + .is_some() + { + vel.0 * dt.0 + } else { + Vec3::zero() + }; + // Don't jump too far at once let increments = (pos_delta.map(|e| e.abs()).reduce_partial_max() / 0.3) .ceil()