Skip to content

Commit

Permalink
Add access to interpolation fraction for fixed timestep interpolation
Browse files Browse the repository at this point in the history
Addresses godotengine#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.
  • Loading branch information
lawnjelly authored and myhalibobo committed Sep 3, 2019
1 parent fd564fb commit 345dd97
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 0 deletions.
5 changes: 5 additions & 0 deletions core/bind/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,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);
}
Expand Down Expand Up @@ -3029,6 +3033,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);

Expand Down
1 change: 1 addition & 0 deletions core/bind/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ class _Engine : public Object {

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;
Expand Down
1 change: 1 addition & 0 deletions core/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions core/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Engine {
float _time_scale;
bool _pixel_snap;
uint64_t _physics_frames;
float _physics_interpolation_fraction;

uint64_t _idle_frames;
bool _in_physics;
Expand Down Expand Up @@ -95,6 +96,7 @@ class Engine {
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;
Expand Down
7 changes: 7 additions & 0 deletions doc/classes/Engine.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@
Returns the main loop object (see [MainLoop] and [SceneTree]).
</description>
</method>
<method name="get_physics_interpolation_fraction" qualifiers="const">
<return type="float">
</return>
<description>
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.
</description>
</method>
<method name="get_singleton" qualifiers="const">
<return type="Object">
</return>
Expand Down
1 change: 1 addition & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1880,6 +1880,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;
Expand Down
4 changes: 4 additions & 0 deletions main/main_timer_sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions main/main_timer_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
Expand Down

0 comments on commit 345dd97

Please sign in to comment.