From 89b42765fa0f188f5f8d4a7a0fed189cbfcb0432 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Sun, 9 Aug 2020 19:17:47 -0700 Subject: [PATCH] Allow tweens to have no interpolator and set material property default interpolators --- src/animation/tween.hpp | 72 ++++++++++-------------------- src/application.cpp | 6 ++- src/renderer/material-property.hpp | 55 +++++++++++++++++++++++ src/scene/camera.cpp | 17 +++---- src/scene/light.cpp | 7 +-- src/scene/point-light.cpp | 3 +- src/scene/spotlight.cpp | 7 +-- 7 files changed, 103 insertions(+), 64 deletions(-) diff --git a/src/animation/tween.hpp b/src/animation/tween.hpp index f792ce8..445179b 100644 --- a/src/animation/tween.hpp +++ b/src/animation/tween.hpp @@ -24,17 +24,6 @@ #include #include -/** - * Linearly interpolates between two values. - * - * @param x Start of the range in which to interpolate. - * @param y End of the range in which to interpolate. - * @param a Value used to interpolate between @p x and @p y. - * @return Interpolated value. - */ -template -T tween_default_interpolator(const T& x, const T& y, double a); - /** * Container which stores two states along with an interpolator, for quick and easy tweening. * @@ -53,24 +42,24 @@ public: * * @param state0 Initial value of state 0. * @param state1 Initial value of state 1. - * @param interpolator Function or function object that will be used to interpolate between states 0 and 1. + * @param interpolator Function used to interpolate between states 0 and 1. */ - explicit tween(const T& state0, const T& state1, const interpolator_type& interpolator = tween_default_interpolator); - + tween(const T& state0, const T& state1, interpolator_type interpolator = nullptr); + /** * Creates a tween. * * @param value Initial value of states 0 and 1. - * @param interpolator Function or function object that will be used to interpolate between states 0 and 1. + * @param interpolator Function used to interpolate between states 0 and 1. */ - explicit tween(const T& value, const interpolator_type& interpolator = tween_default_interpolator); - + explicit tween(const T& value, interpolator_type interpolator = nullptr); + /** * Creates a tween. * - * @param interpolator Function or function object that will be used to interpolate between states 0 and 1. + * @param interpolator Function that will be used to interpolate between states 0 and 1. */ - explicit tween(const interpolator_type& interpolator = tween_default_interpolator); + tween(); /** * Returns a reference to the specified tween state. @@ -84,22 +73,22 @@ public: T& operator[](int state); /** - * Returns an interpolated state between state 0 and state 1. + * Returns an interpolated state between state 0 and state 1. If no interpolator is set, state 1 will be returned. * - * @param a Interpolation factor. Should be on `[0.0, 1.0]`. - * @return Interpolated state. + * @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; /** - * Sets the function object used to interpolate between states 0 and 1. + * Sets the function used to interpolate between states 0 and 1. * - * @param interpolator Interpolator function object. + * @param interpolator Interpolator function. */ void set_interpolator(const interpolator_type& interpolator); /** - * Returns the function or function object that is used to interpolate between states 0 and 1. + * Returns the function used to interpolate between states 0 and 1. */ const interpolator_type& get_interpolator() const; @@ -114,41 +103,28 @@ public: void swap(); private: - interpolator_type interpolator; T state0; T state1; + interpolator_type interpolator; }; template -inline T tween_default_interpolator(const T& x, const T& y, double a) -{ - //return x * (1.0 - a) + y * a; - return y; -} - -template <> -inline float tween_default_interpolator(const float& x, const float& y, double a) -{ - return (y - x) * a + x; -} - -template -tween::tween(const T& value, const interpolator_type& interpolator): - interpolator(interpolator), +tween::tween(const T& value, interpolator_type interpolator): state0(value), - state1(value) + state1(value), + interpolator(interpolator) {} template -tween::tween(const T& state0, const T& state1, const interpolator_type& interpolator): - interpolator(interpolator), +tween::tween(const T& state0, const T& state1, interpolator_type interpolator): state0(state0), - state1(state1) + state1(state1), + interpolator(interpolator) {} template -tween::tween(const interpolator_type& interpolator): - interpolator(interpolator) +tween::tween(): + interpolator(nullptr) {} template @@ -166,7 +142,7 @@ inline T& tween::operator[](int state) template inline typename tween::value_type tween::interpolate(double a) const { - return interpolator(state0, state1, a); + return (interpolator) ? interpolator(state0, state1, a) : state1; } template diff --git a/src/application.cpp b/src/application.cpp index e395ee3..26a4a31 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -936,6 +936,9 @@ application::application(int argc, char** argv): get_ui_scene()->add_object(radial_transition_outer->get_billboard()); animator->add_animation(radial_transition_outer->get_animation()); + // Setup tweens + focal_point_tween.set_interpolator(ease::linear); + // Register CLI commands cli.register_command("echo", cc::echo); cli.register_command("exit", std::function(std::bind(&cc::exit, this))); @@ -998,8 +1001,9 @@ int application::execute() // Reset frame scheduler frame_scheduler.reset(); - // Reset time tween + // Setup time tween time[0] = time[1] = 0.0; + time.set_interpolator(ease::linear); // Schedule frames until closed while (!closed) diff --git a/src/renderer/material-property.hpp b/src/renderer/material-property.hpp index 9e31d41..355b799 100644 --- a/src/renderer/material-property.hpp +++ b/src/renderer/material-property.hpp @@ -23,10 +23,12 @@ #include "animation/tween.hpp" #include "rasterizer/shader-variable-type.hpp" #include "rasterizer/shader-input.hpp" +#include "animation/ease.hpp" #include #include using namespace vmq::types; +using namespace vmq::operators; class material; class shader_program; @@ -100,6 +102,12 @@ template class material_property: public material_property_base { public: + typedef tween tween_type; + typedef typename tween::interpolator_type interpolator_type; + + /// Default tween interpolator function for this material property type. + static T default_interpolator(const T& x, const T& y, double a); + /** * Creates a material property. * @@ -145,6 +153,13 @@ public: */ void set_values(std::size_t index, const T* values, std::size_t count); + /** + * Sets the tween interpolator function. + * + * @param interpolator Tween interpolator function. + */ + void set_tween_interpolator(interpolator_type interpolator); + /// Returns the value of the first element in this property. const T& get_value() const; @@ -167,12 +182,43 @@ private: tween* values; }; +template +inline T material_property::default_interpolator(const T& x, const T& y, double a) +{ + return y; +} + +template <> +inline float material_property::default_interpolator(const float& x, const float& y, double a) +{ + return ease::linear(x, y, static_cast(a)); +} + +template <> +inline float2 material_property::default_interpolator(const float2& x, const float2& y, double a) +{ + return ease::linear(x, y, static_cast(a)); +} + +template <> +inline float3 material_property::default_interpolator(const float3& x, const float3& y, double a) +{ + return ease::linear(x, y, static_cast(a)); +} + +template <> +inline float4 material_property::default_interpolator(const float4& x, const float4& y, double a) +{ + return ease::linear(x, y, static_cast(a)); +} + template material_property::material_property(std::size_t element_count): element_count(element_count), values(nullptr) { values = new tween[element_count]; + set_tween_interpolator(default_interpolator); } template @@ -235,6 +281,15 @@ void material_property::set_values(std::size_t index, const T* values, std::s } } +template +void material_property::set_tween_interpolator(interpolator_type interpolator) +{ + for (std::size_t i = 0; i < element_count; ++i) + { + this->values[i].set_interpolator(interpolator); + } +} + template inline const T& material_property::get_value() const { diff --git a/src/scene/camera.cpp b/src/scene/camera.cpp index 58b5059..2896f1f 100644 --- a/src/scene/camera.cpp +++ b/src/scene/camera.cpp @@ -19,6 +19,7 @@ #include "scene/camera.hpp" #include "configuration.hpp" +#include "animation/ease.hpp" using namespace vmq::operators; @@ -61,14 +62,14 @@ camera::camera(): compositor(nullptr), composite_index(0), orthographic(true), - clip_left(-1.0f), - clip_right(1.0f), - clip_bottom(-1.0f), - clip_top(1.0f), - clip_near(-1.0f), - clip_far(1.0f), - fov(vmq::half_pi), - aspect_ratio(1.0f), + clip_left(-1.0f, ease::linear), + clip_right(1.0f, ease::linear), + clip_bottom(-1.0f, ease::linear), + clip_top(1.0f, ease::linear), + clip_near(-1.0f, ease::linear), + clip_far(1.0f, ease::linear), + fov(vmq::half_pi, ease::linear), + aspect_ratio(1.0f, ease::linear), view(vmq::identity4x4, std::bind(&interpolate_view, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)), projection(vmq::identity4x4, std::bind(&interpolate_projection, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)), view_projection(vmq::identity4x4, std::bind(&interpolate_view_projection, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) diff --git a/src/scene/light.cpp b/src/scene/light.cpp index aa979c2..23d291e 100644 --- a/src/scene/light.cpp +++ b/src/scene/light.cpp @@ -18,14 +18,15 @@ */ #include "scene/light.hpp" +#include "animation/ease.hpp" using namespace vmq::operators; light::light(): bounds(get_translation(), 0.0f), - color(float3{1.0f, 1.0f, 1.0f}), - intensity(1.0f), - scaled_color(float3{1.0f, 1.0f, 1.0f}) + color(float3{1.0f, 1.0f, 1.0f}, ease::linear), + intensity(1.0f, ease::linear), + scaled_color(float3{1.0f, 1.0f, 1.0f}, ease::linear) {} void light::set_color(const float3& color) diff --git a/src/scene/point-light.cpp b/src/scene/point-light.cpp index 86ebe05..f171f34 100644 --- a/src/scene/point-light.cpp +++ b/src/scene/point-light.cpp @@ -18,11 +18,12 @@ */ #include "point-light.hpp" +#include "animation/ease.hpp" using namespace vmq::operators; point_light::point_light(): - attenuation(float3{1, 0, 0}) + attenuation(float3{1, 0, 0}, ease::linear) {} void point_light::set_attenuation(const float3& attenuation) diff --git a/src/scene/spotlight.cpp b/src/scene/spotlight.cpp index 21d41ce..62d2f93 100644 --- a/src/scene/spotlight.cpp +++ b/src/scene/spotlight.cpp @@ -19,6 +19,7 @@ #include "spotlight.hpp" #include "configuration.hpp" +#include "animation/ease.hpp" #include using namespace vmq::operators; @@ -32,9 +33,9 @@ static float3 interpolate_direction(const float3& x, const float3& y, float a) spotlight::spotlight(): direction(global_forward, interpolate_direction), - attenuation(float3{1, 0, 0}), - cutoff(float2{vmq::pi, vmq::pi}), - cosine_cutoff(float2{std::cos(vmq::pi), std::cos(vmq::pi)}) + attenuation(float3{1, 0, 0}, ease::linear), + cutoff(float2{vmq::pi, vmq::pi}, ease::linear), + cosine_cutoff(float2{std::cos(vmq::pi), std::cos(vmq::pi)}, ease::linear) {} void spotlight::set_attenuation(const float3& attenuation)