From bf6c301b9cb515789db03743dbcebc67a1865538 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Mon, 1 Jul 2019 17:42:02 +0100 Subject: [PATCH] Add access to interpolation fraction for fixed timestep interpolation Addresses #30068 This is a prerequisite for allowing proper support for fixed timestep interpolation, exposing the interpolation fraction to the engine, modules and gdscript. The interpolation fraction is the fraction through the current physics tick at the time of the current frame. --- core/bind/core_bind.cpp | 5 +++++ core/bind/core_bind.h | 1 + core/engine.cpp | 1 + core/engine.h | 2 ++ doc/classes/Engine.xml | 7 +++++++ main/main.cpp | 1 + main/main_timer_sync.cpp | 4 ++++ main/main_timer_sync.h | 1 + 8 files changed, 22 insertions(+) diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index f9fb7d76953..01419607b3d 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -2964,6 +2964,10 @@ float _Engine::get_physics_jitter_fix() const { return Engine::get_singleton()->get_physics_jitter_fix(); } +float _Engine::get_physics_interpolation_fraction() const { + return Engine::get_singleton()->get_physics_interpolation_fraction(); +} + void _Engine::set_target_fps(int p_fps) { Engine::get_singleton()->set_target_fps(p_fps); } @@ -3052,6 +3056,7 @@ void _Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("get_iterations_per_second"), &_Engine::get_iterations_per_second); ClassDB::bind_method(D_METHOD("set_physics_jitter_fix", "physics_jitter_fix"), &_Engine::set_physics_jitter_fix); ClassDB::bind_method(D_METHOD("get_physics_jitter_fix"), &_Engine::get_physics_jitter_fix); + ClassDB::bind_method(D_METHOD("get_physics_interpolation_fraction"), &_Engine::get_physics_interpolation_fraction); ClassDB::bind_method(D_METHOD("set_target_fps", "target_fps"), &_Engine::set_target_fps); ClassDB::bind_method(D_METHOD("get_target_fps"), &_Engine::get_target_fps); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 3be5a087528..f0f86e003f7 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -746,6 +746,7 @@ public: void set_physics_jitter_fix(float p_threshold); float get_physics_jitter_fix() const; + float get_physics_interpolation_fraction() const; void set_target_fps(int p_fps); int get_target_fps() const; diff --git a/core/engine.cpp b/core/engine.cpp index 2d8473fbd99..0dd0459403b 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -227,6 +227,7 @@ Engine::Engine() { frames_drawn = 0; ips = 60; physics_jitter_fix = 0.5; + _physics_interpolation_fraction = 0.0f; _frame_delay = 0; _fps = 1; _target_fps = 0; diff --git a/core/engine.h b/core/engine.h index 15665fee296..192e8e67a09 100644 --- a/core/engine.h +++ b/core/engine.h @@ -63,6 +63,7 @@ private: float _time_scale; bool _pixel_snap; uint64_t _physics_frames; + float _physics_interpolation_fraction; uint64_t _idle_frames; bool _in_physics; @@ -95,6 +96,7 @@ public: bool is_in_physics_frame() const { return _in_physics; } uint64_t get_idle_frame_ticks() const { return _frame_ticks; } float get_idle_frame_step() const { return _frame_step; } + float get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; } void set_time_scale(float p_scale); float get_time_scale() const; diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index 60a807c3047..187e13d7bda 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -72,6 +72,13 @@ Returns the main loop object (see [MainLoop] and [SceneTree]). + + + + + Returns the fraction through the current physics tick we are at the time of rendering the frame. This can be used to implement fixed timestep interpolation. + + diff --git a/main/main.cpp b/main/main.cpp index 3f84eca1d27..d3e816eb482 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1869,6 +1869,7 @@ bool Main::iteration() { double scaled_step = step * time_scale; Engine::get_singleton()->_frame_step = step; + Engine::get_singleton()->_physics_interpolation_fraction = advance.interpolation_fraction; uint64_t physics_process_ticks = 0; uint64_t idle_process_ticks = 0; diff --git a/main/main_timer_sync.cpp b/main/main_timer_sync.cpp index f7388c85178..edacb20f28b 100644 --- a/main/main_timer_sync.cpp +++ b/main/main_timer_sync.cpp @@ -178,6 +178,10 @@ MainFrameTime MainTimerSync::advance_checked(float p_frame_slice, int p_iteratio // track deficit time_deficit = p_idle_step - ret.idle_step; + // p_frame_slice is 1.0 / iterations_per_sec + // i.e. the time in seconds taken by a physics tick + ret.interpolation_fraction = time_accum / p_frame_slice; + return ret; } diff --git a/main/main_timer_sync.h b/main/main_timer_sync.h index 179119edce1..93d335b27f0 100644 --- a/main/main_timer_sync.h +++ b/main/main_timer_sync.h @@ -36,6 +36,7 @@ struct MainFrameTime { float idle_step; // time to advance idles for (argument to process()) int physics_steps; // number of times to iterate the physics engine + float interpolation_fraction; // fraction through the current physics tick void clamp_idle(float min_idle_step, float max_idle_step); };