From 62fab1a8668d8e30853feaa97427bd6063f5b9a8 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Thu, 29 Apr 2021 01:36:10 +0800 Subject: [PATCH] Add scalar type to tween template parameters --- src/animation/tween.hpp | 107 ++++++++++++++++++------------- src/application.cpp | 2 +- src/game/game-context.hpp | 2 +- src/math/interpolation.hpp | 2 +- src/renderer/passes/sky-pass.cpp | 2 +- 5 files changed, 67 insertions(+), 48 deletions(-) diff --git a/src/animation/tween.hpp b/src/animation/tween.hpp index a9cb260..18359ed 100644 --- a/src/animation/tween.hpp +++ b/src/animation/tween.hpp @@ -25,17 +25,26 @@ #include /** - * Container which stores two states along with an interpolator, for quick and easy tweening. + * Container which stores two states along with an interpolator, for quick and easy tweening. * * @tparam T Value type. + * @tparam S Scalar type. */ -template +template class tween { public: - //typedef typename std::remove_pointer::type value_type; + static_assert(std::is_scalar::value); + typedef T value_type; - typedef typename std::decay>::type interpolator_type; + typedef S scalar_type; + typedef typename std::decay>::type interpolator_type; + +private: + /// Throws an error if no interpolator is set. + static value_type interpolator_error(const value_type&, const value_type&, scalar_type); + +public: /** * Creates a tween. @@ -44,7 +53,7 @@ public: * @param state1 Initial value of state 1. * @param interpolator Function used to interpolate between states 0 and 1. */ - tween(const T& state0, const T& state1, interpolator_type interpolator = nullptr); + tween(const value_type& state0, const value_type& state1, interpolator_type interpolator = tween::interpolator_error); /** * Creates a tween. @@ -52,25 +61,26 @@ public: * @param value Initial value of states 0 and 1. * @param interpolator Function used to interpolate between states 0 and 1. */ - explicit tween(const T& value, interpolator_type interpolator = nullptr); + explicit tween(const value_type& value, interpolator_type interpolator = tween::interpolator_error); /** * Creates a tween. - * - * @param interpolator Function that will be used to interpolate between states 0 and 1. */ tween(); /** * Returns a reference to the specified tween state. * - * @param state Index of a tween state. Should be either `0` or `1`. + * @param i Index of a tween state. Should be either `0` or `1`. * @return Reference to the specified tween state. */ - const T& operator[](int state) const; + const value_type& operator[](int i) const; - /// @copydoc tween::operator[](int) const - T& operator[](int state); + /// @copydoc tween::operator[](int) const + value_type& operator[](int i); + + /// @copydoc tween::interpolate(scalar_type) const + value_type operator[](scalar_type a) const; /** * Returns an interpolated state between state 0 and state 1. If no interpolator is set, state 1 will be returned. @@ -78,7 +88,7 @@ public: * @param a Interpolation factor on `[0.0, 1.0]`. * @return Interpolated state, or state 1 if no interpolator is set. */ - value_type interpolate(double a) const; + value_type interpolate(scalar_type a) const; /** * Sets the function used to interpolate between states 0 and 1. @@ -103,70 +113,79 @@ public: void swap(); private: - T state0; - T state1; + value_type states[2]; interpolator_type interpolator; }; -template -tween::tween(const T& value, interpolator_type interpolator): - state0(value), - state1(value), +template +typename tween::value_type tween::interpolator_error(const value_type&, const value_type&, scalar_type) +{ + throw std::runtime_error("tween interpolator not set"); +} + +template +tween::tween(const value_type& value, interpolator_type interpolator): + states{value, value}, interpolator(interpolator) {} -template -tween::tween(const T& state0, const T& state1, interpolator_type interpolator): - state0(state0), - state1(state1), +template +tween::tween(const value_type& state0, const value_type& state1, interpolator_type interpolator): + states{state0, state1}, interpolator(interpolator) {} -template -tween::tween(): +template +tween::tween(): interpolator(nullptr) {} -template -inline const T& tween::operator[](int state) const +template +inline const typename tween::value_type& tween::operator[](int i) const +{ + return states[i]; +} + +template +inline typename tween::value_type& tween::operator[](int i) { - return (state <= 0) ? state0 : state1; + return states[i]; } -template -inline T& tween::operator[](int state) +template +inline typename tween::value_type tween::operator[](scalar_type a) const { - return (state <= 0) ? state0 : state1; + return interpolate(a); } -template -inline typename tween::value_type tween::interpolate(double a) const +template +inline typename tween::value_type tween::interpolate(scalar_type a) const { - return (interpolator) ? interpolator(state0, state1, a) : state1; + return interpolator(states[0], states[1], a); } -template -inline void tween::set_interpolator(const interpolator_type& interpolator) +template +inline void tween::set_interpolator(const interpolator_type& interpolator) { this->interpolator = interpolator; } -template -inline const typename tween::interpolator_type& tween::get_interpolator() const +template +inline const typename tween::interpolator_type& tween::get_interpolator() const { return interpolator; } -template -inline void tween::update() +template +inline void tween::update() { - state0 = state1; + states[0] = states[1]; } -template -inline void tween::swap() +template +inline void tween::swap() { - std::swap(state0, state1); + std::swap(states[0], states[1]); } #endif // ANTKEEPER_TWEEN_HPP diff --git a/src/application.cpp b/src/application.cpp index edfec4f..b981286 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -49,7 +49,7 @@ application::application(): window_dimensions({0, 0}), viewport_dimensions({0, 0}), mouse_position({0, 0}), - update_rate(60.0), + update_rate(5.0), logger(nullptr), sdl_window(nullptr), sdl_gl_context(nullptr) diff --git a/src/game/game-context.hpp b/src/game/game-context.hpp index ac56e49..0221e2c 100644 --- a/src/game/game-context.hpp +++ b/src/game/game-context.hpp @@ -35,6 +35,7 @@ #include "input/listener.hpp" #include "input/mapper.hpp" #include "input/event-router.hpp" +#include "animation/tween.hpp" #include #include #include @@ -64,7 +65,6 @@ class outline_pass; struct biome; template class animation; template class material_property; -template class tween; namespace debug { diff --git a/src/math/interpolation.hpp b/src/math/interpolation.hpp index 32a4f5a..ce70720 100644 --- a/src/math/interpolation.hpp +++ b/src/math/interpolation.hpp @@ -70,7 +70,7 @@ T log_lerp(const T& x, const T& y, S a); template inline T lerp(const T& x, const T& y, S a) { - return (y - x) * a + x; + return x + (y - x) * a; } template diff --git a/src/renderer/passes/sky-pass.cpp b/src/renderer/passes/sky-pass.cpp index c0ea2fe..be4ca0b 100644 --- a/src/renderer/passes/sky-pass.cpp +++ b/src/renderer/passes/sky-pass.cpp @@ -80,7 +80,7 @@ void sky_pass::render(render_context* context) const auto viewport = framebuffer->get_dimensions(); rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport)); - float time = time_tween->interpolate(context->alpha); + float time = (*time_tween)[context->alpha]; float2 resolution = {static_cast(std::get<0>(viewport)), static_cast(std::get<1>(viewport))}; const scene::camera& camera = *context->camera;