mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Resolve #867 - Make deltatime use the lowest delta of several frames to avoid 'teleport' effect after single-frame lag spike
This commit is contained in:
parent
20b45a1202
commit
57d3a595ce
@ -54,6 +54,7 @@ pub struct ClockStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const NUMBER_OF_OLD_DELTAS_KEPT: usize = 100;
|
const NUMBER_OF_OLD_DELTAS_KEPT: usize = 100;
|
||||||
|
const NUMBER_OF_DELTAS_COMPARED: usize = 5;
|
||||||
|
|
||||||
impl Clock {
|
impl Clock {
|
||||||
pub fn new(target_dt: Duration) -> Self {
|
pub fn new(target_dt: Duration) -> Self {
|
||||||
@ -75,6 +76,24 @@ impl Clock {
|
|||||||
|
|
||||||
pub fn dt(&self) -> Duration { self.last_dt }
|
pub fn dt(&self) -> Duration { self.last_dt }
|
||||||
|
|
||||||
|
pub fn get_stable_dt(&self) -> Duration {
|
||||||
|
if self.last_dts.len() < NUMBER_OF_DELTAS_COMPARED {
|
||||||
|
self.last_dt
|
||||||
|
} else {
|
||||||
|
let stable_dt = Duration::from_secs_f32(
|
||||||
|
self.last_dts
|
||||||
|
.iter()
|
||||||
|
.skip(self.last_dts.len() - NUMBER_OF_DELTAS_COMPARED)
|
||||||
|
.min()
|
||||||
|
.map_or(self.last_dt.as_secs_f32(), |t| t.into_inner()),
|
||||||
|
);
|
||||||
|
if self.last_dt > 2 * stable_dt {
|
||||||
|
tracing::debug!(?self.last_dt, ?self.total_tick_time, "lag spike detected, unusually slow tick");
|
||||||
|
}
|
||||||
|
stable_dt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Do not modify without asking @xMAC94x first!
|
/// Do not modify without asking @xMAC94x first!
|
||||||
pub fn tick(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
span!(_guard, "tick", "Clock::tick");
|
span!(_guard, "tick", "Clock::tick");
|
||||||
|
@ -634,7 +634,7 @@ impl PlayState for SessionState {
|
|||||||
let right = self.scene.camera().right();
|
let right = self.scene.camera().right();
|
||||||
let dir = right * axis_right + forward * axis_up;
|
let dir = right * axis_right + forward * axis_up;
|
||||||
|
|
||||||
let dt = global_state.clock.dt().as_secs_f32();
|
let dt = global_state.clock.get_stable_dt().as_secs_f32();
|
||||||
if self.freefly_vel.magnitude_squared() > 0.01 {
|
if self.freefly_vel.magnitude_squared() > 0.01 {
|
||||||
let new_vel = self.freefly_vel
|
let new_vel = self.freefly_vel
|
||||||
- self.freefly_vel.normalized() * (FREEFLY_DAMPING * dt);
|
- self.freefly_vel.normalized() * (FREEFLY_DAMPING * dt);
|
||||||
@ -671,7 +671,11 @@ impl PlayState for SessionState {
|
|||||||
// Runs if either in a multiplayer server or the singleplayer server is unpaused
|
// Runs if either in a multiplayer server or the singleplayer server is unpaused
|
||||||
if !global_state.paused() {
|
if !global_state.paused() {
|
||||||
// Perform an in-game tick.
|
// Perform an in-game tick.
|
||||||
match self.tick(global_state.clock.dt(), global_state, &mut outcomes) {
|
match self.tick(
|
||||||
|
global_state.clock.get_stable_dt(),
|
||||||
|
global_state,
|
||||||
|
&mut outcomes,
|
||||||
|
) {
|
||||||
Ok(TickAction::Continue) => {}, // Do nothing
|
Ok(TickAction::Continue) => {}, // Do nothing
|
||||||
Ok(TickAction::Disconnect) => return PlayStateResult::Pop, // Go to main menu
|
Ok(TickAction::Disconnect) => return PlayStateResult::Pop, // Go to main menu
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -740,7 +744,7 @@ impl PlayState for SessionState {
|
|||||||
global_state,
|
global_state,
|
||||||
&debug_info,
|
&debug_info,
|
||||||
&self.scene.camera(),
|
&self.scene.camera(),
|
||||||
global_state.clock.dt(),
|
global_state.clock.get_stable_dt(),
|
||||||
HudInfo {
|
HudInfo {
|
||||||
is_aiming,
|
is_aiming,
|
||||||
is_first_person: matches!(
|
is_first_person: matches!(
|
||||||
|
Loading…
Reference in New Issue
Block a user