mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
massivly decrease the effects of bigger tick times on the pos calculatuion by moving the block friction calcuation into the inner iterator
do physics always after character_behavior as this one is saying how the input should be handled
This commit is contained in:
@ -55,6 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Fixed an error where '{amount} Exp' floater did not use existing localizations
|
- Fixed an error where '{amount} Exp' floater did not use existing localizations
|
||||||
- Fix villagers seeing cultists and familiar enemies through objects.
|
- Fix villagers seeing cultists and familiar enemies through objects.
|
||||||
- Menacing agents are now less spammy with their menacing messages
|
- Menacing agents are now less spammy with their menacing messages
|
||||||
|
- Reduced effects of slow/high FPS on physics like player speed by ~50%
|
||||||
|
|
||||||
## [0.12.0] - 2022-02-19
|
## [0.12.0] - 2022-02-19
|
||||||
|
|
||||||
|
@ -27,8 +27,9 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
|||||||
dispatch::<buff::Sys>(dispatch_builder, &[]);
|
dispatch::<buff::Sys>(dispatch_builder, &[]);
|
||||||
dispatch::<stats::Sys>(dispatch_builder, &[&buff::Sys::sys_name()]);
|
dispatch::<stats::Sys>(dispatch_builder, &[&buff::Sys::sys_name()]);
|
||||||
dispatch::<phys::Sys>(dispatch_builder, &[
|
dispatch::<phys::Sys>(dispatch_builder, &[
|
||||||
|
&character_behavior::Sys::sys_name(),
|
||||||
&interpolation::Sys::sys_name(),
|
&interpolation::Sys::sys_name(),
|
||||||
&controller::Sys::sys_name(),
|
//&controller::Sys::sys_name(), provided by character_behavior
|
||||||
&mount::Sys::sys_name(),
|
&mount::Sys::sys_name(),
|
||||||
&stats::Sys::sys_name(),
|
&stats::Sys::sys_name(),
|
||||||
]);
|
]);
|
||||||
|
@ -1428,6 +1428,7 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let z_range = z_min..z_max;
|
let z_range = z_min..z_max;
|
||||||
|
let fric_mod = read.stats.get(entity).map_or(1.0, |s| s.friction_modifier);
|
||||||
|
|
||||||
// Setup values for the loop below
|
// Setup values for the loop below
|
||||||
physics_state.on_ground = None;
|
physics_state.on_ground = None;
|
||||||
@ -1444,11 +1445,13 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
const MAX_INCREMENTS: usize = 100; // The maximum number of collision tests per tick
|
const MAX_INCREMENTS: usize = 100; // The maximum number of collision tests per tick
|
||||||
let increments = ((pos_delta.map(|e| e.abs()).reduce_partial_max() / 0.3).ceil() as usize)
|
let increments = ((pos_delta.map(|e| e.abs()).reduce_partial_max() / 0.3).ceil() as usize)
|
||||||
.clamped(1, MAX_INCREMENTS);
|
.clamped(1, MAX_INCREMENTS);
|
||||||
|
let increment_dt = dt.0 / (increments as f32);
|
||||||
let old_pos = pos.0;
|
let old_pos = pos.0;
|
||||||
for _ in 0..increments {
|
for _ in 0..increments {
|
||||||
//prof_span!("increment");
|
//prof_span!("increment");
|
||||||
const MAX_ATTEMPTS: usize = 16;
|
const MAX_ATTEMPTS: usize = 16;
|
||||||
pos.0 += pos_delta / increments as f32;
|
let increment_dpos = pos_delta / increments as f32;
|
||||||
|
pos.0 += increment_dpos;
|
||||||
|
|
||||||
let try_colliding_block = |pos: &Pos| {
|
let try_colliding_block = |pos: &Pos| {
|
||||||
//prof_span!("most colliding check");
|
//prof_span!("most colliding check");
|
||||||
@ -1596,6 +1599,18 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
attempts += 1;
|
attempts += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply on-ground-friction
|
||||||
|
let ground_fric = on_ground.map(|b| b.get_friction()).unwrap_or(0.0);
|
||||||
|
if ground_fric > 0.0 {
|
||||||
|
let fric_fac = (1.0 - ground_fric.min(1.0) * fric_mod).powf(increment_dt * 60.0);
|
||||||
|
vel.0 *= fric_fac;
|
||||||
|
// TODO: evaluate activate: undo part of the increment and adjust pos_delta by
|
||||||
|
// friction for the next step
|
||||||
|
|
||||||
|
// pos.0 -= increment_dpos * pos_delta * (1.0 - fric_fac);
|
||||||
|
pos_delta *= fric_fac;
|
||||||
|
}
|
||||||
|
|
||||||
if attempts == MAX_ATTEMPTS {
|
if attempts == MAX_ATTEMPTS {
|
||||||
vel.0 = Vec3::zero();
|
vel.0 = Vec3::zero();
|
||||||
pos.0 = old_pos;
|
pos.0 = old_pos;
|
||||||
@ -1710,7 +1725,6 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
physics_state.on_wall = on_wall;
|
physics_state.on_wall = on_wall;
|
||||||
let fric_mod = read.stats.get(entity).map_or(1.0, |s| s.friction_modifier);
|
|
||||||
|
|
||||||
// skating (ski)
|
// skating (ski)
|
||||||
if !vel.0.xy().is_approx_zero()
|
if !vel.0.xy().is_approx_zero()
|
||||||
@ -1775,18 +1789,13 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
physics_state.skating_active = true;
|
physics_state.skating_active = true;
|
||||||
vel.0 = Vec3::new(new_ground_speed.x, new_ground_speed.y, 0.0);
|
vel.0 = Vec3::new(new_ground_speed.x, new_ground_speed.y, 0.0);
|
||||||
} else {
|
} else {
|
||||||
let ground_fric = physics_state
|
// In contrast to ground_fric keep wall_fric outside the loop as its more costly
|
||||||
.on_ground
|
// and less noticeable
|
||||||
.map(|b| b.get_friction())
|
if physics_state.on_wall.is_some() && climbing {
|
||||||
.unwrap_or(0.0);
|
vel.0 *= (1.0 - FRIC_GROUND * fric_mod).powf(dt.0 * 60.0);
|
||||||
let wall_fric = if physics_state.on_wall.is_some() && climbing {
|
}
|
||||||
FRIC_GROUND
|
// Set ground_vel when friction was applied.
|
||||||
} else {
|
if physics_state.on_wall.is_some() || physics_state.on_ground.is_some() {
|
||||||
0.0
|
|
||||||
};
|
|
||||||
let fric = ground_fric.max(wall_fric);
|
|
||||||
if fric > 0.0 {
|
|
||||||
vel.0 *= (1.0 - fric.min(1.0) * fric_mod).powf(dt.0 * 60.0);
|
|
||||||
physics_state.ground_vel = ground_vel;
|
physics_state.ground_vel = ground_vel;
|
||||||
}
|
}
|
||||||
physics_state.skating_active = false;
|
physics_state.skating_active = false;
|
||||||
|
@ -200,7 +200,7 @@ fn walk_max() -> Result<(), Box<dyn Error>> {
|
|||||||
utils::tick(&mut state, DT);
|
utils::tick(&mut state, DT);
|
||||||
}
|
}
|
||||||
let (pos, vel, _) = utils::get_transform(&state, p1)?;
|
let (pos, vel, _) = utils::get_transform(&state, p1)?;
|
||||||
assert_relative_eq!(pos.0.x, 68.40794, epsilon = EPSILON);
|
assert_relative_eq!(pos.0.x, 68.51424, epsilon = EPSILON);
|
||||||
assert_relative_eq!(vel.0.x, 9.695188, epsilon = EPSILON);
|
assert_relative_eq!(vel.0.x, 9.695188, epsilon = EPSILON);
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
utils::tick(&mut state, DT);
|
utils::tick(&mut state, DT);
|
||||||
@ -241,12 +241,12 @@ fn walk_dt_speed_diff() -> Result<(), Box<dyn Error>> {
|
|||||||
assert_relative_eq!(spos.0.y, 16.0);
|
assert_relative_eq!(spos.0.y, 16.0);
|
||||||
assert_relative_eq!(spos.0.z, 257.0);
|
assert_relative_eq!(spos.0.z, 257.0);
|
||||||
assert_relative_eq!(svel.0.x, 6.071788, epsilon = EPSILON);
|
assert_relative_eq!(svel.0.x, 6.071788, epsilon = EPSILON);
|
||||||
assert_relative_eq!(fpos.0.x, 16.993896, epsilon = EPSILON);
|
assert_relative_eq!(fpos.0.x, 16.71537, epsilon = EPSILON);
|
||||||
assert_relative_eq!(fpos.0.y, 16.0);
|
assert_relative_eq!(fpos.0.y, 16.0);
|
||||||
assert_relative_eq!(fpos.0.z, 257.0);
|
assert_relative_eq!(fpos.0.z, 257.0);
|
||||||
assert_relative_eq!(fvel.0.x, 3.7484815, epsilon = EPSILON);
|
assert_relative_eq!(fvel.0.x, 3.7484815, epsilon = EPSILON);
|
||||||
|
|
||||||
assert_relative_eq!((spos.0.x - fpos.0.x).abs(), 0.5724735, epsilon = EPSILON);
|
assert_relative_eq!((spos.0.x - fpos.0.x).abs(), 0.29394722, epsilon = EPSILON);
|
||||||
assert_relative_eq!((svel.0.x - fvel.0.x).abs(), 2.3233063, epsilon = EPSILON);
|
assert_relative_eq!((svel.0.x - fvel.0.x).abs(), 2.3233063, epsilon = EPSILON);
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
@ -258,11 +258,11 @@ fn walk_dt_speed_diff() -> Result<(), Box<dyn Error>> {
|
|||||||
let (fpos, fvel, _) = utils::get_transform(&fstate, fp1)?;
|
let (fpos, fvel, _) = utils::get_transform(&fstate, fp1)?;
|
||||||
assert_relative_eq!(spos.0.x, 17.248621, epsilon = EPSILON);
|
assert_relative_eq!(spos.0.x, 17.248621, epsilon = EPSILON);
|
||||||
assert_relative_eq!(svel.0.x, 8.344364, epsilon = EPSILON);
|
assert_relative_eq!(svel.0.x, 8.344364, epsilon = EPSILON);
|
||||||
assert_relative_eq!(fpos.0.x, 18.357212, epsilon = EPSILON);
|
assert_relative_eq!(fpos.0.x, 17.673855, epsilon = EPSILON);
|
||||||
assert_relative_eq!(fvel.0.x, 5.1417327, epsilon = EPSILON);
|
assert_relative_eq!(fvel.0.x, 5.1417327, epsilon = EPSILON);
|
||||||
|
|
||||||
// Diff after 200ms
|
// Diff after 200ms
|
||||||
assert_relative_eq!((spos.0.x - fpos.0.x).abs(), 1.1085911, epsilon = EPSILON);
|
assert_relative_eq!((spos.0.x - fpos.0.x).abs(), 0.42523384, epsilon = EPSILON);
|
||||||
assert_relative_eq!((svel.0.x - fvel.0.x).abs(), 3.2026315, epsilon = EPSILON);
|
assert_relative_eq!((svel.0.x - fvel.0.x).abs(), 3.2026315, epsilon = EPSILON);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Reference in New Issue
Block a user