#include #include #include #include #include #include #include namespace mbgl { namespace style { template inline T defaultStopsValue(); template <> inline bool defaultStopsValue() { return true; } template <> inline float defaultStopsValue() { return 1.0f; } template <> inline Color defaultStopsValue() { return { 0, 0, 0, 1 }; } template <> inline std::vector defaultStopsValue() { return {{ 1, 0 }}; } template <> inline std::vector defaultStopsValue() { return {{}}; } template <> inline std::array defaultStopsValue() { return {{ 0, 0 }}; } template <> inline std::array defaultStopsValue() { return {{ 0, 0, 0, 0 }}; } template <> inline std::string defaultStopsValue() { return {}; } template <> inline TranslateAnchorType defaultStopsValue() { return {}; } template <> inline RotateAnchorType defaultStopsValue() { return {}; } template <> inline LineCapType defaultStopsValue() { return {}; } template <> inline LineJoinType defaultStopsValue() { return {}; } template <> inline SymbolPlacementType defaultStopsValue() { return {}; } template <> inline TextAnchorType defaultStopsValue() { return {}; } template <> inline TextJustifyType defaultStopsValue() { return {}; } template <> inline TextTransformType defaultStopsValue() { return {}; } template <> inline AlignmentType defaultStopsValue() { return {}; } template <> inline IconTextFitType defaultStopsValue() { return {}; }; template T PropertyEvaluator::operator()(const Function& fn) const { float base = fn.getBase(); const std::vector>& 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. return defaultStopsValue(); } } template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator>; template class PropertyEvaluator>; template class PropertyEvaluator>; template class PropertyEvaluator>; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template class PropertyEvaluator; template Faded CrossFadedPropertyEvaluator::operator()(const Undefined&) const { return calculate(defaultValue, defaultValue, defaultValue); } template Faded CrossFadedPropertyEvaluator::operator()(const T& constant) const { return calculate(constant, constant, constant); } template inline T getBiggestStopLessThan(const Function& function, float z) { const auto& stops = function.getStops(); for (uint32_t i = 0; i < stops.size(); i++) { if (stops[i].first > z) { return stops[i == 0 ? i : i - 1].second; } } return stops.at(stops.size() - 1).second; } template Faded CrossFadedPropertyEvaluator::operator()(const Function& function) const { return calculate(getBiggestStopLessThan(function, parameters.z - 1.0f), getBiggestStopLessThan(function, parameters.z), getBiggestStopLessThan(function, parameters.z + 1.0f)); } template Faded CrossFadedPropertyEvaluator::calculate(const T& min, const T& mid, const T& max) const { const float z = parameters.z; const float fraction = z - std::floor(z); const std::chrono::duration d = parameters.defaultFadeDuration; const float t = std::min((parameters.now - parameters.zoomHistory.lastIntegerZoomTime) / d, 1.0f); return z > parameters.zoomHistory.lastIntegerZoom ? Faded { min, mid, 2.0f, 1.0f, fraction + (1.0f - fraction) * t } : Faded { max, mid, 0.5f, 1.0f, 1 - (1 - t) * fraction }; } template class CrossFadedPropertyEvaluator; template class CrossFadedPropertyEvaluator>; } // namespace style } // namespace mbgl