#pragma once #include #include #include #include #include #include #include #include namespace mbgl { namespace util { float interpolationFactor(float base, Range range, float z); template struct Interpolator; template T interpolate(const T& a, const T& b, const double t) { return Interpolator()(a, b, t); } template struct Interpolator { T operator()(const T& a, const T& b, const double t) const { return a * (1.0 - t) + b * t; } }; template struct Interpolator> { private: using Array = std::array; template Array operator()(const Array& a, const Array& b, const double t, std::index_sequence) { return {{ interpolate(a[I], b[I], t)... }}; } public: Array operator()(const Array& a, const Array& b, const double t) { return operator()(a, b, t, std::make_index_sequence()); } }; template <> struct Interpolator { public: style::Position operator()(const style::Position& a, const style::Position& b, const double t) { auto pos = style::Position(); auto interpolated = interpolate(a.getCartesian(), b.getCartesian(), t); pos.setCartesian(interpolated); return { pos }; } }; template <> struct Interpolator { public: Color operator()(const Color& a, const Color& b, const double t) { return { interpolate(a.r, b.r, t), interpolate(a.g, b.g, t), interpolate(a.b, b.b, t), interpolate(a.a, b.a, t) }; } }; struct Uninterpolated { template T operator()(const T& a, const T&, const double) const { return a; } }; template <> struct Interpolator : Uninterpolated {}; template struct Interpolator::value>> : Uninterpolated {}; template <> struct Interpolator : Uninterpolated {}; template struct Interpolator> : Uninterpolated {}; template struct Interpolatable : std::conditional_t< !std::is_base_of>::value, std::true_type, std::false_type> {}; } // namespace util } // namespace mbgl