2525#include " math/random.hpp"
2626#include " math/util.hpp"
2727#include " object/player.hpp"
28+ #include " supertux/constants.hpp"
2829#include " supertux/gameconfig.hpp"
2930#include " supertux/globals.hpp"
3031#include " supertux/level.hpp"
@@ -82,7 +83,9 @@ Camera::Camera(const std::string& name) :
8283 m_scale_easing(),
8384 m_scale_anchor(),
8485 m_minimum_scale(1 .f),
85- m_enfore_minimum_scale(false )
86+ m_enfore_minimum_scale(false ),
87+ m_last_translation(0 .0f , 0 .0f ),
88+ m_last_scale(1 .0f )
8689{
8790}
8891
@@ -118,7 +121,9 @@ Camera::Camera(const ReaderMapping& reader) :
118121 m_scale_easing(),
119122 m_scale_anchor(),
120123 m_minimum_scale(1 .f),
121- m_enfore_minimum_scale(false )
124+ m_enfore_minimum_scale(false ),
125+ m_last_translation(0 .0f , 0 .0f ),
126+ m_last_scale(1 .0f )
122127{
123128 std::string modename;
124129
@@ -207,6 +212,26 @@ Camera::check_state()
207212 PathObject::check_state ();
208213}
209214
215+ void Camera::reset_prediction_state ()
216+ {
217+ m_last_translation = get_translation ();
218+ m_last_scale = get_current_scale ();
219+ }
220+
221+ std::pair<Vector, float >
222+ Camera::get_predicted_transform (float time_offset) const
223+ {
224+ if (g_config->frame_prediction ) {
225+ // TODO: extrapolate forwards instead of interpolating over the last frame
226+ float x = time_offset * LOGICAL_FPS;
227+ Vector translation = get_translation () * x + (1 .f - x) * m_last_translation;
228+ float scale = get_current_scale () * x + (1 .f - x) * m_last_scale;
229+ return std::pair (translation, scale);
230+ } else {
231+ return std::pair (get_translation (), get_current_scale ());
232+ }
233+ }
234+
210235const Vector
211236Camera::get_translation () const
212237{
218243Camera::set_translation_centered (const Vector& translation)
219244{
220245 m_translation = translation - m_screen_size.as_vector () / 2 ;
246+ reset_prediction_state ();
221247}
222248
223249Rectf
@@ -237,6 +263,7 @@ Camera::reset(const Vector& tuxpos)
237263 keep_in_bounds (m_translation);
238264
239265 m_cached_translation = m_translation;
266+ reset_prediction_state ();
240267}
241268
242269void
@@ -286,6 +313,7 @@ Camera::scroll_to(const Vector& goal, float scrolltime)
286313 m_translation.x = goal.x ;
287314 m_translation.y = goal.y ;
288315 m_mode = Mode::MANUAL;
316+ reset_prediction_state ();
289317 return ;
290318 }
291319
@@ -313,6 +341,10 @@ Camera::draw(DrawingContext& context)
313341void
314342Camera::update (float dt_sec)
315343{
344+ // For use by camera position prediction
345+ m_last_scale = get_current_scale ();
346+ m_last_translation = get_translation ();
347+
316348 // Minimum scale should be set during the update sequence; else, reset it.
317349 m_enfore_minimum_scale = false ;
318350
@@ -361,6 +393,8 @@ Camera::keep_in_bounds(const Rectf& bounds)
361393
362394 // Remove any scale factor we may have added in the checks above.
363395 m_translation -= scale_factor;
396+
397+ reset_prediction_state ();
364398}
365399
366400void
@@ -754,6 +788,8 @@ Camera::ease_scale(float scale, float time, easing ease, AnchorPoint anchor)
754788 m_scale = scale;
755789 if (m_mode == Mode::MANUAL)
756790 m_translation = m_scale_target_translation;
791+
792+ reset_prediction_state ();
757793 }
758794}
759795
0 commit comments