add interpolation

This commit is contained in:
Konstantin Käfer
2014-06-30 17:41:25 +02:00
parent 18d898fae7
commit a6f7696feb
9 changed files with 70 additions and 7 deletions

View File

@@ -94,6 +94,9 @@ module.exports = {
"min": 0,
"max": 1
}
},
"style.night": {
"fill-color": "blue"
}
}, {
"id": "borders",

View File

@@ -34,6 +34,10 @@ public:
void add(ClassID class_id, timestamp begin, timestamp end, const PropertyValue &value) {
properties.emplace_back(class_id, begin, end, value);
}
bool hasTransitions() const {
return properties.size() > 1;
}
};
}

View File

@@ -43,6 +43,8 @@ public:
// of applied classes.
void updateClasses();
bool hasTransitions() const;
public:
std::shared_ptr<Sprite> sprite;
std::shared_ptr<StyleLayerGroup> layers;

View File

@@ -42,6 +42,8 @@ public:
void setClasses(const std::vector<std::string> &class_names, timestamp now,
const PropertyTransition &defaultTransition);
bool hasTransitions() const;
private:
// Applies all properties from a class, if they haven't been applied already.
void applyClassProperties(ClassID class_id, std::set<PropertyKey> &already_applied,

View File

@@ -13,6 +13,7 @@ public:
const PropertyTransition &defaultTransition);
void updateProperties(float z, timestamp t);
bool hasTransitions() const;
public:
std::vector<std::shared_ptr<StyleLayer>> layers;
};

View File

@@ -495,7 +495,7 @@ void Map::render() {
#endif
// Schedule another rerender when we definitely need a next frame.
if (transform.needsTransition()) {
if (transform.needsTransition() || style->hasTransitions()) {
update();
}

View File

@@ -3,6 +3,7 @@
#include <llmr/style/style_parser.hpp>
#include <llmr/style/style_bucket.hpp>
#include <llmr/util/constants.hpp>
#include <llmr/util/time.hpp>
#include <csscolorparser/csscolorparser.hpp>
#include <rapidjson/document.h>
@@ -55,7 +56,7 @@ void Style::updateProperties(float z, timestamp t) {
}
void Style::setDefaultTransitionDuration(uint16_t duration_milliseconds) {
defaultTransition.duration = duration_milliseconds;
defaultTransition.duration = duration_milliseconds * 1_millisecond;
}
const std::vector<std::string> &Style::getAppliedClasses() const {
@@ -81,6 +82,16 @@ void Style::updateClasses() {
}
}
bool Style::hasTransitions() const {
if (layers) {
if (layers->hasTransitions()) {
return true;
}
}
return false;
}
void Style::loadJSON(const uint8_t *const data) {
uv::writelock lock(mtx);

View File

@@ -181,6 +181,25 @@ 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 t) {
auto it = appliedStyle.find(key);
@@ -189,15 +208,15 @@ void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, c
// Iterate through all properties that we need to apply in order.
const PropertyEvaluator<T> evaluator(z);
for (AppliedClassProperty &property : applied.properties) {
if (property.end >= t) {
if (t >= property.end) {
// We overwrite the current property with the new value.
target = util::apply_visitor(evaluator, property.value);
} else if (property.begin <= t) {
} else if (t >= property.begin) {
// We overwrite the current property partially with the new value.
float progress = float(t - property.begin) / float(property.end - property.begin);
target = util::apply_visitor(evaluator, property.value);
// target = (1.0f - progress) * target + (progress) *
// evaluateProperty(property.value, target, z);
target = interpolate(target, util::apply_visitor(evaluator, property.value), progress);
} else {
// Do not apply this property because its transition hasn't begun yet.
}
}
}
@@ -268,5 +287,13 @@ void StyleLayer::updateProperties(float z, const timestamp t) {
}
}
bool StyleLayer::hasTransitions() const {
for (const std::pair<PropertyKey, AppliedClassProperties> &pair : appliedStyle) {
if (pair.second.hasTransitions()) {
return true;
}
}
return false;
}
}

View File

@@ -1,3 +1,4 @@
#include <llmr/style/style_layer_group.hpp>
namespace llmr {
@@ -19,4 +20,16 @@ void StyleLayerGroup::updateProperties(float z, timestamp t) {
}
}
bool StyleLayerGroup::hasTransitions() const {
for (const std::shared_ptr<const StyleLayer> &layer: layers) {
if (layer) {
if (layer->hasTransitions()) {
return true;
}
}
}
return false;
}
}