[core] Move evaluation algorithm to Function

This commit is contained in:
John Firebaugh
2016-11-30 10:29:16 -08:00
parent 0adf830b9a
commit 05b0dcd0f8
5 changed files with 88 additions and 80 deletions

View File

@@ -218,6 +218,7 @@ set(MBGL_CORE_FILES
src/mbgl/style/cascade_parameters.hpp
src/mbgl/style/class_dictionary.cpp
src/mbgl/style/class_dictionary.hpp
src/mbgl/style/function.cpp
src/mbgl/style/layer.cpp
src/mbgl/style/layer_impl.cpp
src/mbgl/style/layer_impl.hpp

View File

@@ -1,7 +1,8 @@
#pragma once
#include <vector>
#include <cassert>
#include <utility>
#include <vector>
namespace mbgl {
namespace style {
@@ -20,6 +21,8 @@ public:
float getBase() const { return base; }
const std::vector<std::pair<float, T>>& getStops() const { return stops; }
T evaluate(float z) const;
friend bool operator==(const Function& lhs, const Function& rhs) {
return lhs.base == rhs.base && lhs.stops == rhs.stops;
}

View File

@@ -0,0 +1,81 @@
#include <mbgl/style/function.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/util/color.hpp>
#include <mbgl/util/interpolate.hpp>
#include <cmath>
namespace mbgl {
namespace style {
template <typename T>
T Function<T>::evaluate(float z) const {
bool smaller = false;
float smaller_z = 0.0f;
T smaller_val = T();
bool larger = false;
float larger_z = 0.0f;
T larger_val = T();
for (uint32_t i = 0; i < stops.size(); i++) {
float stop_z = stops[i].first;
T stop_val = stops[i].second;
if (stop_z <= z && (!smaller || smaller_z < stop_z)) {
smaller = true;
smaller_z = stop_z;
smaller_val = stop_val;
}
if (stop_z >= z && (!larger || larger_z > stop_z)) {
larger = true;
larger_z = stop_z;
larger_val = stop_val;
}
}
if (smaller && larger) {
if (larger_z == smaller_z || larger_val == smaller_val) {
return smaller_val;
}
const float zoomDiff = larger_z - smaller_z;
const float zoomProgress = z - smaller_z;
if (base == 1.0f) {
const float t = zoomProgress / zoomDiff;
return util::interpolate(smaller_val, larger_val, t);
} else {
const float t = (std::pow(base, zoomProgress) - 1) / (std::pow(base, zoomDiff) - 1);
return util::interpolate(smaller_val, larger_val, t);
}
} else if (larger) {
return larger_val;
} else if (smaller) {
return smaller_val;
} else {
// No stop defined.
assert(false);
return T();
}
}
template class Function<bool>;
template class Function<float>;
template class Function<Color>;
template class Function<std::vector<float>>;
template class Function<std::vector<std::string>>;
template class Function<std::array<float, 2>>;
template class Function<std::array<float, 4>>;
template class Function<std::string>;
template class Function<TranslateAnchorType>;
template class Function<RotateAnchorType>;
template class Function<CirclePitchScaleType>;
template class Function<LineCapType>;
template class Function<LineJoinType>;
template class Function<SymbolPlacementType>;
template class Function<TextAnchorType>;
template class Function<TextJustifyType>;
template class Function<TextTransformType>;
template class Function<AlignmentType>;
template class Function<IconTextFitType>;
} // namespace style
} // namespace mbgl

View File

@@ -1,87 +1,11 @@
#include <mbgl/style/property_evaluator.hpp>
#include <mbgl/style/property_evaluation_parameters.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/util/interpolate.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/color.hpp>
#include <cmath>
namespace mbgl {
namespace style {
template <typename T>
T PropertyEvaluator<T>::operator()(const Function<T>& fn) const {
float base = fn.getBase();
const std::vector<std::pair<float, T>>& stops = fn.getStops();
float z = parameters.z;
bool smaller = false;
float smaller_z = 0.0f;
T smaller_val = T();
bool larger = false;
float larger_z = 0.0f;
T larger_val = T();
for (uint32_t i = 0; i < stops.size(); i++) {
float stop_z = stops[i].first;
T stop_val = stops[i].second;
if (stop_z <= z && (!smaller || smaller_z < stop_z)) {
smaller = true;
smaller_z = stop_z;
smaller_val = stop_val;
}
if (stop_z >= z && (!larger || larger_z > stop_z)) {
larger = true;
larger_z = stop_z;
larger_val = stop_val;
}
}
if (smaller && larger) {
if (larger_z == smaller_z || larger_val == smaller_val) {
return smaller_val;
}
const float zoomDiff = larger_z - smaller_z;
const float zoomProgress = z - smaller_z;
if (base == 1.0f) {
const float t = zoomProgress / zoomDiff;
return util::interpolate(smaller_val, larger_val, t);
} else {
const float t = (std::pow(base, zoomProgress) - 1) / (std::pow(base, zoomDiff) - 1);
return util::interpolate(smaller_val, larger_val, t);
}
} else if (larger) {
return larger_val;
} else if (smaller) {
return smaller_val;
} else {
// No stop defined.
assert(false);
return T();
}
}
template class PropertyEvaluator<bool>;
template class PropertyEvaluator<float>;
template class PropertyEvaluator<Color>;
template class PropertyEvaluator<std::vector<float>>;
template class PropertyEvaluator<std::vector<std::string>>;
template class PropertyEvaluator<std::array<float, 2>>;
template class PropertyEvaluator<std::array<float, 4>>;
template class PropertyEvaluator<std::string>;
template class PropertyEvaluator<TranslateAnchorType>;
template class PropertyEvaluator<RotateAnchorType>;
template class PropertyEvaluator<CirclePitchScaleType>;
template class PropertyEvaluator<LineCapType>;
template class PropertyEvaluator<LineJoinType>;
template class PropertyEvaluator<SymbolPlacementType>;
template class PropertyEvaluator<TextAnchorType>;
template class PropertyEvaluator<TextJustifyType>;
template class PropertyEvaluator<TextTransformType>;
template class PropertyEvaluator<AlignmentType>;
template class PropertyEvaluator<IconTextFitType>;
template <typename T>
Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const Undefined&) const {
return calculate(defaultValue, defaultValue, defaultValue);

View File

@@ -1,13 +1,12 @@
#pragma once
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/property_evaluation_parameters.hpp>
#include <mbgl/util/interpolate.hpp>
namespace mbgl {
namespace style {
class PropertyEvaluationParameters;
template <typename T>
class PropertyEvaluator {
public:
@@ -19,7 +18,7 @@ public:
T operator()(const Undefined&) const { return defaultValue; }
T operator()(const T& constant) const { return constant; }
T operator()(const Function<T>&) const;
T operator()(const Function<T>& fn) const { return fn.evaluate(parameters.z); }
private:
const PropertyEvaluationParameters& parameters;