Consolidate duplicate interpolation definitions
While here, do not interpolate style properties that are not transitionable. The previous behavior was to switch from old to new value halfway through the transition; now the new value is used immediately, as in JS.
This commit is contained in:
@@ -51,6 +51,7 @@ private:
|
||||
// aplied classes in order.
|
||||
template <typename T> void applyStyleProperties(float z, timestamp now);
|
||||
template <typename T> void applyStyleProperty(PropertyKey key, T &, float z, timestamp now);
|
||||
template <typename T> void applyTransitionedStyleProperty(PropertyKey key, T &, float z, timestamp now);
|
||||
|
||||
// Removes all expired style transitions.
|
||||
void cleanupAppliedStyleProperties(timestamp now);
|
||||
|
||||
25
include/mbgl/util/interpolate.hpp
Normal file
25
include/mbgl/util/interpolate.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef MBGL_UTIL_INTERPOLATE
|
||||
#define MBGL_UTIL_INTERPOLATE
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
template <typename T>
|
||||
T interpolate(const T a, const T b, const double t) {
|
||||
return a * (1.0 - t) + b * t;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::array<T, 4> interpolate(const std::array<T, 4>& a, const std::array<T, 4>& b, const double t) {
|
||||
return {{
|
||||
interpolate(a[0], b[0], t),
|
||||
interpolate(a[1], b[1], t),
|
||||
interpolate(a[2], b[2], t),
|
||||
interpolate(a[3], b[3], t)
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -57,11 +57,6 @@ inline T angle_to(const vec2<S>& a, const vec2<S>& b) {
|
||||
return std::atan2(a.y - b.y, a.x - b.x);
|
||||
}
|
||||
|
||||
template <typename T, typename S1, typename S2>
|
||||
inline T interp(S1 a, S2 b, T t) {
|
||||
return (a * ((T)1 - t)) + (b * t);
|
||||
}
|
||||
|
||||
// Reflect an angle around 0 degrees
|
||||
template <typename T>
|
||||
inline std::array<T, 2> flip(const std::array<T, 2>& c) {
|
||||
|
||||
@@ -29,12 +29,6 @@ public:
|
||||
virtual state update(timestamp now) const = 0;
|
||||
virtual ~transition();
|
||||
|
||||
protected:
|
||||
double interpolateDouble(double from, double to, double t) const;
|
||||
float interpolateFloat(float from, float to, double t) const;
|
||||
Color interpolateColor(Color from, Color to, double t) const;
|
||||
std::array<float, 2> interpolateFloatArray(std::array<float, 2> from, std::array<float, 2> to, double t) const;
|
||||
|
||||
protected:
|
||||
const timestamp start, duration;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <mbgl/geometry/resample.hpp>
|
||||
|
||||
#include <mbgl/util/math.hpp>
|
||||
#include <mbgl/util/interpolate.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@@ -43,7 +43,8 @@ Anchors resample(const std::vector<Coordinate> &vertices, float spacing,
|
||||
markedDistance += spacing;
|
||||
|
||||
float t = (markedDistance - distance) / segmentDist,
|
||||
x = util::interp(a.x, b.x, t), y = util::interp(a.y, b.y, t),
|
||||
x = util::interpolate(a.x, b.x, t),
|
||||
y = util::interpolate(a.y, b.y, t),
|
||||
s = minScales[added % len];
|
||||
|
||||
if (x >= 0 && x < 4096 && y >= 0 && y < 4096) {
|
||||
|
||||
@@ -1,35 +1,11 @@
|
||||
#include <mbgl/style/function_properties.hpp>
|
||||
#include <mbgl/style/types.hpp>
|
||||
#include <mbgl/util/interpolate.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T interpolate(T smaller, T larger, const float factor);
|
||||
|
||||
template <>
|
||||
inline float interpolate(const float smaller, const float larger, const float factor) {
|
||||
return (smaller * (1 - factor)) + (larger * factor);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool interpolate(const bool smaller, const bool larger, const float factor) {
|
||||
return interpolate(float(smaller), float(larger), factor);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Color interpolate(const Color smaller, const Color larger, const float factor) {
|
||||
return {{
|
||||
interpolate(smaller[0], larger[0], factor),
|
||||
interpolate(smaller[1], larger[1], factor),
|
||||
interpolate(smaller[2], larger[2], factor),
|
||||
interpolate(smaller[3], larger[3], factor)
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T defaultStopsValue();
|
||||
|
||||
@@ -70,10 +46,10 @@ T StopsFunction<T>::evaluate(float z) const {
|
||||
const float zoomProgress = z - smaller_z;
|
||||
if (base == 1.0f) {
|
||||
const float t = zoomProgress / zoomDiff;
|
||||
return interpolate<T>(smaller_val, larger_val, t);
|
||||
return util::interpolate(smaller_val, larger_val, t);
|
||||
} else {
|
||||
const float t = (std::pow(base, zoomProgress) - 1) / (std::pow(base, zoomDiff) - 1);
|
||||
return interpolate<T>(smaller_val, larger_val, t);
|
||||
return util::interpolate(smaller_val, larger_val, t);
|
||||
}
|
||||
} else if (larger) {
|
||||
return larger_val;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <mbgl/style/style_layer_group.hpp>
|
||||
#include <mbgl/style/property_fallback.hpp>
|
||||
|
||||
#include <mbgl/util/interpolate.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
StyleLayer::StyleLayer(const std::string &id, std::map<ClassID, ClassProperties> &&styles)
|
||||
@@ -117,27 +119,26 @@ private:
|
||||
const float z;
|
||||
};
|
||||
|
||||
inline float interpolate(const float a, const float b, const float t) {
|
||||
return (1.0f - t) * a + t * b;
|
||||
}
|
||||
|
||||
inline Color interpolate(const Color &a, const Color &b, const float t) {
|
||||
const float rt = 1.0f - t;
|
||||
return Color {{
|
||||
rt * a[0] + t * b[0],
|
||||
rt * a[1] + t * b[1],
|
||||
rt * a[2] + t * b[2],
|
||||
rt * a[3] + t * b[3]
|
||||
}};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T interpolate(const T a, const T b, const float t) {
|
||||
return t >= 0.5 ? b : a;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, const timestamp now) {
|
||||
auto it = appliedStyle.find(key);
|
||||
if (it != appliedStyle.end()) {
|
||||
AppliedClassProperties &applied = it->second;
|
||||
// Iterate through all properties that we need to apply in order.
|
||||
const PropertyEvaluator<T> evaluator(z);
|
||||
for (AppliedClassProperty &property : applied.properties) {
|
||||
if (now >= property.begin) {
|
||||
// We overwrite the current property with the new value.
|
||||
target = mapbox::util::apply_visitor(evaluator, property.value);
|
||||
} else {
|
||||
// Do not apply this property because its transition hasn't begun yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void StyleLayer::applyTransitionedStyleProperty(PropertyKey key, T &target, const float z, const timestamp now) {
|
||||
auto it = appliedStyle.find(key);
|
||||
if (it != appliedStyle.end()) {
|
||||
AppliedClassProperties &applied = it->second;
|
||||
@@ -150,7 +151,7 @@ void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, c
|
||||
} else if (now >= property.begin) {
|
||||
// We overwrite the current property partially with the new value.
|
||||
float progress = float(now - property.begin) / float(property.end - property.begin);
|
||||
target = interpolate(target, mapbox::util::apply_visitor(evaluator, property.value), progress);
|
||||
target = util::interpolate(target, mapbox::util::apply_visitor(evaluator, property.value), progress);
|
||||
} else {
|
||||
// Do not apply this property because its transition hasn't begun yet.
|
||||
}
|
||||
@@ -163,11 +164,11 @@ void StyleLayer::applyStyleProperties<FillProperties>(const float z, const times
|
||||
properties.set<FillProperties>();
|
||||
FillProperties &fill = properties.get<FillProperties>();
|
||||
applyStyleProperty(PropertyKey::FillAntialias, fill.antialias, z, now);
|
||||
applyStyleProperty(PropertyKey::FillOpacity, fill.opacity, z, now);
|
||||
applyStyleProperty(PropertyKey::FillColor, fill.fill_color, z, now);
|
||||
applyStyleProperty(PropertyKey::FillOutlineColor, fill.stroke_color, z, now);
|
||||
applyStyleProperty(PropertyKey::FillTranslateX, fill.translate[0], z, now);
|
||||
applyStyleProperty(PropertyKey::FillTranslateY, fill.translate[1], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::FillOpacity, fill.opacity, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::FillColor, fill.fill_color, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::FillOutlineColor, fill.stroke_color, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::FillTranslateX, fill.translate[0], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::FillTranslateY, fill.translate[1], z, now);
|
||||
applyStyleProperty(PropertyKey::FillTranslateAnchor, fill.translateAnchor, z, now);
|
||||
applyStyleProperty(PropertyKey::FillImage, fill.image, z, now);
|
||||
}
|
||||
@@ -176,16 +177,16 @@ template <>
|
||||
void StyleLayer::applyStyleProperties<LineProperties>(const float z, const timestamp now) {
|
||||
properties.set<LineProperties>();
|
||||
LineProperties &line = properties.get<LineProperties>();
|
||||
applyStyleProperty(PropertyKey::LineOpacity, line.opacity, z, now);
|
||||
applyStyleProperty(PropertyKey::LineColor, line.color, z, now);
|
||||
applyStyleProperty(PropertyKey::LineTranslateX, line.translate[0], z, now);
|
||||
applyStyleProperty(PropertyKey::LineTranslateY, line.translate[1], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineOpacity, line.opacity, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineColor, line.color, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineTranslateX, line.translate[0], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineTranslateY, line.translate[1], z, now);
|
||||
applyStyleProperty(PropertyKey::LineTranslateAnchor, line.translateAnchor, z, now);
|
||||
applyStyleProperty(PropertyKey::LineWidth, line.width, z, now);
|
||||
applyStyleProperty(PropertyKey::LineOffset, line.offset, z, now);
|
||||
applyStyleProperty(PropertyKey::LineBlur, line.blur, z, now);
|
||||
applyStyleProperty(PropertyKey::LineDashLand, line.dash_array[0], z, now);
|
||||
applyStyleProperty(PropertyKey::LineDashGap, line.dash_array[1], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineWidth, line.width, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineOffset, line.offset, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineBlur, line.blur, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineDashLand, line.dash_array[0], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::LineDashGap, line.dash_array[1], z, now);
|
||||
applyStyleProperty(PropertyKey::LineImage, line.image, z, now);
|
||||
}
|
||||
|
||||
@@ -193,47 +194,46 @@ template <>
|
||||
void StyleLayer::applyStyleProperties<SymbolProperties>(const float z, const timestamp now) {
|
||||
properties.set<SymbolProperties>();
|
||||
SymbolProperties &symbol = properties.get<SymbolProperties>();
|
||||
applyStyleProperty(PropertyKey::IconOpacity, symbol.icon.opacity, z, now);
|
||||
applyStyleProperty(PropertyKey::IconRotate, symbol.icon.rotate, z, now);
|
||||
applyStyleProperty(PropertyKey::IconSize, symbol.icon.size, z, now);
|
||||
applyStyleProperty(PropertyKey::IconColor, symbol.icon.color, z, now);
|
||||
applyStyleProperty(PropertyKey::IconHaloColor, symbol.icon.halo_color, z, now);
|
||||
applyStyleProperty(PropertyKey::IconHaloWidth, symbol.icon.halo_width, z, now);
|
||||
applyStyleProperty(PropertyKey::IconHaloBlur, symbol.icon.halo_blur, z, now);
|
||||
applyStyleProperty(PropertyKey::IconTranslateX, symbol.icon.translate[0], z, now);
|
||||
applyStyleProperty(PropertyKey::IconTranslateY, symbol.icon.translate[1], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconOpacity, symbol.icon.opacity, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconRotate, symbol.icon.rotate, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconSize, symbol.icon.size, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconColor, symbol.icon.color, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconHaloColor, symbol.icon.halo_color, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconHaloWidth, symbol.icon.halo_width, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconHaloBlur, symbol.icon.halo_blur, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconTranslateX, symbol.icon.translate[0], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::IconTranslateY, symbol.icon.translate[1], z, now);
|
||||
applyStyleProperty(PropertyKey::IconTranslateAnchor, symbol.icon.translate_anchor, z, now);
|
||||
|
||||
applyStyleProperty(PropertyKey::TextOpacity, symbol.text.opacity, z, now);
|
||||
applyStyleProperty(PropertyKey::TextSize, symbol.text.size, z, now);
|
||||
applyStyleProperty(PropertyKey::TextColor, symbol.text.color, z, now);
|
||||
applyStyleProperty(PropertyKey::TextHaloColor, symbol.text.halo_color, z, now);
|
||||
applyStyleProperty(PropertyKey::TextHaloWidth, symbol.text.halo_width, z, now);
|
||||
applyStyleProperty(PropertyKey::TextHaloBlur, symbol.text.halo_blur, z, now);
|
||||
applyStyleProperty(PropertyKey::TextTranslateX, symbol.text.translate[0], z, now);
|
||||
applyStyleProperty(PropertyKey::TextTranslateY, symbol.text.translate[1], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::TextOpacity, symbol.text.opacity, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::TextSize, symbol.text.size, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::TextColor, symbol.text.color, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::TextHaloColor, symbol.text.halo_color, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::TextHaloWidth, symbol.text.halo_width, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::TextHaloBlur, symbol.text.halo_blur, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::TextTranslateX, symbol.text.translate[0], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::TextTranslateY, symbol.text.translate[1], z, now);
|
||||
applyStyleProperty(PropertyKey::TextTranslateAnchor, symbol.text.translate_anchor, z, now);
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
void StyleLayer::applyStyleProperties<RasterProperties>(const float z, const timestamp now) {
|
||||
properties.set<RasterProperties>();
|
||||
RasterProperties &raster = properties.get<RasterProperties>();
|
||||
applyStyleProperty(PropertyKey::RasterOpacity, raster.opacity, z, now);
|
||||
applyStyleProperty(PropertyKey::RasterHueRotate, raster.hue_rotate, z, now);
|
||||
applyStyleProperty(PropertyKey::RasterBrightnessLow, raster.brightness[0], z, now);
|
||||
applyStyleProperty(PropertyKey::RasterBrightnessHigh, raster.brightness[1], z, now);
|
||||
applyStyleProperty(PropertyKey::RasterSaturation, raster.saturation, z, now);
|
||||
applyStyleProperty(PropertyKey::RasterContrast, raster.contrast, z, now);
|
||||
applyStyleProperty(PropertyKey::RasterFade, raster.fade, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::RasterOpacity, raster.opacity, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::RasterHueRotate, raster.hue_rotate, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::RasterBrightnessLow, raster.brightness[0], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::RasterBrightnessHigh, raster.brightness[1], z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::RasterSaturation, raster.saturation, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::RasterContrast, raster.contrast, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::RasterFade, raster.fade, z, now);
|
||||
}
|
||||
|
||||
template <>
|
||||
void StyleLayer::applyStyleProperties<BackgroundProperties>(const float z, const timestamp now) {
|
||||
properties.set<BackgroundProperties>();
|
||||
BackgroundProperties &background = properties.get<BackgroundProperties>();
|
||||
applyStyleProperty(PropertyKey::BackgroundColor, background.color, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::BackgroundColor, background.color, z, now);
|
||||
}
|
||||
|
||||
void StyleLayer::updateProperties(float z, const timestamp now) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <mbgl/text/rotation_range.hpp>
|
||||
|
||||
#include <mbgl/util/interpolate.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -117,8 +119,8 @@ rotatingRotatingCollisions(const CollisionRect &a, const CollisionRect &b,
|
||||
|
||||
double getAngle(const CollisionPoint &p1, const CollisionPoint &p2,
|
||||
CollisionAngle d, const CollisionPoint &corner) {
|
||||
return std::fmod(util::angle_between(util::interp(p1.x, p2.x, d),
|
||||
util::interp(p1.y, p2.y, d), corner.x,
|
||||
return std::fmod(util::angle_between(util::interpolate(p1.x, p2.x, d),
|
||||
util::interpolate(p1.y, p2.y, d), corner.x,
|
||||
corner.y) +
|
||||
2 * M_PI,
|
||||
2 * M_PI);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/util/transition.hpp>
|
||||
#include <mbgl/util/unitbezier.hpp>
|
||||
#include <mbgl/util/interpolate.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl { namespace util {
|
||||
@@ -8,71 +9,18 @@ UnitBezier ease(0, 0, 0.25, 1);
|
||||
|
||||
transition::~transition() {}
|
||||
|
||||
double transition::interpolateDouble(double from, double to, double t) const {
|
||||
return from + (to - from) * t;
|
||||
}
|
||||
|
||||
float transition::interpolateFloat(float from, float to, double t) const {
|
||||
return from + (to - from) * (float)t;
|
||||
}
|
||||
|
||||
mbgl::Color transition::interpolateColor(mbgl::Color from, mbgl::Color to, double t) const {
|
||||
return {{ interpolateFloat(from[0], to[0], t),
|
||||
interpolateFloat(from[1], to[1], t),
|
||||
interpolateFloat(from[2], to[2], t),
|
||||
interpolateFloat(from[3], to[3], t) }};
|
||||
}
|
||||
|
||||
std::array<float, 2> transition::interpolateFloatArray(std::array<float, 2> from, std::array<float, 2> to, double t) const {
|
||||
return {{ interpolateFloat(from[0], to[0], t), interpolateFloat(from[1], to[1], t) }};
|
||||
}
|
||||
|
||||
template <>
|
||||
transition::state ease_transition<double>::update(timestamp now) const {
|
||||
template <typename T>
|
||||
transition::state ease_transition<T>::update(timestamp now) const {
|
||||
float t = progress(now);
|
||||
if (t >= 1) {
|
||||
value = to;
|
||||
return complete;
|
||||
} else {
|
||||
value = interpolateDouble(from, to, ease.solve(t, 0.001));
|
||||
value = interpolate(from, to, ease.solve(t, 0.001));
|
||||
return running;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
transition::state ease_transition<mbgl::Color>::update(timestamp now) const {
|
||||
float t = progress(now);
|
||||
if (t >= 1) {
|
||||
value = to;
|
||||
return complete;
|
||||
} else {
|
||||
value = interpolateColor(from, to, ease.solve(t, 0.001));
|
||||
return running;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
transition::state ease_transition<float>::update(timestamp now) const {
|
||||
float t = progress(now);
|
||||
if (t >= 1) {
|
||||
value = to;
|
||||
return complete;
|
||||
} else {
|
||||
value = interpolateFloat(from, to, ease.solve(t, 0.001));
|
||||
return running;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
transition::state ease_transition<std::array<float, 2>>::update(timestamp now) const {
|
||||
float t = progress(now);
|
||||
if (t >= 1) {
|
||||
value = to;
|
||||
return complete;
|
||||
} else {
|
||||
value = interpolateFloatArray(from, to, ease.solve(t, 0.001));
|
||||
return running;
|
||||
}
|
||||
}
|
||||
template class ease_transition<double>;
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user