diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj index aee8098b..56a87356 100644 --- a/projects/kiwano/kiwano.vcxproj +++ b/projects/kiwano/kiwano.vcxproj @@ -70,6 +70,7 @@ + diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters index f22d5eea..5e622aef 100644 --- a/projects/kiwano/kiwano.vcxproj.filters +++ b/projects/kiwano/kiwano.vcxproj.filters @@ -405,6 +405,9 @@ event\listener + + math + diff --git a/src/kiwano/2d/animation/TweenAnimation.cpp b/src/kiwano/2d/animation/TweenAnimation.cpp index d3498b80..306a4a4e 100644 --- a/src/kiwano/2d/animation/TweenAnimation.cpp +++ b/src/kiwano/2d/animation/TweenAnimation.cpp @@ -42,6 +42,8 @@ TweenAnimation::TweenAnimation(Duration duration) float TweenAnimation::Interpolate(float frac) { + if (frac == 1) + return 1; if (ease_func_) frac = ease_func_(frac); return frac; diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 9af44c4c..5958bad6 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -38,6 +38,7 @@ #include #include #include +#include // // core diff --git a/src/kiwano/math/Interpolator.h b/src/kiwano/math/Interpolator.h new file mode 100644 index 00000000..05e7cd65 --- /dev/null +++ b/src/kiwano/math/Interpolator.h @@ -0,0 +1,159 @@ +// Copyright (c) 2016-2018 Kiwano - Nomango +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once +#include +#include +#include +#include + +namespace kiwano +{ +namespace math +{ + + +template +struct InterpolateMethod; + +template <> +struct InterpolateMethod +{ + inline float operator()(float frac) const noexcept + { + return frac; + } +}; + +template <> +struct InterpolateMethod +{ + float (*method)(float); + + InterpolateMethod(float (*method)(float)) noexcept + : method(method) + { + } + + inline float operator()(float frac) const noexcept + { + if (method) + return method(frac); + return frac; + } +}; + +template <> +struct InterpolateMethod> +{ + Function method; + + InterpolateMethod(const Function& method) noexcept + : method(method) + { + } + + inline float operator()(float frac) const noexcept + { + if (method) + return method(frac); + return frac; + } +}; + +template +class Interpolator; + +template +class Interpolator +{ +public: + template + inline _Ty Interpolate(_Ty start, _Ty end, float frac, const InterpolateMethod<_Method>& method = {}) + { + if (frac >= 1) + return end; + return start + static_cast<_Ty>(static_cast(end - start) * method(frac)); + } +}; + +template +class Interpolator> +{ +public: + template + inline Vec2T<_Ty> Interpolate(const Vec2T<_Ty>& start, const Vec2T<_Ty>& end, float frac, + const InterpolateMethod<_Method>& method = {}) + { + if (frac >= 1) + return end; + + Interpolator<_Ty> fi; + return Vec2T<_Ty>{ + fi.Interpolate(start.x, end.x, frac, method), + fi.Interpolate(start.y, end.y, frac, method) + }; + } +}; + +template +class Interpolator> +{ +public: + template + inline RectT<_Ty> Interpolate(const RectT<_Ty>& start, const RectT<_Ty>& end, float frac, + const InterpolateMethod<_Method>& method = {}) + { + if (frac >= 1) + return end; + + Interpolator> vi; + return RectT<_Ty>{ + vi.Interpolate(start.left_top, end.left_top, frac, method), + vi.Interpolate(start.right_bottom, end.right_bottom, frac, method) + }; + } +}; + +template +class Interpolator> +{ +public: + template + inline TransformT<_Ty> Interpolate(const TransformT<_Ty>& start, const TransformT<_Ty>& end, float frac, + const InterpolateMethod<_Method>& method = {}) + { + if (frac >= 1) + return end; + + Interpolator<_Ty> fi; + Interpolator> vi; + + TransformT<_Ty> transform; + transform.rotation = fi.Interpolate(start.rotation, end.rotation, frac, method); + transform.position = vi.Interpolate(start.position, end.position, frac, method); + transform.scale = vi.Interpolate(start.scale, end.scale, frac, method); + transform.skew = vi.Interpolate(start.skew, end.skew, frac, method); + return transform; + } +}; + +} // namespace math +} // namespace kiwano