浏览代码

Merge pull request #30226 from lawnjelly/interpolate

Add access to interpolation fraction for fixed timestep interpolation
Rémi Verschelde 6 年之前
父节点
当前提交
20a3bb9c48
共有 8 个文件被更改,包括 22 次插入0 次删除
  1. 5 0
      core/bind/core_bind.cpp
  2. 1 0
      core/bind/core_bind.h
  3. 1 0
      core/engine.cpp
  4. 2 0
      core/engine.h
  5. 7 0
      doc/classes/Engine.xml
  6. 1 0
      main/main.cpp
  7. 4 0
      main/main_timer_sync.cpp
  8. 1 0
      main/main_timer_sync.h

+ 5 - 0
core/bind/core_bind.cpp

@@ -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);
 }
@@ -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);
 

+ 1 - 0
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;

+ 1 - 0
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;

+ 2 - 0
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;

+ 7 - 0
doc/classes/Engine.xml

@@ -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>

+ 1 - 0
main/main.cpp

@@ -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;

+ 4 - 0
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;
 }
 

+ 1 - 0
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);
 };