diff options
Diffstat (limited to 'src/mbgl/style/layers')
30 files changed, 3095 insertions, 518 deletions
diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp index e47b41daa8..902f8f4810 100644 --- a/src/mbgl/style/layers/background_layer.cpp +++ b/src/mbgl/style/layers/background_layer.cpp @@ -80,26 +80,26 @@ PropertyValue<Color> BackgroundLayer::getDefaultBackgroundColor() { } PropertyValue<Color> BackgroundLayer::getBackgroundColor() const { - return impl().paint.template get<BackgroundColor>().value; + return impl().paint.backgroundColor.value; } void BackgroundLayer::setBackgroundColor(PropertyValue<Color> value) { if (value == getBackgroundColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundColor>().value = value; + impl_->paint.backgroundColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void BackgroundLayer::setBackgroundColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundColor>().options = options; + impl_->paint.backgroundColor.options = options; baseImpl = std::move(impl_); } TransitionOptions BackgroundLayer::getBackgroundColorTransition() const { - return impl().paint.template get<BackgroundColor>().options; + return impl().paint.backgroundColor.options; } PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() { @@ -107,26 +107,26 @@ PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() { } PropertyValue<std::string> BackgroundLayer::getBackgroundPattern() const { - return impl().paint.template get<BackgroundPattern>().value; + return impl().paint.backgroundPattern.value; } void BackgroundLayer::setBackgroundPattern(PropertyValue<std::string> value) { if (value == getBackgroundPattern()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundPattern>().value = value; + impl_->paint.backgroundPattern.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void BackgroundLayer::setBackgroundPatternTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundPattern>().options = options; + impl_->paint.backgroundPattern.options = options; baseImpl = std::move(impl_); } TransitionOptions BackgroundLayer::getBackgroundPatternTransition() const { - return impl().paint.template get<BackgroundPattern>().options; + return impl().paint.backgroundPattern.options; } PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() { @@ -134,26 +134,26 @@ PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() { } PropertyValue<float> BackgroundLayer::getBackgroundOpacity() const { - return impl().paint.template get<BackgroundOpacity>().value; + return impl().paint.backgroundOpacity.value; } void BackgroundLayer::setBackgroundOpacity(PropertyValue<float> value) { if (value == getBackgroundOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundOpacity>().value = value; + impl_->paint.backgroundOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void BackgroundLayer::setBackgroundOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<BackgroundOpacity>().options = options; + impl_->paint.backgroundOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions BackgroundLayer::getBackgroundOpacityTransition() const { - return impl().paint.template get<BackgroundOpacity>().options; + return impl().paint.backgroundOpacity.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/background_layer_properties.cpp b/src/mbgl/style/layers/background_layer_properties.cpp index ba3e638977..b6835f15c8 100644 --- a/src/mbgl/style/layers/background_layer_properties.cpp +++ b/src/mbgl/style/layers/background_layer_properties.cpp @@ -5,5 +5,47 @@ namespace mbgl { namespace style { +BackgroundPaintProperties::Unevaluated BackgroundPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + backgroundColor.transition(parameters, std::move(prior.backgroundColor)), + backgroundPattern.transition(parameters, std::move(prior.backgroundPattern)), + backgroundOpacity.transition(parameters, std::move(prior.backgroundOpacity)), + }; +} + +BackgroundPaintProperties::Unevaluated BackgroundPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<Color>>(backgroundColor.value), + Transitioning<PropertyValue<std::string>>(backgroundPattern.value), + Transitioning<PropertyValue<float>>(backgroundOpacity.value), + }; +} + +bool BackgroundPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || backgroundColor.value.hasDataDrivenPropertyDifference(other.backgroundColor.value) + || backgroundPattern.value.hasDataDrivenPropertyDifference(other.backgroundPattern.value) + || backgroundOpacity.value.hasDataDrivenPropertyDifference(other.backgroundOpacity.value) + ; +} + +bool BackgroundPaintProperties::Unevaluated::hasTransition() const { + return false + || backgroundColor.hasTransition() + || backgroundPattern.hasTransition() + || backgroundOpacity.hasTransition() + ; +} + +BackgroundPaintProperties::PossiblyEvaluated BackgroundPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + backgroundColor.evaluate(typename BackgroundColor::EvaluatorType(parameters, BackgroundColor::defaultValue()), parameters.now), + backgroundPattern.evaluate(typename BackgroundPattern::EvaluatorType(parameters, BackgroundPattern::defaultValue()), parameters.now), + backgroundOpacity.evaluate(typename BackgroundOpacity::EvaluatorType(parameters, BackgroundOpacity::defaultValue()), parameters.now), + }; +} + + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer_properties.hpp b/src/mbgl/style/layers/background_layer_properties.hpp index 3a61392fb4..bd62ef0a58 100644 --- a/src/mbgl/style/layers/background_layer_properties.hpp +++ b/src/mbgl/style/layers/background_layer_properties.hpp @@ -24,11 +24,39 @@ struct BackgroundOpacity : PaintProperty<float> { static float defaultValue() { return 1; } }; -class BackgroundPaintProperties : public Properties< - BackgroundColor, - BackgroundPattern, - BackgroundOpacity -> {}; +class BackgroundPaintProperties { +public: + + class PossiblyEvaluated { + public: + Color backgroundColor; + Faded<std::string> backgroundPattern; + float backgroundOpacity; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<Color>> backgroundColor; + style::Transitioning<PropertyValue<std::string>> backgroundPattern; + style::Transitioning<PropertyValue<float>> backgroundOpacity; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<Color>> backgroundColor; + style::Transitionable<PropertyValue<std::string>> backgroundPattern; + style::Transitionable<PropertyValue<float>> backgroundOpacity; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp index 1dae77547b..81a98cacec 100644 --- a/src/mbgl/style/layers/circle_layer.cpp +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -108,26 +108,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleRadius() { } PropertyValue<float> CircleLayer::getCircleRadius() const { - return impl().paint.template get<CircleRadius>().value; + return impl().paint.circleRadius.value; } void CircleLayer::setCircleRadius(PropertyValue<float> value) { if (value == getCircleRadius()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleRadius>().value = value; + impl_->paint.circleRadius.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleRadiusTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleRadius>().options = options; + impl_->paint.circleRadius.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleRadiusTransition() const { - return impl().paint.template get<CircleRadius>().options; + return impl().paint.circleRadius.options; } PropertyValue<Color> CircleLayer::getDefaultCircleColor() { @@ -135,26 +135,26 @@ PropertyValue<Color> CircleLayer::getDefaultCircleColor() { } PropertyValue<Color> CircleLayer::getCircleColor() const { - return impl().paint.template get<CircleColor>().value; + return impl().paint.circleColor.value; } void CircleLayer::setCircleColor(PropertyValue<Color> value) { if (value == getCircleColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleColor>().value = value; + impl_->paint.circleColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleColor>().options = options; + impl_->paint.circleColor.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleColorTransition() const { - return impl().paint.template get<CircleColor>().options; + return impl().paint.circleColor.options; } PropertyValue<float> CircleLayer::getDefaultCircleBlur() { @@ -162,26 +162,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleBlur() { } PropertyValue<float> CircleLayer::getCircleBlur() const { - return impl().paint.template get<CircleBlur>().value; + return impl().paint.circleBlur.value; } void CircleLayer::setCircleBlur(PropertyValue<float> value) { if (value == getCircleBlur()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleBlur>().value = value; + impl_->paint.circleBlur.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleBlurTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleBlur>().options = options; + impl_->paint.circleBlur.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleBlurTransition() const { - return impl().paint.template get<CircleBlur>().options; + return impl().paint.circleBlur.options; } PropertyValue<float> CircleLayer::getDefaultCircleOpacity() { @@ -189,26 +189,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleOpacity() { } PropertyValue<float> CircleLayer::getCircleOpacity() const { - return impl().paint.template get<CircleOpacity>().value; + return impl().paint.circleOpacity.value; } void CircleLayer::setCircleOpacity(PropertyValue<float> value) { if (value == getCircleOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleOpacity>().value = value; + impl_->paint.circleOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleOpacity>().options = options; + impl_->paint.circleOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleOpacityTransition() const { - return impl().paint.template get<CircleOpacity>().options; + return impl().paint.circleOpacity.options; } PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() { @@ -216,26 +216,26 @@ PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() { } PropertyValue<std::array<float, 2>> CircleLayer::getCircleTranslate() const { - return impl().paint.template get<CircleTranslate>().value; + return impl().paint.circleTranslate.value; } void CircleLayer::setCircleTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getCircleTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleTranslate>().value = value; + impl_->paint.circleTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleTranslate>().options = options; + impl_->paint.circleTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleTranslateTransition() const { - return impl().paint.template get<CircleTranslate>().options; + return impl().paint.circleTranslate.options; } PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor() { @@ -243,26 +243,26 @@ PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor( } PropertyValue<TranslateAnchorType> CircleLayer::getCircleTranslateAnchor() const { - return impl().paint.template get<CircleTranslateAnchor>().value; + return impl().paint.circleTranslateAnchor.value; } void CircleLayer::setCircleTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getCircleTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleTranslateAnchor>().value = value; + impl_->paint.circleTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleTranslateAnchor>().options = options; + impl_->paint.circleTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleTranslateAnchorTransition() const { - return impl().paint.template get<CircleTranslateAnchor>().options; + return impl().paint.circleTranslateAnchor.options; } PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() { @@ -270,26 +270,26 @@ PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() { } PropertyValue<CirclePitchScaleType> CircleLayer::getCirclePitchScale() const { - return impl().paint.template get<CirclePitchScale>().value; + return impl().paint.circlePitchScale.value; } void CircleLayer::setCirclePitchScale(PropertyValue<CirclePitchScaleType> value) { if (value == getCirclePitchScale()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CirclePitchScale>().value = value; + impl_->paint.circlePitchScale.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCirclePitchScaleTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CirclePitchScale>().options = options; + impl_->paint.circlePitchScale.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCirclePitchScaleTransition() const { - return impl().paint.template get<CirclePitchScale>().options; + return impl().paint.circlePitchScale.options; } PropertyValue<AlignmentType> CircleLayer::getDefaultCirclePitchAlignment() { @@ -297,26 +297,26 @@ PropertyValue<AlignmentType> CircleLayer::getDefaultCirclePitchAlignment() { } PropertyValue<AlignmentType> CircleLayer::getCirclePitchAlignment() const { - return impl().paint.template get<CirclePitchAlignment>().value; + return impl().paint.circlePitchAlignment.value; } void CircleLayer::setCirclePitchAlignment(PropertyValue<AlignmentType> value) { if (value == getCirclePitchAlignment()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CirclePitchAlignment>().value = value; + impl_->paint.circlePitchAlignment.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCirclePitchAlignmentTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CirclePitchAlignment>().options = options; + impl_->paint.circlePitchAlignment.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCirclePitchAlignmentTransition() const { - return impl().paint.template get<CirclePitchAlignment>().options; + return impl().paint.circlePitchAlignment.options; } PropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() { @@ -324,26 +324,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() { } PropertyValue<float> CircleLayer::getCircleStrokeWidth() const { - return impl().paint.template get<CircleStrokeWidth>().value; + return impl().paint.circleStrokeWidth.value; } void CircleLayer::setCircleStrokeWidth(PropertyValue<float> value) { if (value == getCircleStrokeWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeWidth>().value = value; + impl_->paint.circleStrokeWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleStrokeWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeWidth>().options = options; + impl_->paint.circleStrokeWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleStrokeWidthTransition() const { - return impl().paint.template get<CircleStrokeWidth>().options; + return impl().paint.circleStrokeWidth.options; } PropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() { @@ -351,26 +351,26 @@ PropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() { } PropertyValue<Color> CircleLayer::getCircleStrokeColor() const { - return impl().paint.template get<CircleStrokeColor>().value; + return impl().paint.circleStrokeColor.value; } void CircleLayer::setCircleStrokeColor(PropertyValue<Color> value) { if (value == getCircleStrokeColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeColor>().value = value; + impl_->paint.circleStrokeColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleStrokeColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeColor>().options = options; + impl_->paint.circleStrokeColor.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleStrokeColorTransition() const { - return impl().paint.template get<CircleStrokeColor>().options; + return impl().paint.circleStrokeColor.options; } PropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() { @@ -378,26 +378,26 @@ PropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() { } PropertyValue<float> CircleLayer::getCircleStrokeOpacity() const { - return impl().paint.template get<CircleStrokeOpacity>().value; + return impl().paint.circleStrokeOpacity.value; } void CircleLayer::setCircleStrokeOpacity(PropertyValue<float> value) { if (value == getCircleStrokeOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeOpacity>().value = value; + impl_->paint.circleStrokeOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void CircleLayer::setCircleStrokeOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<CircleStrokeOpacity>().options = options; + impl_->paint.circleStrokeOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions CircleLayer::getCircleStrokeOpacityTransition() const { - return impl().paint.template get<CircleStrokeOpacity>().options; + return impl().paint.circleStrokeOpacity.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/circle_layer_properties.cpp b/src/mbgl/style/layers/circle_layer_properties.cpp index af727fa36f..c9e654e635 100644 --- a/src/mbgl/style/layers/circle_layer_properties.cpp +++ b/src/mbgl/style/layers/circle_layer_properties.cpp @@ -5,5 +5,215 @@ namespace mbgl { namespace style { +CirclePaintProperties::Unevaluated CirclePaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + circleRadius.transition(parameters, std::move(prior.circleRadius)), + circleColor.transition(parameters, std::move(prior.circleColor)), + circleBlur.transition(parameters, std::move(prior.circleBlur)), + circleOpacity.transition(parameters, std::move(prior.circleOpacity)), + circleTranslate.transition(parameters, std::move(prior.circleTranslate)), + circleTranslateAnchor.transition(parameters, std::move(prior.circleTranslateAnchor)), + circlePitchScale.transition(parameters, std::move(prior.circlePitchScale)), + circlePitchAlignment.transition(parameters, std::move(prior.circlePitchAlignment)), + circleStrokeWidth.transition(parameters, std::move(prior.circleStrokeWidth)), + circleStrokeColor.transition(parameters, std::move(prior.circleStrokeColor)), + circleStrokeOpacity.transition(parameters, std::move(prior.circleStrokeOpacity)), + }; +} + +CirclePaintProperties::Unevaluated CirclePaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(circleRadius.value), + Transitioning<PropertyValue<Color>>(circleColor.value), + Transitioning<PropertyValue<float>>(circleBlur.value), + Transitioning<PropertyValue<float>>(circleOpacity.value), + Transitioning<PropertyValue<std::array<float, 2>>>(circleTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(circleTranslateAnchor.value), + Transitioning<PropertyValue<CirclePitchScaleType>>(circlePitchScale.value), + Transitioning<PropertyValue<AlignmentType>>(circlePitchAlignment.value), + Transitioning<PropertyValue<float>>(circleStrokeWidth.value), + Transitioning<PropertyValue<Color>>(circleStrokeColor.value), + Transitioning<PropertyValue<float>>(circleStrokeOpacity.value), + }; +} + +bool CirclePaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || circleRadius.value.hasDataDrivenPropertyDifference(other.circleRadius.value) + || circleColor.value.hasDataDrivenPropertyDifference(other.circleColor.value) + || circleBlur.value.hasDataDrivenPropertyDifference(other.circleBlur.value) + || circleOpacity.value.hasDataDrivenPropertyDifference(other.circleOpacity.value) + || circleTranslate.value.hasDataDrivenPropertyDifference(other.circleTranslate.value) + || circleTranslateAnchor.value.hasDataDrivenPropertyDifference(other.circleTranslateAnchor.value) + || circlePitchScale.value.hasDataDrivenPropertyDifference(other.circlePitchScale.value) + || circlePitchAlignment.value.hasDataDrivenPropertyDifference(other.circlePitchAlignment.value) + || circleStrokeWidth.value.hasDataDrivenPropertyDifference(other.circleStrokeWidth.value) + || circleStrokeColor.value.hasDataDrivenPropertyDifference(other.circleStrokeColor.value) + || circleStrokeOpacity.value.hasDataDrivenPropertyDifference(other.circleStrokeOpacity.value) + ; +} + +bool CirclePaintProperties::Unevaluated::hasTransition() const { + return false + || circleRadius.hasTransition() + || circleColor.hasTransition() + || circleBlur.hasTransition() + || circleOpacity.hasTransition() + || circleTranslate.hasTransition() + || circleTranslateAnchor.hasTransition() + || circlePitchScale.hasTransition() + || circlePitchAlignment.hasTransition() + || circleStrokeWidth.hasTransition() + || circleStrokeColor.hasTransition() + || circleStrokeOpacity.hasTransition() + ; +} + +CirclePaintProperties::PossiblyEvaluated CirclePaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + circleRadius.evaluate(typename CircleRadius::EvaluatorType(parameters, CircleRadius::defaultValue()), parameters.now), + circleColor.evaluate(typename CircleColor::EvaluatorType(parameters, CircleColor::defaultValue()), parameters.now), + circleBlur.evaluate(typename CircleBlur::EvaluatorType(parameters, CircleBlur::defaultValue()), parameters.now), + circleOpacity.evaluate(typename CircleOpacity::EvaluatorType(parameters, CircleOpacity::defaultValue()), parameters.now), + circleTranslate.evaluate(typename CircleTranslate::EvaluatorType(parameters, CircleTranslate::defaultValue()), parameters.now), + circleTranslateAnchor.evaluate(typename CircleTranslateAnchor::EvaluatorType(parameters, CircleTranslateAnchor::defaultValue()), parameters.now), + circlePitchScale.evaluate(typename CirclePitchScale::EvaluatorType(parameters, CirclePitchScale::defaultValue()), parameters.now), + circlePitchAlignment.evaluate(typename CirclePitchAlignment::EvaluatorType(parameters, CirclePitchAlignment::defaultValue()), parameters.now), + circleStrokeWidth.evaluate(typename CircleStrokeWidth::EvaluatorType(parameters, CircleStrokeWidth::defaultValue()), parameters.now), + circleStrokeColor.evaluate(typename CircleStrokeColor::EvaluatorType(parameters, CircleStrokeColor::defaultValue()), parameters.now), + circleStrokeOpacity.evaluate(typename CircleStrokeOpacity::EvaluatorType(parameters, CircleStrokeOpacity::defaultValue()), parameters.now), + }; +} + +CirclePaintProperties::Binders CirclePaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_radius::Type>::create(circleRadius, z, CircleRadius::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_color::Type>::create(circleColor, z, CircleColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_blur::Type>::create(circleBlur, z, CircleBlur::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(circleOpacity, z, CircleOpacity::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_stroke_width::Type>::create(circleStrokeWidth, z, CircleStrokeWidth::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_stroke_color::Type>::create(circleStrokeColor, z, CircleStrokeColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_stroke_opacity::Type>::create(circleStrokeOpacity, z, CircleStrokeOpacity::defaultValue()), + }; +} + +std::bitset<8> CirclePaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, circleRadius.isConstant()); + result.set(1, circleColor.isConstant()); + result.set(2, circleBlur.isConstant()); + result.set(3, circleOpacity.isConstant()); + result.set(4, circleStrokeWidth.isConstant()); + result.set(5, circleStrokeColor.isConstant()); + result.set(6, circleStrokeOpacity.isConstant()); + return result; +} + +std::vector<std::string> CirclePaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(circleRadius.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleRadius::Uniform::name() + : std::string()); + result.push_back(circleColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleColor::Uniform::name() + : std::string()); + result.push_back(circleBlur.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleBlur::Uniform::name() + : std::string()); + result.push_back(circleOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleOpacity::Uniform::name() + : std::string()); + result.push_back(circleStrokeWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleStrokeWidth::Uniform::name() + : std::string()); + result.push_back(circleStrokeColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleStrokeColor::Uniform::name() + : std::string()); + result.push_back(circleStrokeOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + CircleStrokeOpacity::Uniform::name() + : std::string()); + return result; +} + +void CirclePaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + circleRadius->populateVertexVector(feature, length); + circleColor->populateVertexVector(feature, length); + circleBlur->populateVertexVector(feature, length); + circleOpacity->populateVertexVector(feature, length); + circleStrokeWidth->populateVertexVector(feature, length); + circleStrokeColor->populateVertexVector(feature, length); + circleStrokeOpacity->populateVertexVector(feature, length); +} + +void CirclePaintProperties::Binders::upload(gl::Context& context) { + circleRadius->upload(context); + circleColor->upload(context); + circleBlur->upload(context); + circleOpacity->upload(context); + circleStrokeWidth->upload(context); + circleStrokeColor->upload(context); + circleStrokeOpacity->upload(context); +} + +CirclePaintProperties::Binders::AttributeBindings CirclePaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + circleRadius->attributeBinding(currentProperties.circleRadius), + circleColor->attributeBinding(currentProperties.circleColor), + circleBlur->attributeBinding(currentProperties.circleBlur), + circleOpacity->attributeBinding(currentProperties.circleOpacity), + circleStrokeWidth->attributeBinding(currentProperties.circleStrokeWidth), + circleStrokeColor->attributeBinding(currentProperties.circleStrokeColor), + circleStrokeOpacity->attributeBinding(currentProperties.circleStrokeOpacity), + }; +} + +CirclePaintProperties::Binders::UniformValues CirclePaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_radius>::Value { + circleRadius->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_color>::Value { + circleColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_blur>::Value { + circleBlur->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_opacity>::Value { + circleOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_stroke_width>::Value { + circleStrokeWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_stroke_color>::Value { + circleStrokeColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_stroke_opacity>::Value { + circleStrokeOpacity->interpolationFactor(currentZoom) + }, + typename uniforms::u_radius::Value { + circleRadius->uniformValue(currentProperties.circleRadius) + }, + typename uniforms::u_color::Value { + circleColor->uniformValue(currentProperties.circleColor) + }, + typename uniforms::u_blur::Value { + circleBlur->uniformValue(currentProperties.circleBlur) + }, + typename uniforms::u_opacity::Value { + circleOpacity->uniformValue(currentProperties.circleOpacity) + }, + typename uniforms::u_stroke_width::Value { + circleStrokeWidth->uniformValue(currentProperties.circleStrokeWidth) + }, + typename uniforms::u_stroke_color::Value { + circleStrokeColor->uniformValue(currentProperties.circleStrokeColor) + }, + typename uniforms::u_stroke_opacity::Value { + circleStrokeOpacity->uniformValue(currentProperties.circleStrokeOpacity) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp index bc0c961e75..e64cb27775 100644 --- a/src/mbgl/style/layers/circle_layer_properties.hpp +++ b/src/mbgl/style/layers/circle_layer_properties.hpp @@ -56,19 +56,116 @@ struct CircleStrokeOpacity : DataDrivenPaintProperty<float, attributes::a_stroke static float defaultValue() { return 1; } }; -class CirclePaintProperties : public Properties< - CircleRadius, - CircleColor, - CircleBlur, - CircleOpacity, - CircleTranslate, - CircleTranslateAnchor, - CirclePitchScale, - CirclePitchAlignment, - CircleStrokeWidth, - CircleStrokeColor, - CircleStrokeOpacity -> {}; +class CirclePaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_radius::Type>> circleRadius; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_color::Type>> circleColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_blur::Type>> circleBlur; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> circleOpacity; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_stroke_width::Type>> circleStrokeWidth; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_stroke_color::Type>> circleStrokeColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_stroke_opacity::Type>> circleStrokeOpacity; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_radius>, + ZoomInterpolatedAttribute<attributes::a_color>, + ZoomInterpolatedAttribute<attributes::a_blur>, + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_stroke_width>, + ZoomInterpolatedAttribute<attributes::a_stroke_color>, + ZoomInterpolatedAttribute<attributes::a_stroke_opacity> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_radius>, + InterpolationUniform<attributes::a_color>, + InterpolationUniform<attributes::a_blur>, + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_stroke_width>, + InterpolationUniform<attributes::a_stroke_color>, + InterpolationUniform<attributes::a_stroke_opacity>, + uniforms::u_radius, + uniforms::u_color, + uniforms::u_blur, + uniforms::u_opacity, + uniforms::u_stroke_width, + uniforms::u_stroke_color, + uniforms::u_stroke_opacity + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> circleRadius; + PossiblyEvaluatedPropertyValue<Color> circleColor; + PossiblyEvaluatedPropertyValue<float> circleBlur; + PossiblyEvaluatedPropertyValue<float> circleOpacity; + std::array<float, 2> circleTranslate; + TranslateAnchorType circleTranslateAnchor; + CirclePitchScaleType circlePitchScale; + AlignmentType circlePitchAlignment; + PossiblyEvaluatedPropertyValue<float> circleStrokeWidth; + PossiblyEvaluatedPropertyValue<Color> circleStrokeColor; + PossiblyEvaluatedPropertyValue<float> circleStrokeOpacity; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> circleRadius; + style::Transitioning<PropertyValue<Color>> circleColor; + style::Transitioning<PropertyValue<float>> circleBlur; + style::Transitioning<PropertyValue<float>> circleOpacity; + style::Transitioning<PropertyValue<std::array<float, 2>>> circleTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> circleTranslateAnchor; + style::Transitioning<PropertyValue<CirclePitchScaleType>> circlePitchScale; + style::Transitioning<PropertyValue<AlignmentType>> circlePitchAlignment; + style::Transitioning<PropertyValue<float>> circleStrokeWidth; + style::Transitioning<PropertyValue<Color>> circleStrokeColor; + style::Transitioning<PropertyValue<float>> circleStrokeOpacity; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> circleRadius; + style::Transitionable<PropertyValue<Color>> circleColor; + style::Transitionable<PropertyValue<float>> circleBlur; + style::Transitionable<PropertyValue<float>> circleOpacity; + style::Transitionable<PropertyValue<std::array<float, 2>>> circleTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> circleTranslateAnchor; + style::Transitionable<PropertyValue<CirclePitchScaleType>> circlePitchScale; + style::Transitionable<PropertyValue<AlignmentType>> circlePitchAlignment; + style::Transitionable<PropertyValue<float>> circleStrokeWidth; + style::Transitionable<PropertyValue<Color>> circleStrokeColor; + style::Transitionable<PropertyValue<float>> circleStrokeOpacity; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp index db90415daa..ddde6b6d06 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp @@ -108,26 +108,26 @@ PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionOpacity() { } PropertyValue<float> FillExtrusionLayer::getFillExtrusionOpacity() const { - return impl().paint.template get<FillExtrusionOpacity>().value; + return impl().paint.fillExtrusionOpacity.value; } void FillExtrusionLayer::setFillExtrusionOpacity(PropertyValue<float> value) { if (value == getFillExtrusionOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionOpacity>().value = value; + impl_->paint.fillExtrusionOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionOpacity>().options = options; + impl_->paint.fillExtrusionOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionOpacityTransition() const { - return impl().paint.template get<FillExtrusionOpacity>().options; + return impl().paint.fillExtrusionOpacity.options; } PropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() { @@ -135,26 +135,26 @@ PropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() { } PropertyValue<Color> FillExtrusionLayer::getFillExtrusionColor() const { - return impl().paint.template get<FillExtrusionColor>().value; + return impl().paint.fillExtrusionColor.value; } void FillExtrusionLayer::setFillExtrusionColor(PropertyValue<Color> value) { if (value == getFillExtrusionColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionColor>().value = value; + impl_->paint.fillExtrusionColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionColor>().options = options; + impl_->paint.fillExtrusionColor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionColorTransition() const { - return impl().paint.template get<FillExtrusionColor>().options; + return impl().paint.fillExtrusionColor.options; } PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionTranslate() { @@ -162,26 +162,26 @@ PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionT } PropertyValue<std::array<float, 2>> FillExtrusionLayer::getFillExtrusionTranslate() const { - return impl().paint.template get<FillExtrusionTranslate>().value; + return impl().paint.fillExtrusionTranslate.value; } void FillExtrusionLayer::setFillExtrusionTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getFillExtrusionTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionTranslate>().value = value; + impl_->paint.fillExtrusionTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionTranslate>().options = options; + impl_->paint.fillExtrusionTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionTranslateTransition() const { - return impl().paint.template get<FillExtrusionTranslate>().options; + return impl().paint.fillExtrusionTranslate.options; } PropertyValue<TranslateAnchorType> FillExtrusionLayer::getDefaultFillExtrusionTranslateAnchor() { @@ -189,26 +189,26 @@ PropertyValue<TranslateAnchorType> FillExtrusionLayer::getDefaultFillExtrusionTr } PropertyValue<TranslateAnchorType> FillExtrusionLayer::getFillExtrusionTranslateAnchor() const { - return impl().paint.template get<FillExtrusionTranslateAnchor>().value; + return impl().paint.fillExtrusionTranslateAnchor.value; } void FillExtrusionLayer::setFillExtrusionTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getFillExtrusionTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionTranslateAnchor>().value = value; + impl_->paint.fillExtrusionTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionTranslateAnchor>().options = options; + impl_->paint.fillExtrusionTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionTranslateAnchorTransition() const { - return impl().paint.template get<FillExtrusionTranslateAnchor>().options; + return impl().paint.fillExtrusionTranslateAnchor.options; } PropertyValue<std::string> FillExtrusionLayer::getDefaultFillExtrusionPattern() { @@ -216,26 +216,26 @@ PropertyValue<std::string> FillExtrusionLayer::getDefaultFillExtrusionPattern() } PropertyValue<std::string> FillExtrusionLayer::getFillExtrusionPattern() const { - return impl().paint.template get<FillExtrusionPattern>().value; + return impl().paint.fillExtrusionPattern.value; } void FillExtrusionLayer::setFillExtrusionPattern(PropertyValue<std::string> value) { if (value == getFillExtrusionPattern()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionPattern>().value = value; + impl_->paint.fillExtrusionPattern.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionPatternTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionPattern>().options = options; + impl_->paint.fillExtrusionPattern.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionPatternTransition() const { - return impl().paint.template get<FillExtrusionPattern>().options; + return impl().paint.fillExtrusionPattern.options; } PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() { @@ -243,26 +243,26 @@ PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() { } PropertyValue<float> FillExtrusionLayer::getFillExtrusionHeight() const { - return impl().paint.template get<FillExtrusionHeight>().value; + return impl().paint.fillExtrusionHeight.value; } void FillExtrusionLayer::setFillExtrusionHeight(PropertyValue<float> value) { if (value == getFillExtrusionHeight()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionHeight>().value = value; + impl_->paint.fillExtrusionHeight.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionHeightTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionHeight>().options = options; + impl_->paint.fillExtrusionHeight.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionHeightTransition() const { - return impl().paint.template get<FillExtrusionHeight>().options; + return impl().paint.fillExtrusionHeight.options; } PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() { @@ -270,26 +270,26 @@ PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() { } PropertyValue<float> FillExtrusionLayer::getFillExtrusionBase() const { - return impl().paint.template get<FillExtrusionBase>().value; + return impl().paint.fillExtrusionBase.value; } void FillExtrusionLayer::setFillExtrusionBase(PropertyValue<float> value) { if (value == getFillExtrusionBase()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionBase>().value = value; + impl_->paint.fillExtrusionBase.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillExtrusionLayer::setFillExtrusionBaseTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillExtrusionBase>().options = options; + impl_->paint.fillExtrusionBase.options = options; baseImpl = std::move(impl_); } TransitionOptions FillExtrusionLayer::getFillExtrusionBaseTransition() const { - return impl().paint.template get<FillExtrusionBase>().options; + return impl().paint.fillExtrusionBase.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp index 59572bd3ab..23aea2ce09 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp @@ -5,5 +5,139 @@ namespace mbgl { namespace style { +FillExtrusionPaintProperties::Unevaluated FillExtrusionPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + fillExtrusionOpacity.transition(parameters, std::move(prior.fillExtrusionOpacity)), + fillExtrusionColor.transition(parameters, std::move(prior.fillExtrusionColor)), + fillExtrusionTranslate.transition(parameters, std::move(prior.fillExtrusionTranslate)), + fillExtrusionTranslateAnchor.transition(parameters, std::move(prior.fillExtrusionTranslateAnchor)), + fillExtrusionPattern.transition(parameters, std::move(prior.fillExtrusionPattern)), + fillExtrusionHeight.transition(parameters, std::move(prior.fillExtrusionHeight)), + fillExtrusionBase.transition(parameters, std::move(prior.fillExtrusionBase)), + }; +} + +FillExtrusionPaintProperties::Unevaluated FillExtrusionPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(fillExtrusionOpacity.value), + Transitioning<PropertyValue<Color>>(fillExtrusionColor.value), + Transitioning<PropertyValue<std::array<float, 2>>>(fillExtrusionTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(fillExtrusionTranslateAnchor.value), + Transitioning<PropertyValue<std::string>>(fillExtrusionPattern.value), + Transitioning<PropertyValue<float>>(fillExtrusionHeight.value), + Transitioning<PropertyValue<float>>(fillExtrusionBase.value), + }; +} + +bool FillExtrusionPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || fillExtrusionOpacity.value.hasDataDrivenPropertyDifference(other.fillExtrusionOpacity.value) + || fillExtrusionColor.value.hasDataDrivenPropertyDifference(other.fillExtrusionColor.value) + || fillExtrusionTranslate.value.hasDataDrivenPropertyDifference(other.fillExtrusionTranslate.value) + || fillExtrusionTranslateAnchor.value.hasDataDrivenPropertyDifference(other.fillExtrusionTranslateAnchor.value) + || fillExtrusionPattern.value.hasDataDrivenPropertyDifference(other.fillExtrusionPattern.value) + || fillExtrusionHeight.value.hasDataDrivenPropertyDifference(other.fillExtrusionHeight.value) + || fillExtrusionBase.value.hasDataDrivenPropertyDifference(other.fillExtrusionBase.value) + ; +} + +bool FillExtrusionPaintProperties::Unevaluated::hasTransition() const { + return false + || fillExtrusionOpacity.hasTransition() + || fillExtrusionColor.hasTransition() + || fillExtrusionTranslate.hasTransition() + || fillExtrusionTranslateAnchor.hasTransition() + || fillExtrusionPattern.hasTransition() + || fillExtrusionHeight.hasTransition() + || fillExtrusionBase.hasTransition() + ; +} + +FillExtrusionPaintProperties::PossiblyEvaluated FillExtrusionPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + fillExtrusionOpacity.evaluate(typename FillExtrusionOpacity::EvaluatorType(parameters, FillExtrusionOpacity::defaultValue()), parameters.now), + fillExtrusionColor.evaluate(typename FillExtrusionColor::EvaluatorType(parameters, FillExtrusionColor::defaultValue()), parameters.now), + fillExtrusionTranslate.evaluate(typename FillExtrusionTranslate::EvaluatorType(parameters, FillExtrusionTranslate::defaultValue()), parameters.now), + fillExtrusionTranslateAnchor.evaluate(typename FillExtrusionTranslateAnchor::EvaluatorType(parameters, FillExtrusionTranslateAnchor::defaultValue()), parameters.now), + fillExtrusionPattern.evaluate(typename FillExtrusionPattern::EvaluatorType(parameters, FillExtrusionPattern::defaultValue()), parameters.now), + fillExtrusionHeight.evaluate(typename FillExtrusionHeight::EvaluatorType(parameters, FillExtrusionHeight::defaultValue()), parameters.now), + fillExtrusionBase.evaluate(typename FillExtrusionBase::EvaluatorType(parameters, FillExtrusionBase::defaultValue()), parameters.now), + }; +} + +FillExtrusionPaintProperties::Binders FillExtrusionPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<Color, typename attributes::a_color::Type>::create(fillExtrusionColor, z, FillExtrusionColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_height::Type>::create(fillExtrusionHeight, z, FillExtrusionHeight::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_base::Type>::create(fillExtrusionBase, z, FillExtrusionBase::defaultValue()), + }; +} + +std::bitset<8> FillExtrusionPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, fillExtrusionColor.isConstant()); + result.set(1, fillExtrusionHeight.isConstant()); + result.set(2, fillExtrusionBase.isConstant()); + return result; +} + +std::vector<std::string> FillExtrusionPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(fillExtrusionColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillExtrusionColor::Uniform::name() + : std::string()); + result.push_back(fillExtrusionHeight.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillExtrusionHeight::Uniform::name() + : std::string()); + result.push_back(fillExtrusionBase.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillExtrusionBase::Uniform::name() + : std::string()); + return result; +} + +void FillExtrusionPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + fillExtrusionColor->populateVertexVector(feature, length); + fillExtrusionHeight->populateVertexVector(feature, length); + fillExtrusionBase->populateVertexVector(feature, length); +} + +void FillExtrusionPaintProperties::Binders::upload(gl::Context& context) { + fillExtrusionColor->upload(context); + fillExtrusionHeight->upload(context); + fillExtrusionBase->upload(context); +} + +FillExtrusionPaintProperties::Binders::AttributeBindings FillExtrusionPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + fillExtrusionColor->attributeBinding(currentProperties.fillExtrusionColor), + fillExtrusionHeight->attributeBinding(currentProperties.fillExtrusionHeight), + fillExtrusionBase->attributeBinding(currentProperties.fillExtrusionBase), + }; +} + +FillExtrusionPaintProperties::Binders::UniformValues FillExtrusionPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_color>::Value { + fillExtrusionColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_height>::Value { + fillExtrusionHeight->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_base>::Value { + fillExtrusionBase->interpolationFactor(currentZoom) + }, + typename uniforms::u_color::Value { + fillExtrusionColor->uniformValue(currentProperties.fillExtrusionColor) + }, + typename uniforms::u_height::Value { + fillExtrusionHeight->uniformValue(currentProperties.fillExtrusionHeight) + }, + typename uniforms::u_base::Value { + fillExtrusionBase->uniformValue(currentProperties.fillExtrusionBase) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp index 19be59a2fe..4e94a0813a 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp @@ -40,15 +40,88 @@ struct FillExtrusionBase : DataDrivenPaintProperty<float, attributes::a_base, un static float defaultValue() { return 0; } }; -class FillExtrusionPaintProperties : public Properties< - FillExtrusionOpacity, - FillExtrusionColor, - FillExtrusionTranslate, - FillExtrusionTranslateAnchor, - FillExtrusionPattern, - FillExtrusionHeight, - FillExtrusionBase -> {}; +class FillExtrusionPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_color::Type>> fillExtrusionColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_height::Type>> fillExtrusionHeight; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_base::Type>> fillExtrusionBase; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_color>, + ZoomInterpolatedAttribute<attributes::a_height>, + ZoomInterpolatedAttribute<attributes::a_base> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_color>, + InterpolationUniform<attributes::a_height>, + InterpolationUniform<attributes::a_base>, + uniforms::u_color, + uniforms::u_height, + uniforms::u_base + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + float fillExtrusionOpacity; + PossiblyEvaluatedPropertyValue<Color> fillExtrusionColor; + std::array<float, 2> fillExtrusionTranslate; + TranslateAnchorType fillExtrusionTranslateAnchor; + Faded<std::string> fillExtrusionPattern; + PossiblyEvaluatedPropertyValue<float> fillExtrusionHeight; + PossiblyEvaluatedPropertyValue<float> fillExtrusionBase; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> fillExtrusionOpacity; + style::Transitioning<PropertyValue<Color>> fillExtrusionColor; + style::Transitioning<PropertyValue<std::array<float, 2>>> fillExtrusionTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> fillExtrusionTranslateAnchor; + style::Transitioning<PropertyValue<std::string>> fillExtrusionPattern; + style::Transitioning<PropertyValue<float>> fillExtrusionHeight; + style::Transitioning<PropertyValue<float>> fillExtrusionBase; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> fillExtrusionOpacity; + style::Transitionable<PropertyValue<Color>> fillExtrusionColor; + style::Transitionable<PropertyValue<std::array<float, 2>>> fillExtrusionTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> fillExtrusionTranslateAnchor; + style::Transitionable<PropertyValue<std::string>> fillExtrusionPattern; + style::Transitionable<PropertyValue<float>> fillExtrusionHeight; + style::Transitionable<PropertyValue<float>> fillExtrusionBase; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp index 2da131b6b2..7ab1799f88 100644 --- a/src/mbgl/style/layers/fill_layer.cpp +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -108,26 +108,26 @@ PropertyValue<bool> FillLayer::getDefaultFillAntialias() { } PropertyValue<bool> FillLayer::getFillAntialias() const { - return impl().paint.template get<FillAntialias>().value; + return impl().paint.fillAntialias.value; } void FillLayer::setFillAntialias(PropertyValue<bool> value) { if (value == getFillAntialias()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillAntialias>().value = value; + impl_->paint.fillAntialias.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillAntialiasTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillAntialias>().options = options; + impl_->paint.fillAntialias.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillAntialiasTransition() const { - return impl().paint.template get<FillAntialias>().options; + return impl().paint.fillAntialias.options; } PropertyValue<float> FillLayer::getDefaultFillOpacity() { @@ -135,26 +135,26 @@ PropertyValue<float> FillLayer::getDefaultFillOpacity() { } PropertyValue<float> FillLayer::getFillOpacity() const { - return impl().paint.template get<FillOpacity>().value; + return impl().paint.fillOpacity.value; } void FillLayer::setFillOpacity(PropertyValue<float> value) { if (value == getFillOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillOpacity>().value = value; + impl_->paint.fillOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillOpacity>().options = options; + impl_->paint.fillOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillOpacityTransition() const { - return impl().paint.template get<FillOpacity>().options; + return impl().paint.fillOpacity.options; } PropertyValue<Color> FillLayer::getDefaultFillColor() { @@ -162,26 +162,26 @@ PropertyValue<Color> FillLayer::getDefaultFillColor() { } PropertyValue<Color> FillLayer::getFillColor() const { - return impl().paint.template get<FillColor>().value; + return impl().paint.fillColor.value; } void FillLayer::setFillColor(PropertyValue<Color> value) { if (value == getFillColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillColor>().value = value; + impl_->paint.fillColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillColor>().options = options; + impl_->paint.fillColor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillColorTransition() const { - return impl().paint.template get<FillColor>().options; + return impl().paint.fillColor.options; } PropertyValue<Color> FillLayer::getDefaultFillOutlineColor() { @@ -189,26 +189,26 @@ PropertyValue<Color> FillLayer::getDefaultFillOutlineColor() { } PropertyValue<Color> FillLayer::getFillOutlineColor() const { - return impl().paint.template get<FillOutlineColor>().value; + return impl().paint.fillOutlineColor.value; } void FillLayer::setFillOutlineColor(PropertyValue<Color> value) { if (value == getFillOutlineColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillOutlineColor>().value = value; + impl_->paint.fillOutlineColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillOutlineColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillOutlineColor>().options = options; + impl_->paint.fillOutlineColor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillOutlineColorTransition() const { - return impl().paint.template get<FillOutlineColor>().options; + return impl().paint.fillOutlineColor.options; } PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() { @@ -216,26 +216,26 @@ PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() { } PropertyValue<std::array<float, 2>> FillLayer::getFillTranslate() const { - return impl().paint.template get<FillTranslate>().value; + return impl().paint.fillTranslate.value; } void FillLayer::setFillTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getFillTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillTranslate>().value = value; + impl_->paint.fillTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillTranslate>().options = options; + impl_->paint.fillTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillTranslateTransition() const { - return impl().paint.template get<FillTranslate>().options; + return impl().paint.fillTranslate.options; } PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() { @@ -243,26 +243,26 @@ PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() { } PropertyValue<TranslateAnchorType> FillLayer::getFillTranslateAnchor() const { - return impl().paint.template get<FillTranslateAnchor>().value; + return impl().paint.fillTranslateAnchor.value; } void FillLayer::setFillTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getFillTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillTranslateAnchor>().value = value; + impl_->paint.fillTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillTranslateAnchor>().options = options; + impl_->paint.fillTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillTranslateAnchorTransition() const { - return impl().paint.template get<FillTranslateAnchor>().options; + return impl().paint.fillTranslateAnchor.options; } PropertyValue<std::string> FillLayer::getDefaultFillPattern() { @@ -270,26 +270,26 @@ PropertyValue<std::string> FillLayer::getDefaultFillPattern() { } PropertyValue<std::string> FillLayer::getFillPattern() const { - return impl().paint.template get<FillPattern>().value; + return impl().paint.fillPattern.value; } void FillLayer::setFillPattern(PropertyValue<std::string> value) { if (value == getFillPattern()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<FillPattern>().value = value; + impl_->paint.fillPattern.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void FillLayer::setFillPatternTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<FillPattern>().options = options; + impl_->paint.fillPattern.options = options; baseImpl = std::move(impl_); } TransitionOptions FillLayer::getFillPatternTransition() const { - return impl().paint.template get<FillPattern>().options; + return impl().paint.fillPattern.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/fill_layer_properties.cpp b/src/mbgl/style/layers/fill_layer_properties.cpp index b07a083950..10ba8d43f6 100644 --- a/src/mbgl/style/layers/fill_layer_properties.cpp +++ b/src/mbgl/style/layers/fill_layer_properties.cpp @@ -5,5 +5,139 @@ namespace mbgl { namespace style { +FillPaintProperties::Unevaluated FillPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + fillAntialias.transition(parameters, std::move(prior.fillAntialias)), + fillOpacity.transition(parameters, std::move(prior.fillOpacity)), + fillColor.transition(parameters, std::move(prior.fillColor)), + fillOutlineColor.transition(parameters, std::move(prior.fillOutlineColor)), + fillTranslate.transition(parameters, std::move(prior.fillTranslate)), + fillTranslateAnchor.transition(parameters, std::move(prior.fillTranslateAnchor)), + fillPattern.transition(parameters, std::move(prior.fillPattern)), + }; +} + +FillPaintProperties::Unevaluated FillPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<bool>>(fillAntialias.value), + Transitioning<PropertyValue<float>>(fillOpacity.value), + Transitioning<PropertyValue<Color>>(fillColor.value), + Transitioning<PropertyValue<Color>>(fillOutlineColor.value), + Transitioning<PropertyValue<std::array<float, 2>>>(fillTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(fillTranslateAnchor.value), + Transitioning<PropertyValue<std::string>>(fillPattern.value), + }; +} + +bool FillPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || fillAntialias.value.hasDataDrivenPropertyDifference(other.fillAntialias.value) + || fillOpacity.value.hasDataDrivenPropertyDifference(other.fillOpacity.value) + || fillColor.value.hasDataDrivenPropertyDifference(other.fillColor.value) + || fillOutlineColor.value.hasDataDrivenPropertyDifference(other.fillOutlineColor.value) + || fillTranslate.value.hasDataDrivenPropertyDifference(other.fillTranslate.value) + || fillTranslateAnchor.value.hasDataDrivenPropertyDifference(other.fillTranslateAnchor.value) + || fillPattern.value.hasDataDrivenPropertyDifference(other.fillPattern.value) + ; +} + +bool FillPaintProperties::Unevaluated::hasTransition() const { + return false + || fillAntialias.hasTransition() + || fillOpacity.hasTransition() + || fillColor.hasTransition() + || fillOutlineColor.hasTransition() + || fillTranslate.hasTransition() + || fillTranslateAnchor.hasTransition() + || fillPattern.hasTransition() + ; +} + +FillPaintProperties::PossiblyEvaluated FillPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + fillAntialias.evaluate(typename FillAntialias::EvaluatorType(parameters, FillAntialias::defaultValue()), parameters.now), + fillOpacity.evaluate(typename FillOpacity::EvaluatorType(parameters, FillOpacity::defaultValue()), parameters.now), + fillColor.evaluate(typename FillColor::EvaluatorType(parameters, FillColor::defaultValue()), parameters.now), + fillOutlineColor.evaluate(typename FillOutlineColor::EvaluatorType(parameters, FillOutlineColor::defaultValue()), parameters.now), + fillTranslate.evaluate(typename FillTranslate::EvaluatorType(parameters, FillTranslate::defaultValue()), parameters.now), + fillTranslateAnchor.evaluate(typename FillTranslateAnchor::EvaluatorType(parameters, FillTranslateAnchor::defaultValue()), parameters.now), + fillPattern.evaluate(typename FillPattern::EvaluatorType(parameters, FillPattern::defaultValue()), parameters.now), + }; +} + +FillPaintProperties::Binders FillPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(fillOpacity, z, FillOpacity::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_color::Type>::create(fillColor, z, FillColor::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_outline_color::Type>::create(fillOutlineColor, z, FillOutlineColor::defaultValue()), + }; +} + +std::bitset<8> FillPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, fillOpacity.isConstant()); + result.set(1, fillColor.isConstant()); + result.set(2, fillOutlineColor.isConstant()); + return result; +} + +std::vector<std::string> FillPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(fillOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillOpacity::Uniform::name() + : std::string()); + result.push_back(fillColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillColor::Uniform::name() + : std::string()); + result.push_back(fillOutlineColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + FillOutlineColor::Uniform::name() + : std::string()); + return result; +} + +void FillPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + fillOpacity->populateVertexVector(feature, length); + fillColor->populateVertexVector(feature, length); + fillOutlineColor->populateVertexVector(feature, length); +} + +void FillPaintProperties::Binders::upload(gl::Context& context) { + fillOpacity->upload(context); + fillColor->upload(context); + fillOutlineColor->upload(context); +} + +FillPaintProperties::Binders::AttributeBindings FillPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + fillOpacity->attributeBinding(currentProperties.fillOpacity), + fillColor->attributeBinding(currentProperties.fillColor), + fillOutlineColor->attributeBinding(currentProperties.fillOutlineColor), + }; +} + +FillPaintProperties::Binders::UniformValues FillPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_opacity>::Value { + fillOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_color>::Value { + fillColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_outline_color>::Value { + fillOutlineColor->interpolationFactor(currentZoom) + }, + typename uniforms::u_opacity::Value { + fillOpacity->uniformValue(currentProperties.fillOpacity) + }, + typename uniforms::u_color::Value { + fillColor->uniformValue(currentProperties.fillColor) + }, + typename uniforms::u_outline_color::Value { + fillOutlineColor->uniformValue(currentProperties.fillOutlineColor) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp index cb01194515..23041d4a9c 100644 --- a/src/mbgl/style/layers/fill_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_layer_properties.hpp @@ -40,15 +40,88 @@ struct FillPattern : CrossFadedPaintProperty<std::string> { static std::string defaultValue() { return ""; } }; -class FillPaintProperties : public Properties< - FillAntialias, - FillOpacity, - FillColor, - FillOutlineColor, - FillTranslate, - FillTranslateAnchor, - FillPattern -> {}; +class FillPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> fillOpacity; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_color::Type>> fillColor; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_outline_color::Type>> fillOutlineColor; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_color>, + ZoomInterpolatedAttribute<attributes::a_outline_color> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_color>, + InterpolationUniform<attributes::a_outline_color>, + uniforms::u_opacity, + uniforms::u_color, + uniforms::u_outline_color + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + bool fillAntialias; + PossiblyEvaluatedPropertyValue<float> fillOpacity; + PossiblyEvaluatedPropertyValue<Color> fillColor; + PossiblyEvaluatedPropertyValue<Color> fillOutlineColor; + std::array<float, 2> fillTranslate; + TranslateAnchorType fillTranslateAnchor; + Faded<std::string> fillPattern; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<bool>> fillAntialias; + style::Transitioning<PropertyValue<float>> fillOpacity; + style::Transitioning<PropertyValue<Color>> fillColor; + style::Transitioning<PropertyValue<Color>> fillOutlineColor; + style::Transitioning<PropertyValue<std::array<float, 2>>> fillTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> fillTranslateAnchor; + style::Transitioning<PropertyValue<std::string>> fillPattern; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<bool>> fillAntialias; + style::Transitionable<PropertyValue<float>> fillOpacity; + style::Transitionable<PropertyValue<Color>> fillColor; + style::Transitionable<PropertyValue<Color>> fillOutlineColor; + style::Transitionable<PropertyValue<std::array<float, 2>>> fillTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> fillTranslateAnchor; + style::Transitionable<PropertyValue<std::string>> fillPattern; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/heatmap_layer.cpp b/src/mbgl/style/layers/heatmap_layer.cpp index df00558135..a82eceb026 100644 --- a/src/mbgl/style/layers/heatmap_layer.cpp +++ b/src/mbgl/style/layers/heatmap_layer.cpp @@ -108,26 +108,26 @@ PropertyValue<float> HeatmapLayer::getDefaultHeatmapRadius() { } PropertyValue<float> HeatmapLayer::getHeatmapRadius() const { - return impl().paint.template get<HeatmapRadius>().value; + return impl().paint.heatmapRadius.value; } void HeatmapLayer::setHeatmapRadius(PropertyValue<float> value) { if (value == getHeatmapRadius()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapRadius>().value = value; + impl_->paint.heatmapRadius.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapRadiusTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapRadius>().options = options; + impl_->paint.heatmapRadius.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapRadiusTransition() const { - return impl().paint.template get<HeatmapRadius>().options; + return impl().paint.heatmapRadius.options; } PropertyValue<float> HeatmapLayer::getDefaultHeatmapWeight() { @@ -135,26 +135,26 @@ PropertyValue<float> HeatmapLayer::getDefaultHeatmapWeight() { } PropertyValue<float> HeatmapLayer::getHeatmapWeight() const { - return impl().paint.template get<HeatmapWeight>().value; + return impl().paint.heatmapWeight.value; } void HeatmapLayer::setHeatmapWeight(PropertyValue<float> value) { if (value == getHeatmapWeight()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapWeight>().value = value; + impl_->paint.heatmapWeight.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapWeightTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapWeight>().options = options; + impl_->paint.heatmapWeight.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapWeightTransition() const { - return impl().paint.template get<HeatmapWeight>().options; + return impl().paint.heatmapWeight.options; } PropertyValue<float> HeatmapLayer::getDefaultHeatmapIntensity() { @@ -162,26 +162,26 @@ PropertyValue<float> HeatmapLayer::getDefaultHeatmapIntensity() { } PropertyValue<float> HeatmapLayer::getHeatmapIntensity() const { - return impl().paint.template get<HeatmapIntensity>().value; + return impl().paint.heatmapIntensity.value; } void HeatmapLayer::setHeatmapIntensity(PropertyValue<float> value) { if (value == getHeatmapIntensity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapIntensity>().value = value; + impl_->paint.heatmapIntensity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapIntensityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapIntensity>().options = options; + impl_->paint.heatmapIntensity.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapIntensityTransition() const { - return impl().paint.template get<HeatmapIntensity>().options; + return impl().paint.heatmapIntensity.options; } ColorRampPropertyValue HeatmapLayer::getDefaultHeatmapColor() { @@ -191,26 +191,26 @@ ColorRampPropertyValue HeatmapLayer::getDefaultHeatmapColor() { } ColorRampPropertyValue HeatmapLayer::getHeatmapColor() const { - return impl().paint.template get<HeatmapColor>().value; + return impl().paint.heatmapColor.value; } void HeatmapLayer::setHeatmapColor(ColorRampPropertyValue value) { if (value == getHeatmapColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapColor>().value = value; + impl_->paint.heatmapColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapColor>().options = options; + impl_->paint.heatmapColor.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapColorTransition() const { - return impl().paint.template get<HeatmapColor>().options; + return impl().paint.heatmapColor.options; } PropertyValue<float> HeatmapLayer::getDefaultHeatmapOpacity() { @@ -218,26 +218,26 @@ PropertyValue<float> HeatmapLayer::getDefaultHeatmapOpacity() { } PropertyValue<float> HeatmapLayer::getHeatmapOpacity() const { - return impl().paint.template get<HeatmapOpacity>().value; + return impl().paint.heatmapOpacity.value; } void HeatmapLayer::setHeatmapOpacity(PropertyValue<float> value) { if (value == getHeatmapOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapOpacity>().value = value; + impl_->paint.heatmapOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HeatmapLayer::setHeatmapOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HeatmapOpacity>().options = options; + impl_->paint.heatmapOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions HeatmapLayer::getHeatmapOpacityTransition() const { - return impl().paint.template get<HeatmapOpacity>().options; + return impl().paint.heatmapOpacity.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/heatmap_layer_properties.cpp b/src/mbgl/style/layers/heatmap_layer_properties.cpp index 2edb839589..947749a5ad 100644 --- a/src/mbgl/style/layers/heatmap_layer_properties.cpp +++ b/src/mbgl/style/layers/heatmap_layer_properties.cpp @@ -5,5 +5,115 @@ namespace mbgl { namespace style { +HeatmapPaintProperties::Unevaluated HeatmapPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + heatmapRadius.transition(parameters, std::move(prior.heatmapRadius)), + heatmapWeight.transition(parameters, std::move(prior.heatmapWeight)), + heatmapIntensity.transition(parameters, std::move(prior.heatmapIntensity)), + heatmapColor.transition(parameters, std::move(prior.heatmapColor)), + heatmapOpacity.transition(parameters, std::move(prior.heatmapOpacity)), + }; +} + +HeatmapPaintProperties::Unevaluated HeatmapPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(heatmapRadius.value), + Transitioning<PropertyValue<float>>(heatmapWeight.value), + Transitioning<PropertyValue<float>>(heatmapIntensity.value), + Transitioning<ColorRampPropertyValue>(heatmapColor.value), + Transitioning<PropertyValue<float>>(heatmapOpacity.value), + }; +} + +bool HeatmapPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || heatmapRadius.value.hasDataDrivenPropertyDifference(other.heatmapRadius.value) + || heatmapWeight.value.hasDataDrivenPropertyDifference(other.heatmapWeight.value) + || heatmapIntensity.value.hasDataDrivenPropertyDifference(other.heatmapIntensity.value) + || heatmapColor.value.hasDataDrivenPropertyDifference(other.heatmapColor.value) + || heatmapOpacity.value.hasDataDrivenPropertyDifference(other.heatmapOpacity.value) + ; +} + +bool HeatmapPaintProperties::Unevaluated::hasTransition() const { + return false + || heatmapRadius.hasTransition() + || heatmapWeight.hasTransition() + || heatmapIntensity.hasTransition() + || heatmapColor.hasTransition() + || heatmapOpacity.hasTransition() + ; +} + +HeatmapPaintProperties::PossiblyEvaluated HeatmapPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + heatmapRadius.evaluate(typename HeatmapRadius::EvaluatorType(parameters, HeatmapRadius::defaultValue()), parameters.now), + heatmapWeight.evaluate(typename HeatmapWeight::EvaluatorType(parameters, HeatmapWeight::defaultValue()), parameters.now), + heatmapIntensity.evaluate(typename HeatmapIntensity::EvaluatorType(parameters, HeatmapIntensity::defaultValue()), parameters.now), + heatmapColor.evaluate(typename HeatmapColor::EvaluatorType(parameters, HeatmapColor::defaultValue()), parameters.now), + heatmapOpacity.evaluate(typename HeatmapOpacity::EvaluatorType(parameters, HeatmapOpacity::defaultValue()), parameters.now), + }; +} + +HeatmapPaintProperties::Binders HeatmapPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_radius::Type>::create(heatmapRadius, z, HeatmapRadius::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_weight::Type>::create(heatmapWeight, z, HeatmapWeight::defaultValue()), + }; +} + +std::bitset<8> HeatmapPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, heatmapRadius.isConstant()); + result.set(1, heatmapWeight.isConstant()); + return result; +} + +std::vector<std::string> HeatmapPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(heatmapRadius.isConstant() + ? std::string("#define HAS_UNIFORM_") + HeatmapRadius::Uniform::name() + : std::string()); + result.push_back(heatmapWeight.isConstant() + ? std::string("#define HAS_UNIFORM_") + HeatmapWeight::Uniform::name() + : std::string()); + return result; +} + +void HeatmapPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + heatmapRadius->populateVertexVector(feature, length); + heatmapWeight->populateVertexVector(feature, length); +} + +void HeatmapPaintProperties::Binders::upload(gl::Context& context) { + heatmapRadius->upload(context); + heatmapWeight->upload(context); +} + +HeatmapPaintProperties::Binders::AttributeBindings HeatmapPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + heatmapRadius->attributeBinding(currentProperties.heatmapRadius), + heatmapWeight->attributeBinding(currentProperties.heatmapWeight), + }; +} + +HeatmapPaintProperties::Binders::UniformValues HeatmapPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_radius>::Value { + heatmapRadius->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_weight>::Value { + heatmapWeight->interpolationFactor(currentZoom) + }, + typename uniforms::u_radius::Value { + heatmapRadius->uniformValue(currentProperties.heatmapRadius) + }, + typename uniforms::u_weight::Value { + heatmapWeight->uniformValue(currentProperties.heatmapWeight) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/heatmap_layer_properties.hpp b/src/mbgl/style/layers/heatmap_layer_properties.hpp index 4d49a52c72..02627e0b46 100644 --- a/src/mbgl/style/layers/heatmap_layer_properties.hpp +++ b/src/mbgl/style/layers/heatmap_layer_properties.hpp @@ -31,13 +31,78 @@ struct HeatmapOpacity : PaintProperty<float> { static float defaultValue() { return 1; } }; -class HeatmapPaintProperties : public Properties< - HeatmapRadius, - HeatmapWeight, - HeatmapIntensity, - HeatmapColor, - HeatmapOpacity -> {}; +class HeatmapPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_radius::Type>> heatmapRadius; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_weight::Type>> heatmapWeight; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_radius>, + ZoomInterpolatedAttribute<attributes::a_weight> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_radius>, + InterpolationUniform<attributes::a_weight>, + uniforms::u_radius, + uniforms::u_weight + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> heatmapRadius; + PossiblyEvaluatedPropertyValue<float> heatmapWeight; + float heatmapIntensity; + Color heatmapColor; + float heatmapOpacity; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> heatmapRadius; + style::Transitioning<PropertyValue<float>> heatmapWeight; + style::Transitioning<PropertyValue<float>> heatmapIntensity; + style::Transitioning<ColorRampPropertyValue> heatmapColor; + style::Transitioning<PropertyValue<float>> heatmapOpacity; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> heatmapRadius; + style::Transitionable<PropertyValue<float>> heatmapWeight; + style::Transitionable<PropertyValue<float>> heatmapIntensity; + style::Transitionable<ColorRampPropertyValue> heatmapColor; + style::Transitionable<PropertyValue<float>> heatmapOpacity; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/hillshade_layer.cpp b/src/mbgl/style/layers/hillshade_layer.cpp index fb96c681cc..fa61bba317 100644 --- a/src/mbgl/style/layers/hillshade_layer.cpp +++ b/src/mbgl/style/layers/hillshade_layer.cpp @@ -86,26 +86,26 @@ PropertyValue<float> HillshadeLayer::getDefaultHillshadeIlluminationDirection() } PropertyValue<float> HillshadeLayer::getHillshadeIlluminationDirection() const { - return impl().paint.template get<HillshadeIlluminationDirection>().value; + return impl().paint.hillshadeIlluminationDirection.value; } void HillshadeLayer::setHillshadeIlluminationDirection(PropertyValue<float> value) { if (value == getHillshadeIlluminationDirection()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeIlluminationDirection>().value = value; + impl_->paint.hillshadeIlluminationDirection.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeIlluminationDirectionTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeIlluminationDirection>().options = options; + impl_->paint.hillshadeIlluminationDirection.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeIlluminationDirectionTransition() const { - return impl().paint.template get<HillshadeIlluminationDirection>().options; + return impl().paint.hillshadeIlluminationDirection.options; } PropertyValue<HillshadeIlluminationAnchorType> HillshadeLayer::getDefaultHillshadeIlluminationAnchor() { @@ -113,26 +113,26 @@ PropertyValue<HillshadeIlluminationAnchorType> HillshadeLayer::getDefaultHillsha } PropertyValue<HillshadeIlluminationAnchorType> HillshadeLayer::getHillshadeIlluminationAnchor() const { - return impl().paint.template get<HillshadeIlluminationAnchor>().value; + return impl().paint.hillshadeIlluminationAnchor.value; } void HillshadeLayer::setHillshadeIlluminationAnchor(PropertyValue<HillshadeIlluminationAnchorType> value) { if (value == getHillshadeIlluminationAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeIlluminationAnchor>().value = value; + impl_->paint.hillshadeIlluminationAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeIlluminationAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeIlluminationAnchor>().options = options; + impl_->paint.hillshadeIlluminationAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeIlluminationAnchorTransition() const { - return impl().paint.template get<HillshadeIlluminationAnchor>().options; + return impl().paint.hillshadeIlluminationAnchor.options; } PropertyValue<float> HillshadeLayer::getDefaultHillshadeExaggeration() { @@ -140,26 +140,26 @@ PropertyValue<float> HillshadeLayer::getDefaultHillshadeExaggeration() { } PropertyValue<float> HillshadeLayer::getHillshadeExaggeration() const { - return impl().paint.template get<HillshadeExaggeration>().value; + return impl().paint.hillshadeExaggeration.value; } void HillshadeLayer::setHillshadeExaggeration(PropertyValue<float> value) { if (value == getHillshadeExaggeration()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeExaggeration>().value = value; + impl_->paint.hillshadeExaggeration.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeExaggerationTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeExaggeration>().options = options; + impl_->paint.hillshadeExaggeration.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeExaggerationTransition() const { - return impl().paint.template get<HillshadeExaggeration>().options; + return impl().paint.hillshadeExaggeration.options; } PropertyValue<Color> HillshadeLayer::getDefaultHillshadeShadowColor() { @@ -167,26 +167,26 @@ PropertyValue<Color> HillshadeLayer::getDefaultHillshadeShadowColor() { } PropertyValue<Color> HillshadeLayer::getHillshadeShadowColor() const { - return impl().paint.template get<HillshadeShadowColor>().value; + return impl().paint.hillshadeShadowColor.value; } void HillshadeLayer::setHillshadeShadowColor(PropertyValue<Color> value) { if (value == getHillshadeShadowColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeShadowColor>().value = value; + impl_->paint.hillshadeShadowColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeShadowColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeShadowColor>().options = options; + impl_->paint.hillshadeShadowColor.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeShadowColorTransition() const { - return impl().paint.template get<HillshadeShadowColor>().options; + return impl().paint.hillshadeShadowColor.options; } PropertyValue<Color> HillshadeLayer::getDefaultHillshadeHighlightColor() { @@ -194,26 +194,26 @@ PropertyValue<Color> HillshadeLayer::getDefaultHillshadeHighlightColor() { } PropertyValue<Color> HillshadeLayer::getHillshadeHighlightColor() const { - return impl().paint.template get<HillshadeHighlightColor>().value; + return impl().paint.hillshadeHighlightColor.value; } void HillshadeLayer::setHillshadeHighlightColor(PropertyValue<Color> value) { if (value == getHillshadeHighlightColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeHighlightColor>().value = value; + impl_->paint.hillshadeHighlightColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeHighlightColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeHighlightColor>().options = options; + impl_->paint.hillshadeHighlightColor.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeHighlightColorTransition() const { - return impl().paint.template get<HillshadeHighlightColor>().options; + return impl().paint.hillshadeHighlightColor.options; } PropertyValue<Color> HillshadeLayer::getDefaultHillshadeAccentColor() { @@ -221,26 +221,26 @@ PropertyValue<Color> HillshadeLayer::getDefaultHillshadeAccentColor() { } PropertyValue<Color> HillshadeLayer::getHillshadeAccentColor() const { - return impl().paint.template get<HillshadeAccentColor>().value; + return impl().paint.hillshadeAccentColor.value; } void HillshadeLayer::setHillshadeAccentColor(PropertyValue<Color> value) { if (value == getHillshadeAccentColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeAccentColor>().value = value; + impl_->paint.hillshadeAccentColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void HillshadeLayer::setHillshadeAccentColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<HillshadeAccentColor>().options = options; + impl_->paint.hillshadeAccentColor.options = options; baseImpl = std::move(impl_); } TransitionOptions HillshadeLayer::getHillshadeAccentColorTransition() const { - return impl().paint.template get<HillshadeAccentColor>().options; + return impl().paint.hillshadeAccentColor.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/hillshade_layer_properties.cpp b/src/mbgl/style/layers/hillshade_layer_properties.cpp index f296ab4520..c51e557d6e 100644 --- a/src/mbgl/style/layers/hillshade_layer_properties.cpp +++ b/src/mbgl/style/layers/hillshade_layer_properties.cpp @@ -5,5 +5,62 @@ namespace mbgl { namespace style { +HillshadePaintProperties::Unevaluated HillshadePaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + hillshadeIlluminationDirection.transition(parameters, std::move(prior.hillshadeIlluminationDirection)), + hillshadeIlluminationAnchor.transition(parameters, std::move(prior.hillshadeIlluminationAnchor)), + hillshadeExaggeration.transition(parameters, std::move(prior.hillshadeExaggeration)), + hillshadeShadowColor.transition(parameters, std::move(prior.hillshadeShadowColor)), + hillshadeHighlightColor.transition(parameters, std::move(prior.hillshadeHighlightColor)), + hillshadeAccentColor.transition(parameters, std::move(prior.hillshadeAccentColor)), + }; +} + +HillshadePaintProperties::Unevaluated HillshadePaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(hillshadeIlluminationDirection.value), + Transitioning<PropertyValue<HillshadeIlluminationAnchorType>>(hillshadeIlluminationAnchor.value), + Transitioning<PropertyValue<float>>(hillshadeExaggeration.value), + Transitioning<PropertyValue<Color>>(hillshadeShadowColor.value), + Transitioning<PropertyValue<Color>>(hillshadeHighlightColor.value), + Transitioning<PropertyValue<Color>>(hillshadeAccentColor.value), + }; +} + +bool HillshadePaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || hillshadeIlluminationDirection.value.hasDataDrivenPropertyDifference(other.hillshadeIlluminationDirection.value) + || hillshadeIlluminationAnchor.value.hasDataDrivenPropertyDifference(other.hillshadeIlluminationAnchor.value) + || hillshadeExaggeration.value.hasDataDrivenPropertyDifference(other.hillshadeExaggeration.value) + || hillshadeShadowColor.value.hasDataDrivenPropertyDifference(other.hillshadeShadowColor.value) + || hillshadeHighlightColor.value.hasDataDrivenPropertyDifference(other.hillshadeHighlightColor.value) + || hillshadeAccentColor.value.hasDataDrivenPropertyDifference(other.hillshadeAccentColor.value) + ; +} + +bool HillshadePaintProperties::Unevaluated::hasTransition() const { + return false + || hillshadeIlluminationDirection.hasTransition() + || hillshadeIlluminationAnchor.hasTransition() + || hillshadeExaggeration.hasTransition() + || hillshadeShadowColor.hasTransition() + || hillshadeHighlightColor.hasTransition() + || hillshadeAccentColor.hasTransition() + ; +} + +HillshadePaintProperties::PossiblyEvaluated HillshadePaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + hillshadeIlluminationDirection.evaluate(typename HillshadeIlluminationDirection::EvaluatorType(parameters, HillshadeIlluminationDirection::defaultValue()), parameters.now), + hillshadeIlluminationAnchor.evaluate(typename HillshadeIlluminationAnchor::EvaluatorType(parameters, HillshadeIlluminationAnchor::defaultValue()), parameters.now), + hillshadeExaggeration.evaluate(typename HillshadeExaggeration::EvaluatorType(parameters, HillshadeExaggeration::defaultValue()), parameters.now), + hillshadeShadowColor.evaluate(typename HillshadeShadowColor::EvaluatorType(parameters, HillshadeShadowColor::defaultValue()), parameters.now), + hillshadeHighlightColor.evaluate(typename HillshadeHighlightColor::EvaluatorType(parameters, HillshadeHighlightColor::defaultValue()), parameters.now), + hillshadeAccentColor.evaluate(typename HillshadeAccentColor::EvaluatorType(parameters, HillshadeAccentColor::defaultValue()), parameters.now), + }; +} + + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/hillshade_layer_properties.hpp b/src/mbgl/style/layers/hillshade_layer_properties.hpp index 260d7ea808..df54c5a381 100644 --- a/src/mbgl/style/layers/hillshade_layer_properties.hpp +++ b/src/mbgl/style/layers/hillshade_layer_properties.hpp @@ -36,14 +36,48 @@ struct HillshadeAccentColor : PaintProperty<Color> { static Color defaultValue() { return Color::black(); } }; -class HillshadePaintProperties : public Properties< - HillshadeIlluminationDirection, - HillshadeIlluminationAnchor, - HillshadeExaggeration, - HillshadeShadowColor, - HillshadeHighlightColor, - HillshadeAccentColor -> {}; +class HillshadePaintProperties { +public: + + class PossiblyEvaluated { + public: + float hillshadeIlluminationDirection; + HillshadeIlluminationAnchorType hillshadeIlluminationAnchor; + float hillshadeExaggeration; + Color hillshadeShadowColor; + Color hillshadeHighlightColor; + Color hillshadeAccentColor; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> hillshadeIlluminationDirection; + style::Transitioning<PropertyValue<HillshadeIlluminationAnchorType>> hillshadeIlluminationAnchor; + style::Transitioning<PropertyValue<float>> hillshadeExaggeration; + style::Transitioning<PropertyValue<Color>> hillshadeShadowColor; + style::Transitioning<PropertyValue<Color>> hillshadeHighlightColor; + style::Transitioning<PropertyValue<Color>> hillshadeAccentColor; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> hillshadeIlluminationDirection; + style::Transitionable<PropertyValue<HillshadeIlluminationAnchorType>> hillshadeIlluminationAnchor; + style::Transitionable<PropertyValue<float>> hillshadeExaggeration; + style::Transitionable<PropertyValue<Color>> hillshadeShadowColor; + style::Transitionable<PropertyValue<Color>> hillshadeHighlightColor; + style::Transitionable<PropertyValue<Color>> hillshadeAccentColor; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index 4e80a7bf74..8094f76955 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -52,7 +52,11 @@ std::unique_ptr<Layer> <%- camelize(type) %>Layer::cloneRef(const std::string& i <% if (layoutProperties.length) { -%> void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - layout.stringify(writer); + writer.StartObject(); +<% for (const property of layoutProperties) { -%> + conversion::stringify<<%- camelize(property.name) %>>(writer, layout.<%- camelizeWithLeadingLowercase(property.name) %>); +<% } -%> + writer.EndObject(); } <% } else { -%> void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const { @@ -127,14 +131,14 @@ void <%- camelize(type) %>Layer::setMaxZoom(float maxZoom) { } <%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { - return impl().layout.get<<%- camelize(property.name) %>>(); + return impl().layout.<%- camelizeWithLeadingLowercase(property.name) %>; } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) { if (value == get<%- camelize(property.name) %>()) return; auto impl_ = mutableImpl(); - impl_->layout.get<<%- camelize(property.name) %>>() = value; + impl_->layout.<%- camelizeWithLeadingLowercase(property.name) %> = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -153,26 +157,26 @@ void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyV } <%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { - return impl().paint.template get<<%- camelize(property.name) %>>().value; + return impl().paint.<%- camelizeWithLeadingLowercase(property.name) %>.value; } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) { if (value == get<%- camelize(property.name) %>()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<<%- camelize(property.name) %>>().value = value; + impl_->paint.<%- camelizeWithLeadingLowercase(property.name) %>.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>Transition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<<%- camelize(property.name) %>>().options = options; + impl_->paint.<%- camelizeWithLeadingLowercase(property.name) %>.options = options; baseImpl = std::move(impl_); } TransitionOptions <%- camelize(type) %>Layer::get<%- camelize(property.name) %>Transition() const { - return impl().paint.template get<<%- camelize(property.name) %>>().options; + return impl().paint.<%- camelizeWithLeadingLowercase(property.name) %>.options; } <% } -%> diff --git a/src/mbgl/style/layers/layer_properties.cpp.ejs b/src/mbgl/style/layers/layer_properties.cpp.ejs index e5523e5439..5b3e3a9e67 100644 --- a/src/mbgl/style/layers/layer_properties.cpp.ejs +++ b/src/mbgl/style/layers/layer_properties.cpp.ejs @@ -10,5 +10,207 @@ namespace mbgl { namespace style { +<% if (layoutProperties.length) { -%> +bool operator==(const <%- camelize(type) %>LayoutProperties::Unevaluated& lhs, const <%- camelize(type) %>LayoutProperties::Unevaluated& rhs) { + return true +<% for (const property of layoutProperties) { -%> + && lhs.<%- camelizeWithLeadingLowercase(property.name) %> == rhs.<%- camelizeWithLeadingLowercase(property.name) %> +<% } -%> + ; +} + +<%- camelize(type) %>LayoutProperties::PossiblyEvaluated <%- camelize(type) %>LayoutProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { +<% for (const property of layoutProperties) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.evaluate(typename <%- camelize(property.name) %>::EvaluatorType(parameters, <%- camelize(property.name) %>::defaultValue()), parameters.now), +<% } -%> + }; +} + +<%- camelize(type) %>LayoutProperties::Evaluated <%- camelize(type) %>LayoutProperties::PossiblyEvaluated::evaluate(float z, const GeometryTileFeature& feature) const { + return Evaluated { +<% for (const property of layoutProperties) { -%> +<% if (isDataDriven(property)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.evaluate(feature, z, <%- camelize(property.name) %>::defaultValue()), +<% } else { -%> + <%- camelizeWithLeadingLowercase(property.name) %>, +<% } -%> +<% } -%> + }; +} + +<% } -%> +<%- camelize(type) %>PaintProperties::Unevaluated <%- camelize(type) %>PaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { +<% for (const property of paintProperties) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.transition(parameters, std::move(prior.<%- camelizeWithLeadingLowercase(property.name) %>)), +<% } -%> + }; +} + +<%- camelize(type) %>PaintProperties::Unevaluated <%- camelize(type) %>PaintProperties::Transitionable::untransitioned() const { + return Unevaluated { +<% for (const property of paintProperties) { -%> + Transitioning<<%- propertyValueType(property) %>>(<%- camelizeWithLeadingLowercase(property.name) %>.value), +<% } -%> + }; +} + +bool <%- camelize(type) %>PaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false +<% for (const property of paintProperties) { -%> + || <%- camelizeWithLeadingLowercase(property.name) %>.value.hasDataDrivenPropertyDifference(other.<%- camelizeWithLeadingLowercase(property.name) %>.value) +<% } -%> + ; +} + +bool <%- camelize(type) %>PaintProperties::Unevaluated::hasTransition() const { + return false +<% for (const property of paintProperties) { -%> + || <%- camelizeWithLeadingLowercase(property.name) %>.hasTransition() +<% } -%> + ; +} + +<%- camelize(type) %>PaintProperties::PossiblyEvaluated <%- camelize(type) %>PaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { +<% for (const property of paintProperties) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>.evaluate(typename <%- camelize(property.name) %>::EvaluatorType(parameters, <%- camelize(property.name) %>::defaultValue()), parameters.now), +<% } -%> + }; +} + +<% if (type !== "symbol" && type !== "background" && type !== "raster" && type !== "hillshade") { -%> +<%- camelize(type) %>PaintProperties::Binders <%- camelize(type) %>PaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + PaintPropertyBinder<<%- evaluatedType(property) %>, typename <%- attributeType(property, type) %>::Type>::create(<%- camelizeWithLeadingLowercase(property.name) %>, z, <%- camelize(property.name) %>::defaultValue()), +<% } -%> + }; +} + +std::bitset<8> <%- camelize(type) %>PaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; +<% for (let i = 0; i < paintProperties.filter(isDataDriven).length; i++) { -%> + result.set(<%- i %>, <%- camelizeWithLeadingLowercase(paintProperties.filter(isDataDriven)[i].name) %>.isConstant()); +<% } -%> + return result; +} + +std::vector<std::string> <%- camelize(type) %>PaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + result.push_back(<%- camelizeWithLeadingLowercase(property.name) %>.isConstant() + ? std::string("#define HAS_UNIFORM_") + <%- camelize(property.name) %>::Uniform::name() + : std::string()); +<% } -%> + return result; +} + +void <%- camelize(type) %>PaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->populateVertexVector(feature, length); +<% } -%> +} + +void <%- camelize(type) %>PaintProperties::Binders::upload(gl::Context& context) { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->upload(context); +<% } -%> +} + +<%- camelize(type) %>PaintProperties::Binders::AttributeBindings <%- camelize(type) %>PaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->attributeBinding(currentProperties.<%- camelizeWithLeadingLowercase(property.name) %>), +<% } -%> + }; +} + +<%- camelize(type) %>PaintProperties::Binders::UniformValues <%- camelize(type) %>PaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + typename InterpolationUniform<<%- attributeType(property, type) %>>::Value { + <%- camelizeWithLeadingLowercase(property.name) %>->interpolationFactor(currentZoom) + }, +<% } -%> +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + typename <%- uniformType(property, type) %>::Value { + <%- camelizeWithLeadingLowercase(property.name) %>->uniformValue(currentProperties.<%- camelizeWithLeadingLowercase(property.name) %>) + }, +<% } -%> + }; +} +<% } -%> + +<% if (type === "symbol") { -%> +<% for (const subtype of ['icon', 'text']) { + const properties = paintProperties.filter(({name}) => name.startsWith(`${subtype}-`)); +%> + +<%- camelize(subtype) %>PaintProperties::Binders <%- camelize(subtype) %>PaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { +<% for (const property of properties.filter(isDataDriven)) { -%> + PaintPropertyBinder<<%- evaluatedType(property) %>, typename <%- attributeType(property, type) %>::Type>::create(<%- camelizeWithLeadingLowercase(property.name) %>, z, <%- camelize(property.name) %>::defaultValue()), +<% } -%> + }; +} + +std::bitset<8> <%- camelize(subtype) %>PaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; +<% for (let i = 0; i < properties.filter(isDataDriven).length; i++) { -%> + result.set(<%- i %>, <%- camelizeWithLeadingLowercase(properties.filter(isDataDriven)[i].name) %>.isConstant()); +<% } -%> + return result; +} + +std::vector<std::string> <%- camelize(subtype) %>PaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; +<% for (const property of properties.filter(isDataDriven)) { -%> + result.push_back(<%- camelizeWithLeadingLowercase(property.name) %>.isConstant() + ? std::string("#define HAS_UNIFORM_") + <%- camelize(property.name) %>::Uniform::name() + : std::string()); +<% } -%> + return result; +} + +void <%- camelize(subtype) %>PaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { +<% for (const property of properties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->populateVertexVector(feature, length); +<% } -%> +} + +void <%- camelize(subtype) %>PaintProperties::Binders::upload(gl::Context& context) { +<% for (const property of properties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->upload(context); +<% } -%> +} + +<%- camelize(subtype) %>PaintProperties::Binders::AttributeBindings <%- camelize(subtype) %>PaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { +<% for (const property of properties.filter(isDataDriven)) { -%> + <%- camelizeWithLeadingLowercase(property.name) %>->attributeBinding(currentProperties.<%- camelizeWithLeadingLowercase(property.name) %>), +<% } -%> + }; +} + +<%- camelize(subtype) %>PaintProperties::Binders::UniformValues <%- camelize(subtype) %>PaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { +<% for (const property of properties.filter(isDataDriven)) { -%> + typename InterpolationUniform<<%- attributeType(property, type) %>>::Value { + <%- camelizeWithLeadingLowercase(property.name) %>->interpolationFactor(currentZoom) + }, +<% } -%> +<% for (const property of properties.filter(isDataDriven)) { -%> + typename <%- uniformType(property, type) %>::Value { + <%- camelizeWithLeadingLowercase(property.name) %>->uniformValue(currentProperties.<%- camelizeWithLeadingLowercase(property.name) %>) + }, +<% } -%> + }; +} + +<% } -%> +<% } -%> + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs index 694d9a62b7..c1b404bd6d 100644 --- a/src/mbgl/style/layers/layer_properties.hpp.ejs +++ b/src/mbgl/style/layers/layer_properties.hpp.ejs @@ -36,20 +36,158 @@ struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> <% } -%> <% if (layoutProperties.length) { -%> -class <%- camelize(type) %>LayoutProperties : public Properties< -<% for (const property of layoutProperties.slice(0, -1)) { -%> - <%- camelize(property.name) %>, +class <%- camelize(type) %>LayoutProperties { +public: + class Evaluated { + public: +<% for (const property of layoutProperties) { -%> + <%- evaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + }; + + class PossiblyEvaluated { + public: +<% for (const property of layoutProperties) { -%> + <%- possiblyEvaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + Evaluated evaluate(float z, const GeometryTileFeature& feature) const; + }; + + class Unevaluated { + public: +<% for (const property of layoutProperties) { -%> + <%- propertyValueType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + + friend bool operator==(const Unevaluated&, const Unevaluated&); + friend inline bool operator!=(const Unevaluated& lhs, const Unevaluated& rhs) { return !(lhs == rhs); } + }; +}; + <% } -%> - <%- camelize(layoutProperties.slice(-1)[0].name) %> -> {}; +class <%- camelize(type) %>PaintProperties { +public: +<% if (type !== "symbol" && type !== "background" && type !== "raster" && type !== "hillshade") { -%> + class PossiblyEvaluated; + + class Binders { + public: +<% for (const property of paintProperties.filter(isDataDriven)) { -%> + std::unique_ptr<PaintPropertyBinder<<%- evaluatedType(property) %>, typename <%- attributeType(property, type) %>::Type>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + <%- paintProperties.filter(isDataDriven).map(property => `ZoomInterpolatedAttribute<${attributeType(property, type)}>`).join(',\n ') %> + >; + + using Uniforms = gl::Uniforms< + <%- paintProperties.filter(isDataDriven).map(property => `InterpolationUniform<${attributeType(property, type)}>`) + .concat(paintProperties.filter(isDataDriven).map(property => uniformType(property, type))).join(',\n ') %> + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; +<% } -%> + + class PossiblyEvaluated { + public: +<% for (const property of paintProperties) { -%> + <%- possiblyEvaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> +<% if (type !== "symbol" && type !== "background" && type !== "raster" && type !== "hillshade") { -%> + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; +<% } -%> + }; + + class Unevaluated { + public: +<% for (const property of paintProperties) { -%> + style::Transitioning<<%- propertyValueType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: +<% for (const property of paintProperties) { -%> + style::Transitionable<<%- propertyValueType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + +<% if (type === "symbol") { -%> +// {icon,text}-specific paint-property packs for use in the symbol Programs. +// Since each program deals either with icons or text, using a smaller property set +// lets us avoid unnecessarily binding attributes for properties the program wouldn't use. + +<% for (const subtype of ['icon', 'text']) { + const properties = paintProperties.filter(({name}) => name.startsWith(`${subtype}-`)); +%> +class <%- camelize(subtype) %>PaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: +<% for (const property of properties.filter(isDataDriven)) { -%> + std::unique_ptr<PaintPropertyBinder<<%- evaluatedType(property) %>, typename <%- attributeType(property, type) %>::Type>> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + <%- properties.filter(isDataDriven).map(property => `ZoomInterpolatedAttribute<${attributeType(property, type)}>`).join(',\n ') %> + >; + + using Uniforms = gl::Uniforms< + <%- properties.filter(isDataDriven).map(property => `InterpolationUniform<${attributeType(property, type)}>`).join(',\n ') %>, + <%- properties.filter(isDataDriven).map(property => uniformType(property, type)).join(',\n ') %> + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: +<% for (const property of properties) { -%> + <%- possiblyEvaluatedType(property) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; +}; <% } -%> -class <%- camelize(type) %>PaintProperties : public Properties< -<% for (const property of paintProperties.slice(0, -1)) { -%> - <%- camelize(property.name) %>, <% } -%> - <%- camelize(paintProperties.slice(-1)[0].name) %> -> {}; } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index c744adad95..4354fe9f04 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -40,7 +40,12 @@ std::unique_ptr<Layer> LineLayer::cloneRef(const std::string& id_) const { } void LineLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - layout.stringify(writer); + writer.StartObject(); + conversion::stringify<LineCap>(writer, layout.lineCap); + conversion::stringify<LineJoin>(writer, layout.lineJoin); + conversion::stringify<LineMiterLimit>(writer, layout.lineMiterLimit); + conversion::stringify<LineRoundLimit>(writer, layout.lineRoundLimit); + writer.EndObject(); } // Source @@ -106,14 +111,14 @@ PropertyValue<LineCapType> LineLayer::getDefaultLineCap() { } PropertyValue<LineCapType> LineLayer::getLineCap() const { - return impl().layout.get<LineCap>(); + return impl().layout.lineCap; } void LineLayer::setLineCap(PropertyValue<LineCapType> value) { if (value == getLineCap()) return; auto impl_ = mutableImpl(); - impl_->layout.get<LineCap>() = value; + impl_->layout.lineCap = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -122,14 +127,14 @@ PropertyValue<LineJoinType> LineLayer::getDefaultLineJoin() { } PropertyValue<LineJoinType> LineLayer::getLineJoin() const { - return impl().layout.get<LineJoin>(); + return impl().layout.lineJoin; } void LineLayer::setLineJoin(PropertyValue<LineJoinType> value) { if (value == getLineJoin()) return; auto impl_ = mutableImpl(); - impl_->layout.get<LineJoin>() = value; + impl_->layout.lineJoin = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -138,14 +143,14 @@ PropertyValue<float> LineLayer::getDefaultLineMiterLimit() { } PropertyValue<float> LineLayer::getLineMiterLimit() const { - return impl().layout.get<LineMiterLimit>(); + return impl().layout.lineMiterLimit; } void LineLayer::setLineMiterLimit(PropertyValue<float> value) { if (value == getLineMiterLimit()) return; auto impl_ = mutableImpl(); - impl_->layout.get<LineMiterLimit>() = value; + impl_->layout.lineMiterLimit = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -154,14 +159,14 @@ PropertyValue<float> LineLayer::getDefaultLineRoundLimit() { } PropertyValue<float> LineLayer::getLineRoundLimit() const { - return impl().layout.get<LineRoundLimit>(); + return impl().layout.lineRoundLimit; } void LineLayer::setLineRoundLimit(PropertyValue<float> value) { if (value == getLineRoundLimit()) return; auto impl_ = mutableImpl(); - impl_->layout.get<LineRoundLimit>() = value; + impl_->layout.lineRoundLimit = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -173,26 +178,26 @@ PropertyValue<float> LineLayer::getDefaultLineOpacity() { } PropertyValue<float> LineLayer::getLineOpacity() const { - return impl().paint.template get<LineOpacity>().value; + return impl().paint.lineOpacity.value; } void LineLayer::setLineOpacity(PropertyValue<float> value) { if (value == getLineOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineOpacity>().value = value; + impl_->paint.lineOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineOpacity>().options = options; + impl_->paint.lineOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineOpacityTransition() const { - return impl().paint.template get<LineOpacity>().options; + return impl().paint.lineOpacity.options; } PropertyValue<Color> LineLayer::getDefaultLineColor() { @@ -200,26 +205,26 @@ PropertyValue<Color> LineLayer::getDefaultLineColor() { } PropertyValue<Color> LineLayer::getLineColor() const { - return impl().paint.template get<LineColor>().value; + return impl().paint.lineColor.value; } void LineLayer::setLineColor(PropertyValue<Color> value) { if (value == getLineColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineColor>().value = value; + impl_->paint.lineColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineColor>().options = options; + impl_->paint.lineColor.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineColorTransition() const { - return impl().paint.template get<LineColor>().options; + return impl().paint.lineColor.options; } PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() { @@ -227,26 +232,26 @@ PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() { } PropertyValue<std::array<float, 2>> LineLayer::getLineTranslate() const { - return impl().paint.template get<LineTranslate>().value; + return impl().paint.lineTranslate.value; } void LineLayer::setLineTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getLineTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineTranslate>().value = value; + impl_->paint.lineTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineTranslate>().options = options; + impl_->paint.lineTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineTranslateTransition() const { - return impl().paint.template get<LineTranslate>().options; + return impl().paint.lineTranslate.options; } PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() { @@ -254,26 +259,26 @@ PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() { } PropertyValue<TranslateAnchorType> LineLayer::getLineTranslateAnchor() const { - return impl().paint.template get<LineTranslateAnchor>().value; + return impl().paint.lineTranslateAnchor.value; } void LineLayer::setLineTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getLineTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineTranslateAnchor>().value = value; + impl_->paint.lineTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineTranslateAnchor>().options = options; + impl_->paint.lineTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineTranslateAnchorTransition() const { - return impl().paint.template get<LineTranslateAnchor>().options; + return impl().paint.lineTranslateAnchor.options; } PropertyValue<float> LineLayer::getDefaultLineWidth() { @@ -281,26 +286,26 @@ PropertyValue<float> LineLayer::getDefaultLineWidth() { } PropertyValue<float> LineLayer::getLineWidth() const { - return impl().paint.template get<LineWidth>().value; + return impl().paint.lineWidth.value; } void LineLayer::setLineWidth(PropertyValue<float> value) { if (value == getLineWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineWidth>().value = value; + impl_->paint.lineWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineWidth>().options = options; + impl_->paint.lineWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineWidthTransition() const { - return impl().paint.template get<LineWidth>().options; + return impl().paint.lineWidth.options; } PropertyValue<float> LineLayer::getDefaultLineGapWidth() { @@ -308,26 +313,26 @@ PropertyValue<float> LineLayer::getDefaultLineGapWidth() { } PropertyValue<float> LineLayer::getLineGapWidth() const { - return impl().paint.template get<LineGapWidth>().value; + return impl().paint.lineGapWidth.value; } void LineLayer::setLineGapWidth(PropertyValue<float> value) { if (value == getLineGapWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineGapWidth>().value = value; + impl_->paint.lineGapWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineGapWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineGapWidth>().options = options; + impl_->paint.lineGapWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineGapWidthTransition() const { - return impl().paint.template get<LineGapWidth>().options; + return impl().paint.lineGapWidth.options; } PropertyValue<float> LineLayer::getDefaultLineOffset() { @@ -335,26 +340,26 @@ PropertyValue<float> LineLayer::getDefaultLineOffset() { } PropertyValue<float> LineLayer::getLineOffset() const { - return impl().paint.template get<LineOffset>().value; + return impl().paint.lineOffset.value; } void LineLayer::setLineOffset(PropertyValue<float> value) { if (value == getLineOffset()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineOffset>().value = value; + impl_->paint.lineOffset.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineOffsetTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineOffset>().options = options; + impl_->paint.lineOffset.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineOffsetTransition() const { - return impl().paint.template get<LineOffset>().options; + return impl().paint.lineOffset.options; } PropertyValue<float> LineLayer::getDefaultLineBlur() { @@ -362,26 +367,26 @@ PropertyValue<float> LineLayer::getDefaultLineBlur() { } PropertyValue<float> LineLayer::getLineBlur() const { - return impl().paint.template get<LineBlur>().value; + return impl().paint.lineBlur.value; } void LineLayer::setLineBlur(PropertyValue<float> value) { if (value == getLineBlur()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineBlur>().value = value; + impl_->paint.lineBlur.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineBlurTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineBlur>().options = options; + impl_->paint.lineBlur.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineBlurTransition() const { - return impl().paint.template get<LineBlur>().options; + return impl().paint.lineBlur.options; } PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() { @@ -389,26 +394,26 @@ PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() { } PropertyValue<std::vector<float>> LineLayer::getLineDasharray() const { - return impl().paint.template get<LineDasharray>().value; + return impl().paint.lineDasharray.value; } void LineLayer::setLineDasharray(PropertyValue<std::vector<float>> value) { if (value == getLineDasharray()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LineDasharray>().value = value; + impl_->paint.lineDasharray.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLineDasharrayTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LineDasharray>().options = options; + impl_->paint.lineDasharray.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLineDasharrayTransition() const { - return impl().paint.template get<LineDasharray>().options; + return impl().paint.lineDasharray.options; } PropertyValue<std::string> LineLayer::getDefaultLinePattern() { @@ -416,26 +421,26 @@ PropertyValue<std::string> LineLayer::getDefaultLinePattern() { } PropertyValue<std::string> LineLayer::getLinePattern() const { - return impl().paint.template get<LinePattern>().value; + return impl().paint.linePattern.value; } void LineLayer::setLinePattern(PropertyValue<std::string> value) { if (value == getLinePattern()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<LinePattern>().value = value; + impl_->paint.linePattern.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void LineLayer::setLinePatternTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<LinePattern>().options = options; + impl_->paint.linePattern.options = options; baseImpl = std::move(impl_); } TransitionOptions LineLayer::getLinePatternTransition() const { - return impl().paint.template get<LinePattern>().options; + return impl().paint.linePattern.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/line_layer_properties.cpp b/src/mbgl/style/layers/line_layer_properties.cpp index 174239bcc8..169b571fbe 100644 --- a/src/mbgl/style/layers/line_layer_properties.cpp +++ b/src/mbgl/style/layers/line_layer_properties.cpp @@ -5,5 +5,223 @@ namespace mbgl { namespace style { +bool operator==(const LineLayoutProperties::Unevaluated& lhs, const LineLayoutProperties::Unevaluated& rhs) { + return true + && lhs.lineCap == rhs.lineCap + && lhs.lineJoin == rhs.lineJoin + && lhs.lineMiterLimit == rhs.lineMiterLimit + && lhs.lineRoundLimit == rhs.lineRoundLimit + ; +} + +LineLayoutProperties::PossiblyEvaluated LineLayoutProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + lineCap.evaluate(typename LineCap::EvaluatorType(parameters, LineCap::defaultValue()), parameters.now), + lineJoin.evaluate(typename LineJoin::EvaluatorType(parameters, LineJoin::defaultValue()), parameters.now), + lineMiterLimit.evaluate(typename LineMiterLimit::EvaluatorType(parameters, LineMiterLimit::defaultValue()), parameters.now), + lineRoundLimit.evaluate(typename LineRoundLimit::EvaluatorType(parameters, LineRoundLimit::defaultValue()), parameters.now), + }; +} + +LineLayoutProperties::Evaluated LineLayoutProperties::PossiblyEvaluated::evaluate(float z, const GeometryTileFeature& feature) const { + return Evaluated { + lineCap, + lineJoin.evaluate(feature, z, LineJoin::defaultValue()), + lineMiterLimit, + lineRoundLimit, + }; +} + +LinePaintProperties::Unevaluated LinePaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + lineOpacity.transition(parameters, std::move(prior.lineOpacity)), + lineColor.transition(parameters, std::move(prior.lineColor)), + lineTranslate.transition(parameters, std::move(prior.lineTranslate)), + lineTranslateAnchor.transition(parameters, std::move(prior.lineTranslateAnchor)), + lineWidth.transition(parameters, std::move(prior.lineWidth)), + lineGapWidth.transition(parameters, std::move(prior.lineGapWidth)), + lineOffset.transition(parameters, std::move(prior.lineOffset)), + lineBlur.transition(parameters, std::move(prior.lineBlur)), + lineDasharray.transition(parameters, std::move(prior.lineDasharray)), + linePattern.transition(parameters, std::move(prior.linePattern)), + }; +} + +LinePaintProperties::Unevaluated LinePaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(lineOpacity.value), + Transitioning<PropertyValue<Color>>(lineColor.value), + Transitioning<PropertyValue<std::array<float, 2>>>(lineTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(lineTranslateAnchor.value), + Transitioning<PropertyValue<float>>(lineWidth.value), + Transitioning<PropertyValue<float>>(lineGapWidth.value), + Transitioning<PropertyValue<float>>(lineOffset.value), + Transitioning<PropertyValue<float>>(lineBlur.value), + Transitioning<PropertyValue<std::vector<float>>>(lineDasharray.value), + Transitioning<PropertyValue<std::string>>(linePattern.value), + }; +} + +bool LinePaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || lineOpacity.value.hasDataDrivenPropertyDifference(other.lineOpacity.value) + || lineColor.value.hasDataDrivenPropertyDifference(other.lineColor.value) + || lineTranslate.value.hasDataDrivenPropertyDifference(other.lineTranslate.value) + || lineTranslateAnchor.value.hasDataDrivenPropertyDifference(other.lineTranslateAnchor.value) + || lineWidth.value.hasDataDrivenPropertyDifference(other.lineWidth.value) + || lineGapWidth.value.hasDataDrivenPropertyDifference(other.lineGapWidth.value) + || lineOffset.value.hasDataDrivenPropertyDifference(other.lineOffset.value) + || lineBlur.value.hasDataDrivenPropertyDifference(other.lineBlur.value) + || lineDasharray.value.hasDataDrivenPropertyDifference(other.lineDasharray.value) + || linePattern.value.hasDataDrivenPropertyDifference(other.linePattern.value) + ; +} + +bool LinePaintProperties::Unevaluated::hasTransition() const { + return false + || lineOpacity.hasTransition() + || lineColor.hasTransition() + || lineTranslate.hasTransition() + || lineTranslateAnchor.hasTransition() + || lineWidth.hasTransition() + || lineGapWidth.hasTransition() + || lineOffset.hasTransition() + || lineBlur.hasTransition() + || lineDasharray.hasTransition() + || linePattern.hasTransition() + ; +} + +LinePaintProperties::PossiblyEvaluated LinePaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + lineOpacity.evaluate(typename LineOpacity::EvaluatorType(parameters, LineOpacity::defaultValue()), parameters.now), + lineColor.evaluate(typename LineColor::EvaluatorType(parameters, LineColor::defaultValue()), parameters.now), + lineTranslate.evaluate(typename LineTranslate::EvaluatorType(parameters, LineTranslate::defaultValue()), parameters.now), + lineTranslateAnchor.evaluate(typename LineTranslateAnchor::EvaluatorType(parameters, LineTranslateAnchor::defaultValue()), parameters.now), + lineWidth.evaluate(typename LineWidth::EvaluatorType(parameters, LineWidth::defaultValue()), parameters.now), + lineGapWidth.evaluate(typename LineGapWidth::EvaluatorType(parameters, LineGapWidth::defaultValue()), parameters.now), + lineOffset.evaluate(typename LineOffset::EvaluatorType(parameters, LineOffset::defaultValue()), parameters.now), + lineBlur.evaluate(typename LineBlur::EvaluatorType(parameters, LineBlur::defaultValue()), parameters.now), + lineDasharray.evaluate(typename LineDasharray::EvaluatorType(parameters, LineDasharray::defaultValue()), parameters.now), + linePattern.evaluate(typename LinePattern::EvaluatorType(parameters, LinePattern::defaultValue()), parameters.now), + }; +} + +LinePaintProperties::Binders LinePaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(lineOpacity, z, LineOpacity::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_color::Type>::create(lineColor, z, LineColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_width::Type>::create(lineWidth, z, LineWidth::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_gapwidth::Type>::create(lineGapWidth, z, LineGapWidth::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_offset<1>::Type>::create(lineOffset, z, LineOffset::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_blur::Type>::create(lineBlur, z, LineBlur::defaultValue()), + }; +} + +std::bitset<8> LinePaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, lineOpacity.isConstant()); + result.set(1, lineColor.isConstant()); + result.set(2, lineWidth.isConstant()); + result.set(3, lineGapWidth.isConstant()); + result.set(4, lineOffset.isConstant()); + result.set(5, lineBlur.isConstant()); + return result; +} + +std::vector<std::string> LinePaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(lineOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineOpacity::Uniform::name() + : std::string()); + result.push_back(lineColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineColor::Uniform::name() + : std::string()); + result.push_back(lineWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineWidth::Uniform::name() + : std::string()); + result.push_back(lineGapWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineGapWidth::Uniform::name() + : std::string()); + result.push_back(lineOffset.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineOffset::Uniform::name() + : std::string()); + result.push_back(lineBlur.isConstant() + ? std::string("#define HAS_UNIFORM_") + LineBlur::Uniform::name() + : std::string()); + return result; +} + +void LinePaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + lineOpacity->populateVertexVector(feature, length); + lineColor->populateVertexVector(feature, length); + lineWidth->populateVertexVector(feature, length); + lineGapWidth->populateVertexVector(feature, length); + lineOffset->populateVertexVector(feature, length); + lineBlur->populateVertexVector(feature, length); +} + +void LinePaintProperties::Binders::upload(gl::Context& context) { + lineOpacity->upload(context); + lineColor->upload(context); + lineWidth->upload(context); + lineGapWidth->upload(context); + lineOffset->upload(context); + lineBlur->upload(context); +} + +LinePaintProperties::Binders::AttributeBindings LinePaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + lineOpacity->attributeBinding(currentProperties.lineOpacity), + lineColor->attributeBinding(currentProperties.lineColor), + lineWidth->attributeBinding(currentProperties.lineWidth), + lineGapWidth->attributeBinding(currentProperties.lineGapWidth), + lineOffset->attributeBinding(currentProperties.lineOffset), + lineBlur->attributeBinding(currentProperties.lineBlur), + }; +} + +LinePaintProperties::Binders::UniformValues LinePaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_opacity>::Value { + lineOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_color>::Value { + lineColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_width>::Value { + lineWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_gapwidth>::Value { + lineGapWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_offset<1>>::Value { + lineOffset->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_blur>::Value { + lineBlur->interpolationFactor(currentZoom) + }, + typename uniforms::u_opacity::Value { + lineOpacity->uniformValue(currentProperties.lineOpacity) + }, + typename uniforms::u_color::Value { + lineColor->uniformValue(currentProperties.lineColor) + }, + typename uniforms::u_width::Value { + lineWidth->uniformValue(currentProperties.lineWidth) + }, + typename uniforms::u_gapwidth::Value { + lineGapWidth->uniformValue(currentProperties.lineGapWidth) + }, + typename uniforms::u_offset::Value { + lineOffset->uniformValue(currentProperties.lineOffset) + }, + typename uniforms::u_blur::Value { + lineBlur->uniformValue(currentProperties.lineBlur) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index aeaf51698a..f65499d9da 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -72,25 +72,143 @@ struct LinePattern : CrossFadedPaintProperty<std::string> { static std::string defaultValue() { return ""; } }; -class LineLayoutProperties : public Properties< - LineCap, - LineJoin, - LineMiterLimit, - LineRoundLimit -> {}; - -class LinePaintProperties : public Properties< - LineOpacity, - LineColor, - LineTranslate, - LineTranslateAnchor, - LineWidth, - LineGapWidth, - LineOffset, - LineBlur, - LineDasharray, - LinePattern -> {}; +class LineLayoutProperties { +public: + class Evaluated { + public: + LineCapType lineCap; + LineJoinType lineJoin; + float lineMiterLimit; + float lineRoundLimit; + }; + + class PossiblyEvaluated { + public: + LineCapType lineCap; + PossiblyEvaluatedPropertyValue<LineJoinType> lineJoin; + float lineMiterLimit; + float lineRoundLimit; + + Evaluated evaluate(float z, const GeometryTileFeature& feature) const; + }; + + class Unevaluated { + public: + PropertyValue<LineCapType> lineCap; + PropertyValue<LineJoinType> lineJoin; + PropertyValue<float> lineMiterLimit; + PropertyValue<float> lineRoundLimit; + + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + + friend bool operator==(const Unevaluated&, const Unevaluated&); + friend inline bool operator!=(const Unevaluated& lhs, const Unevaluated& rhs) { return !(lhs == rhs); } + }; +}; + +class LinePaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> lineOpacity; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_color::Type>> lineColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_width::Type>> lineWidth; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_gapwidth::Type>> lineGapWidth; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_offset<1>::Type>> lineOffset; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_blur::Type>> lineBlur; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_color>, + ZoomInterpolatedAttribute<attributes::a_width>, + ZoomInterpolatedAttribute<attributes::a_gapwidth>, + ZoomInterpolatedAttribute<attributes::a_offset<1>>, + ZoomInterpolatedAttribute<attributes::a_blur> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_color>, + InterpolationUniform<attributes::a_width>, + InterpolationUniform<attributes::a_gapwidth>, + InterpolationUniform<attributes::a_offset<1>>, + InterpolationUniform<attributes::a_blur>, + uniforms::u_opacity, + uniforms::u_color, + uniforms::u_width, + uniforms::u_gapwidth, + uniforms::u_offset, + uniforms::u_blur + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> lineOpacity; + PossiblyEvaluatedPropertyValue<Color> lineColor; + std::array<float, 2> lineTranslate; + TranslateAnchorType lineTranslateAnchor; + PossiblyEvaluatedPropertyValue<float> lineWidth; + PossiblyEvaluatedPropertyValue<float> lineGapWidth; + PossiblyEvaluatedPropertyValue<float> lineOffset; + PossiblyEvaluatedPropertyValue<float> lineBlur; + Faded<std::vector<float>> lineDasharray; + Faded<std::string> linePattern; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> lineOpacity; + style::Transitioning<PropertyValue<Color>> lineColor; + style::Transitioning<PropertyValue<std::array<float, 2>>> lineTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> lineTranslateAnchor; + style::Transitioning<PropertyValue<float>> lineWidth; + style::Transitioning<PropertyValue<float>> lineGapWidth; + style::Transitioning<PropertyValue<float>> lineOffset; + style::Transitioning<PropertyValue<float>> lineBlur; + style::Transitioning<PropertyValue<std::vector<float>>> lineDasharray; + style::Transitioning<PropertyValue<std::string>> linePattern; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> lineOpacity; + style::Transitionable<PropertyValue<Color>> lineColor; + style::Transitionable<PropertyValue<std::array<float, 2>>> lineTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> lineTranslateAnchor; + style::Transitionable<PropertyValue<float>> lineWidth; + style::Transitionable<PropertyValue<float>> lineGapWidth; + style::Transitionable<PropertyValue<float>> lineOffset; + style::Transitionable<PropertyValue<float>> lineBlur; + style::Transitionable<PropertyValue<std::vector<float>>> lineDasharray; + style::Transitionable<PropertyValue<std::string>> linePattern; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp index 45d3240833..63520b4e99 100644 --- a/src/mbgl/style/layers/raster_layer.cpp +++ b/src/mbgl/style/layers/raster_layer.cpp @@ -86,26 +86,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterOpacity() { } PropertyValue<float> RasterLayer::getRasterOpacity() const { - return impl().paint.template get<RasterOpacity>().value; + return impl().paint.rasterOpacity.value; } void RasterLayer::setRasterOpacity(PropertyValue<float> value) { if (value == getRasterOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterOpacity>().value = value; + impl_->paint.rasterOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterOpacity>().options = options; + impl_->paint.rasterOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterOpacityTransition() const { - return impl().paint.template get<RasterOpacity>().options; + return impl().paint.rasterOpacity.options; } PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() { @@ -113,26 +113,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() { } PropertyValue<float> RasterLayer::getRasterHueRotate() const { - return impl().paint.template get<RasterHueRotate>().value; + return impl().paint.rasterHueRotate.value; } void RasterLayer::setRasterHueRotate(PropertyValue<float> value) { if (value == getRasterHueRotate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterHueRotate>().value = value; + impl_->paint.rasterHueRotate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterHueRotateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterHueRotate>().options = options; + impl_->paint.rasterHueRotate.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterHueRotateTransition() const { - return impl().paint.template get<RasterHueRotate>().options; + return impl().paint.rasterHueRotate.options; } PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() { @@ -140,26 +140,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() { } PropertyValue<float> RasterLayer::getRasterBrightnessMin() const { - return impl().paint.template get<RasterBrightnessMin>().value; + return impl().paint.rasterBrightnessMin.value; } void RasterLayer::setRasterBrightnessMin(PropertyValue<float> value) { if (value == getRasterBrightnessMin()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterBrightnessMin>().value = value; + impl_->paint.rasterBrightnessMin.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterBrightnessMinTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterBrightnessMin>().options = options; + impl_->paint.rasterBrightnessMin.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterBrightnessMinTransition() const { - return impl().paint.template get<RasterBrightnessMin>().options; + return impl().paint.rasterBrightnessMin.options; } PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() { @@ -167,26 +167,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() { } PropertyValue<float> RasterLayer::getRasterBrightnessMax() const { - return impl().paint.template get<RasterBrightnessMax>().value; + return impl().paint.rasterBrightnessMax.value; } void RasterLayer::setRasterBrightnessMax(PropertyValue<float> value) { if (value == getRasterBrightnessMax()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterBrightnessMax>().value = value; + impl_->paint.rasterBrightnessMax.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterBrightnessMaxTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterBrightnessMax>().options = options; + impl_->paint.rasterBrightnessMax.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterBrightnessMaxTransition() const { - return impl().paint.template get<RasterBrightnessMax>().options; + return impl().paint.rasterBrightnessMax.options; } PropertyValue<float> RasterLayer::getDefaultRasterSaturation() { @@ -194,26 +194,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterSaturation() { } PropertyValue<float> RasterLayer::getRasterSaturation() const { - return impl().paint.template get<RasterSaturation>().value; + return impl().paint.rasterSaturation.value; } void RasterLayer::setRasterSaturation(PropertyValue<float> value) { if (value == getRasterSaturation()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterSaturation>().value = value; + impl_->paint.rasterSaturation.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterSaturationTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterSaturation>().options = options; + impl_->paint.rasterSaturation.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterSaturationTransition() const { - return impl().paint.template get<RasterSaturation>().options; + return impl().paint.rasterSaturation.options; } PropertyValue<float> RasterLayer::getDefaultRasterContrast() { @@ -221,26 +221,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterContrast() { } PropertyValue<float> RasterLayer::getRasterContrast() const { - return impl().paint.template get<RasterContrast>().value; + return impl().paint.rasterContrast.value; } void RasterLayer::setRasterContrast(PropertyValue<float> value) { if (value == getRasterContrast()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterContrast>().value = value; + impl_->paint.rasterContrast.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterContrastTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterContrast>().options = options; + impl_->paint.rasterContrast.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterContrastTransition() const { - return impl().paint.template get<RasterContrast>().options; + return impl().paint.rasterContrast.options; } PropertyValue<RasterResamplingType> RasterLayer::getDefaultRasterResampling() { @@ -248,26 +248,26 @@ PropertyValue<RasterResamplingType> RasterLayer::getDefaultRasterResampling() { } PropertyValue<RasterResamplingType> RasterLayer::getRasterResampling() const { - return impl().paint.template get<RasterResampling>().value; + return impl().paint.rasterResampling.value; } void RasterLayer::setRasterResampling(PropertyValue<RasterResamplingType> value) { if (value == getRasterResampling()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterResampling>().value = value; + impl_->paint.rasterResampling.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterResamplingTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterResampling>().options = options; + impl_->paint.rasterResampling.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterResamplingTransition() const { - return impl().paint.template get<RasterResampling>().options; + return impl().paint.rasterResampling.options; } PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() { @@ -275,26 +275,26 @@ PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() { } PropertyValue<float> RasterLayer::getRasterFadeDuration() const { - return impl().paint.template get<RasterFadeDuration>().value; + return impl().paint.rasterFadeDuration.value; } void RasterLayer::setRasterFadeDuration(PropertyValue<float> value) { if (value == getRasterFadeDuration()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<RasterFadeDuration>().value = value; + impl_->paint.rasterFadeDuration.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void RasterLayer::setRasterFadeDurationTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<RasterFadeDuration>().options = options; + impl_->paint.rasterFadeDuration.options = options; baseImpl = std::move(impl_); } TransitionOptions RasterLayer::getRasterFadeDurationTransition() const { - return impl().paint.template get<RasterFadeDuration>().options; + return impl().paint.rasterFadeDuration.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/raster_layer_properties.cpp b/src/mbgl/style/layers/raster_layer_properties.cpp index 303719af40..336cbe0c49 100644 --- a/src/mbgl/style/layers/raster_layer_properties.cpp +++ b/src/mbgl/style/layers/raster_layer_properties.cpp @@ -5,5 +5,72 @@ namespace mbgl { namespace style { +RasterPaintProperties::Unevaluated RasterPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + rasterOpacity.transition(parameters, std::move(prior.rasterOpacity)), + rasterHueRotate.transition(parameters, std::move(prior.rasterHueRotate)), + rasterBrightnessMin.transition(parameters, std::move(prior.rasterBrightnessMin)), + rasterBrightnessMax.transition(parameters, std::move(prior.rasterBrightnessMax)), + rasterSaturation.transition(parameters, std::move(prior.rasterSaturation)), + rasterContrast.transition(parameters, std::move(prior.rasterContrast)), + rasterResampling.transition(parameters, std::move(prior.rasterResampling)), + rasterFadeDuration.transition(parameters, std::move(prior.rasterFadeDuration)), + }; +} + +RasterPaintProperties::Unevaluated RasterPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(rasterOpacity.value), + Transitioning<PropertyValue<float>>(rasterHueRotate.value), + Transitioning<PropertyValue<float>>(rasterBrightnessMin.value), + Transitioning<PropertyValue<float>>(rasterBrightnessMax.value), + Transitioning<PropertyValue<float>>(rasterSaturation.value), + Transitioning<PropertyValue<float>>(rasterContrast.value), + Transitioning<PropertyValue<RasterResamplingType>>(rasterResampling.value), + Transitioning<PropertyValue<float>>(rasterFadeDuration.value), + }; +} + +bool RasterPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || rasterOpacity.value.hasDataDrivenPropertyDifference(other.rasterOpacity.value) + || rasterHueRotate.value.hasDataDrivenPropertyDifference(other.rasterHueRotate.value) + || rasterBrightnessMin.value.hasDataDrivenPropertyDifference(other.rasterBrightnessMin.value) + || rasterBrightnessMax.value.hasDataDrivenPropertyDifference(other.rasterBrightnessMax.value) + || rasterSaturation.value.hasDataDrivenPropertyDifference(other.rasterSaturation.value) + || rasterContrast.value.hasDataDrivenPropertyDifference(other.rasterContrast.value) + || rasterResampling.value.hasDataDrivenPropertyDifference(other.rasterResampling.value) + || rasterFadeDuration.value.hasDataDrivenPropertyDifference(other.rasterFadeDuration.value) + ; +} + +bool RasterPaintProperties::Unevaluated::hasTransition() const { + return false + || rasterOpacity.hasTransition() + || rasterHueRotate.hasTransition() + || rasterBrightnessMin.hasTransition() + || rasterBrightnessMax.hasTransition() + || rasterSaturation.hasTransition() + || rasterContrast.hasTransition() + || rasterResampling.hasTransition() + || rasterFadeDuration.hasTransition() + ; +} + +RasterPaintProperties::PossiblyEvaluated RasterPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + rasterOpacity.evaluate(typename RasterOpacity::EvaluatorType(parameters, RasterOpacity::defaultValue()), parameters.now), + rasterHueRotate.evaluate(typename RasterHueRotate::EvaluatorType(parameters, RasterHueRotate::defaultValue()), parameters.now), + rasterBrightnessMin.evaluate(typename RasterBrightnessMin::EvaluatorType(parameters, RasterBrightnessMin::defaultValue()), parameters.now), + rasterBrightnessMax.evaluate(typename RasterBrightnessMax::EvaluatorType(parameters, RasterBrightnessMax::defaultValue()), parameters.now), + rasterSaturation.evaluate(typename RasterSaturation::EvaluatorType(parameters, RasterSaturation::defaultValue()), parameters.now), + rasterContrast.evaluate(typename RasterContrast::EvaluatorType(parameters, RasterContrast::defaultValue()), parameters.now), + rasterResampling.evaluate(typename RasterResampling::EvaluatorType(parameters, RasterResampling::defaultValue()), parameters.now), + rasterFadeDuration.evaluate(typename RasterFadeDuration::EvaluatorType(parameters, RasterFadeDuration::defaultValue()), parameters.now), + }; +} + + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp index 08818c9fb3..d43ab78a95 100644 --- a/src/mbgl/style/layers/raster_layer_properties.hpp +++ b/src/mbgl/style/layers/raster_layer_properties.hpp @@ -44,16 +44,54 @@ struct RasterFadeDuration : PaintProperty<float> { static float defaultValue() { return 300; } }; -class RasterPaintProperties : public Properties< - RasterOpacity, - RasterHueRotate, - RasterBrightnessMin, - RasterBrightnessMax, - RasterSaturation, - RasterContrast, - RasterResampling, - RasterFadeDuration -> {}; +class RasterPaintProperties { +public: + + class PossiblyEvaluated { + public: + float rasterOpacity; + float rasterHueRotate; + float rasterBrightnessMin; + float rasterBrightnessMax; + float rasterSaturation; + float rasterContrast; + RasterResamplingType rasterResampling; + float rasterFadeDuration; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> rasterOpacity; + style::Transitioning<PropertyValue<float>> rasterHueRotate; + style::Transitioning<PropertyValue<float>> rasterBrightnessMin; + style::Transitioning<PropertyValue<float>> rasterBrightnessMax; + style::Transitioning<PropertyValue<float>> rasterSaturation; + style::Transitioning<PropertyValue<float>> rasterContrast; + style::Transitioning<PropertyValue<RasterResamplingType>> rasterResampling; + style::Transitioning<PropertyValue<float>> rasterFadeDuration; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> rasterOpacity; + style::Transitionable<PropertyValue<float>> rasterHueRotate; + style::Transitionable<PropertyValue<float>> rasterBrightnessMin; + style::Transitionable<PropertyValue<float>> rasterBrightnessMax; + style::Transitionable<PropertyValue<float>> rasterSaturation; + style::Transitionable<PropertyValue<float>> rasterContrast; + style::Transitionable<PropertyValue<RasterResamplingType>> rasterResampling; + style::Transitionable<PropertyValue<float>> rasterFadeDuration; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 48af6b13aa..9786e7a3f3 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -40,7 +40,44 @@ std::unique_ptr<Layer> SymbolLayer::cloneRef(const std::string& id_) const { } void SymbolLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const { - layout.stringify(writer); + writer.StartObject(); + conversion::stringify<SymbolPlacement>(writer, layout.symbolPlacement); + conversion::stringify<SymbolSpacing>(writer, layout.symbolSpacing); + conversion::stringify<SymbolAvoidEdges>(writer, layout.symbolAvoidEdges); + conversion::stringify<IconAllowOverlap>(writer, layout.iconAllowOverlap); + conversion::stringify<IconIgnorePlacement>(writer, layout.iconIgnorePlacement); + conversion::stringify<IconOptional>(writer, layout.iconOptional); + conversion::stringify<IconRotationAlignment>(writer, layout.iconRotationAlignment); + conversion::stringify<IconSize>(writer, layout.iconSize); + conversion::stringify<IconTextFit>(writer, layout.iconTextFit); + conversion::stringify<IconTextFitPadding>(writer, layout.iconTextFitPadding); + conversion::stringify<IconImage>(writer, layout.iconImage); + conversion::stringify<IconRotate>(writer, layout.iconRotate); + conversion::stringify<IconPadding>(writer, layout.iconPadding); + conversion::stringify<IconKeepUpright>(writer, layout.iconKeepUpright); + conversion::stringify<IconOffset>(writer, layout.iconOffset); + conversion::stringify<IconAnchor>(writer, layout.iconAnchor); + conversion::stringify<IconPitchAlignment>(writer, layout.iconPitchAlignment); + conversion::stringify<TextPitchAlignment>(writer, layout.textPitchAlignment); + conversion::stringify<TextRotationAlignment>(writer, layout.textRotationAlignment); + conversion::stringify<TextField>(writer, layout.textField); + conversion::stringify<TextFont>(writer, layout.textFont); + conversion::stringify<TextSize>(writer, layout.textSize); + conversion::stringify<TextMaxWidth>(writer, layout.textMaxWidth); + conversion::stringify<TextLineHeight>(writer, layout.textLineHeight); + conversion::stringify<TextLetterSpacing>(writer, layout.textLetterSpacing); + conversion::stringify<TextJustify>(writer, layout.textJustify); + conversion::stringify<TextAnchor>(writer, layout.textAnchor); + conversion::stringify<TextMaxAngle>(writer, layout.textMaxAngle); + conversion::stringify<TextRotate>(writer, layout.textRotate); + conversion::stringify<TextPadding>(writer, layout.textPadding); + conversion::stringify<TextKeepUpright>(writer, layout.textKeepUpright); + conversion::stringify<TextTransform>(writer, layout.textTransform); + conversion::stringify<TextOffset>(writer, layout.textOffset); + conversion::stringify<TextAllowOverlap>(writer, layout.textAllowOverlap); + conversion::stringify<TextIgnorePlacement>(writer, layout.textIgnorePlacement); + conversion::stringify<TextOptional>(writer, layout.textOptional); + writer.EndObject(); } // Source @@ -106,14 +143,14 @@ PropertyValue<SymbolPlacementType> SymbolLayer::getDefaultSymbolPlacement() { } PropertyValue<SymbolPlacementType> SymbolLayer::getSymbolPlacement() const { - return impl().layout.get<SymbolPlacement>(); + return impl().layout.symbolPlacement; } void SymbolLayer::setSymbolPlacement(PropertyValue<SymbolPlacementType> value) { if (value == getSymbolPlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.get<SymbolPlacement>() = value; + impl_->layout.symbolPlacement = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -122,14 +159,14 @@ PropertyValue<float> SymbolLayer::getDefaultSymbolSpacing() { } PropertyValue<float> SymbolLayer::getSymbolSpacing() const { - return impl().layout.get<SymbolSpacing>(); + return impl().layout.symbolSpacing; } void SymbolLayer::setSymbolSpacing(PropertyValue<float> value) { if (value == getSymbolSpacing()) return; auto impl_ = mutableImpl(); - impl_->layout.get<SymbolSpacing>() = value; + impl_->layout.symbolSpacing = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -138,14 +175,14 @@ PropertyValue<bool> SymbolLayer::getDefaultSymbolAvoidEdges() { } PropertyValue<bool> SymbolLayer::getSymbolAvoidEdges() const { - return impl().layout.get<SymbolAvoidEdges>(); + return impl().layout.symbolAvoidEdges; } void SymbolLayer::setSymbolAvoidEdges(PropertyValue<bool> value) { if (value == getSymbolAvoidEdges()) return; auto impl_ = mutableImpl(); - impl_->layout.get<SymbolAvoidEdges>() = value; + impl_->layout.symbolAvoidEdges = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -154,14 +191,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconAllowOverlap() { } PropertyValue<bool> SymbolLayer::getIconAllowOverlap() const { - return impl().layout.get<IconAllowOverlap>(); + return impl().layout.iconAllowOverlap; } void SymbolLayer::setIconAllowOverlap(PropertyValue<bool> value) { if (value == getIconAllowOverlap()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconAllowOverlap>() = value; + impl_->layout.iconAllowOverlap = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -170,14 +207,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconIgnorePlacement() { } PropertyValue<bool> SymbolLayer::getIconIgnorePlacement() const { - return impl().layout.get<IconIgnorePlacement>(); + return impl().layout.iconIgnorePlacement; } void SymbolLayer::setIconIgnorePlacement(PropertyValue<bool> value) { if (value == getIconIgnorePlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconIgnorePlacement>() = value; + impl_->layout.iconIgnorePlacement = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -186,14 +223,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconOptional() { } PropertyValue<bool> SymbolLayer::getIconOptional() const { - return impl().layout.get<IconOptional>(); + return impl().layout.iconOptional; } void SymbolLayer::setIconOptional(PropertyValue<bool> value) { if (value == getIconOptional()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconOptional>() = value; + impl_->layout.iconOptional = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -202,14 +239,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultIconRotationAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getIconRotationAlignment() const { - return impl().layout.get<IconRotationAlignment>(); + return impl().layout.iconRotationAlignment; } void SymbolLayer::setIconRotationAlignment(PropertyValue<AlignmentType> value) { if (value == getIconRotationAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconRotationAlignment>() = value; + impl_->layout.iconRotationAlignment = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -218,14 +255,14 @@ PropertyValue<float> SymbolLayer::getDefaultIconSize() { } PropertyValue<float> SymbolLayer::getIconSize() const { - return impl().layout.get<IconSize>(); + return impl().layout.iconSize; } void SymbolLayer::setIconSize(PropertyValue<float> value) { if (value == getIconSize()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconSize>() = value; + impl_->layout.iconSize = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -234,14 +271,14 @@ PropertyValue<IconTextFitType> SymbolLayer::getDefaultIconTextFit() { } PropertyValue<IconTextFitType> SymbolLayer::getIconTextFit() const { - return impl().layout.get<IconTextFit>(); + return impl().layout.iconTextFit; } void SymbolLayer::setIconTextFit(PropertyValue<IconTextFitType> value) { if (value == getIconTextFit()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconTextFit>() = value; + impl_->layout.iconTextFit = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -250,14 +287,14 @@ PropertyValue<std::array<float, 4>> SymbolLayer::getDefaultIconTextFitPadding() } PropertyValue<std::array<float, 4>> SymbolLayer::getIconTextFitPadding() const { - return impl().layout.get<IconTextFitPadding>(); + return impl().layout.iconTextFitPadding; } void SymbolLayer::setIconTextFitPadding(PropertyValue<std::array<float, 4>> value) { if (value == getIconTextFitPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconTextFitPadding>() = value; + impl_->layout.iconTextFitPadding = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -266,14 +303,14 @@ PropertyValue<std::string> SymbolLayer::getDefaultIconImage() { } PropertyValue<std::string> SymbolLayer::getIconImage() const { - return impl().layout.get<IconImage>(); + return impl().layout.iconImage; } void SymbolLayer::setIconImage(PropertyValue<std::string> value) { if (value == getIconImage()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconImage>() = value; + impl_->layout.iconImage = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -282,14 +319,14 @@ PropertyValue<float> SymbolLayer::getDefaultIconRotate() { } PropertyValue<float> SymbolLayer::getIconRotate() const { - return impl().layout.get<IconRotate>(); + return impl().layout.iconRotate; } void SymbolLayer::setIconRotate(PropertyValue<float> value) { if (value == getIconRotate()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconRotate>() = value; + impl_->layout.iconRotate = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -298,14 +335,14 @@ PropertyValue<float> SymbolLayer::getDefaultIconPadding() { } PropertyValue<float> SymbolLayer::getIconPadding() const { - return impl().layout.get<IconPadding>(); + return impl().layout.iconPadding; } void SymbolLayer::setIconPadding(PropertyValue<float> value) { if (value == getIconPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconPadding>() = value; + impl_->layout.iconPadding = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -314,14 +351,14 @@ PropertyValue<bool> SymbolLayer::getDefaultIconKeepUpright() { } PropertyValue<bool> SymbolLayer::getIconKeepUpright() const { - return impl().layout.get<IconKeepUpright>(); + return impl().layout.iconKeepUpright; } void SymbolLayer::setIconKeepUpright(PropertyValue<bool> value) { if (value == getIconKeepUpright()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconKeepUpright>() = value; + impl_->layout.iconKeepUpright = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -330,14 +367,14 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconOffset() { } PropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const { - return impl().layout.get<IconOffset>(); + return impl().layout.iconOffset; } void SymbolLayer::setIconOffset(PropertyValue<std::array<float, 2>> value) { if (value == getIconOffset()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconOffset>() = value; + impl_->layout.iconOffset = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -346,14 +383,14 @@ PropertyValue<SymbolAnchorType> SymbolLayer::getDefaultIconAnchor() { } PropertyValue<SymbolAnchorType> SymbolLayer::getIconAnchor() const { - return impl().layout.get<IconAnchor>(); + return impl().layout.iconAnchor; } void SymbolLayer::setIconAnchor(PropertyValue<SymbolAnchorType> value) { if (value == getIconAnchor()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconAnchor>() = value; + impl_->layout.iconAnchor = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -362,14 +399,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultIconPitchAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getIconPitchAlignment() const { - return impl().layout.get<IconPitchAlignment>(); + return impl().layout.iconPitchAlignment; } void SymbolLayer::setIconPitchAlignment(PropertyValue<AlignmentType> value) { if (value == getIconPitchAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.get<IconPitchAlignment>() = value; + impl_->layout.iconPitchAlignment = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -378,14 +415,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultTextPitchAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getTextPitchAlignment() const { - return impl().layout.get<TextPitchAlignment>(); + return impl().layout.textPitchAlignment; } void SymbolLayer::setTextPitchAlignment(PropertyValue<AlignmentType> value) { if (value == getTextPitchAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextPitchAlignment>() = value; + impl_->layout.textPitchAlignment = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -394,14 +431,14 @@ PropertyValue<AlignmentType> SymbolLayer::getDefaultTextRotationAlignment() { } PropertyValue<AlignmentType> SymbolLayer::getTextRotationAlignment() const { - return impl().layout.get<TextRotationAlignment>(); + return impl().layout.textRotationAlignment; } void SymbolLayer::setTextRotationAlignment(PropertyValue<AlignmentType> value) { if (value == getTextRotationAlignment()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextRotationAlignment>() = value; + impl_->layout.textRotationAlignment = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -410,14 +447,14 @@ PropertyValue<std::string> SymbolLayer::getDefaultTextField() { } PropertyValue<std::string> SymbolLayer::getTextField() const { - return impl().layout.get<TextField>(); + return impl().layout.textField; } void SymbolLayer::setTextField(PropertyValue<std::string> value) { if (value == getTextField()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextField>() = value; + impl_->layout.textField = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -426,14 +463,14 @@ PropertyValue<std::vector<std::string>> SymbolLayer::getDefaultTextFont() { } PropertyValue<std::vector<std::string>> SymbolLayer::getTextFont() const { - return impl().layout.get<TextFont>(); + return impl().layout.textFont; } void SymbolLayer::setTextFont(PropertyValue<std::vector<std::string>> value) { if (value == getTextFont()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextFont>() = value; + impl_->layout.textFont = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -442,14 +479,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextSize() { } PropertyValue<float> SymbolLayer::getTextSize() const { - return impl().layout.get<TextSize>(); + return impl().layout.textSize; } void SymbolLayer::setTextSize(PropertyValue<float> value) { if (value == getTextSize()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextSize>() = value; + impl_->layout.textSize = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -458,14 +495,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextMaxWidth() { } PropertyValue<float> SymbolLayer::getTextMaxWidth() const { - return impl().layout.get<TextMaxWidth>(); + return impl().layout.textMaxWidth; } void SymbolLayer::setTextMaxWidth(PropertyValue<float> value) { if (value == getTextMaxWidth()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextMaxWidth>() = value; + impl_->layout.textMaxWidth = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -474,14 +511,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextLineHeight() { } PropertyValue<float> SymbolLayer::getTextLineHeight() const { - return impl().layout.get<TextLineHeight>(); + return impl().layout.textLineHeight; } void SymbolLayer::setTextLineHeight(PropertyValue<float> value) { if (value == getTextLineHeight()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextLineHeight>() = value; + impl_->layout.textLineHeight = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -490,14 +527,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextLetterSpacing() { } PropertyValue<float> SymbolLayer::getTextLetterSpacing() const { - return impl().layout.get<TextLetterSpacing>(); + return impl().layout.textLetterSpacing; } void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) { if (value == getTextLetterSpacing()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextLetterSpacing>() = value; + impl_->layout.textLetterSpacing = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -506,14 +543,14 @@ PropertyValue<TextJustifyType> SymbolLayer::getDefaultTextJustify() { } PropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const { - return impl().layout.get<TextJustify>(); + return impl().layout.textJustify; } void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) { if (value == getTextJustify()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextJustify>() = value; + impl_->layout.textJustify = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -522,14 +559,14 @@ PropertyValue<SymbolAnchorType> SymbolLayer::getDefaultTextAnchor() { } PropertyValue<SymbolAnchorType> SymbolLayer::getTextAnchor() const { - return impl().layout.get<TextAnchor>(); + return impl().layout.textAnchor; } void SymbolLayer::setTextAnchor(PropertyValue<SymbolAnchorType> value) { if (value == getTextAnchor()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextAnchor>() = value; + impl_->layout.textAnchor = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -538,14 +575,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextMaxAngle() { } PropertyValue<float> SymbolLayer::getTextMaxAngle() const { - return impl().layout.get<TextMaxAngle>(); + return impl().layout.textMaxAngle; } void SymbolLayer::setTextMaxAngle(PropertyValue<float> value) { if (value == getTextMaxAngle()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextMaxAngle>() = value; + impl_->layout.textMaxAngle = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -554,14 +591,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextRotate() { } PropertyValue<float> SymbolLayer::getTextRotate() const { - return impl().layout.get<TextRotate>(); + return impl().layout.textRotate; } void SymbolLayer::setTextRotate(PropertyValue<float> value) { if (value == getTextRotate()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextRotate>() = value; + impl_->layout.textRotate = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -570,14 +607,14 @@ PropertyValue<float> SymbolLayer::getDefaultTextPadding() { } PropertyValue<float> SymbolLayer::getTextPadding() const { - return impl().layout.get<TextPadding>(); + return impl().layout.textPadding; } void SymbolLayer::setTextPadding(PropertyValue<float> value) { if (value == getTextPadding()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextPadding>() = value; + impl_->layout.textPadding = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -586,14 +623,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextKeepUpright() { } PropertyValue<bool> SymbolLayer::getTextKeepUpright() const { - return impl().layout.get<TextKeepUpright>(); + return impl().layout.textKeepUpright; } void SymbolLayer::setTextKeepUpright(PropertyValue<bool> value) { if (value == getTextKeepUpright()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextKeepUpright>() = value; + impl_->layout.textKeepUpright = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -602,14 +639,14 @@ PropertyValue<TextTransformType> SymbolLayer::getDefaultTextTransform() { } PropertyValue<TextTransformType> SymbolLayer::getTextTransform() const { - return impl().layout.get<TextTransform>(); + return impl().layout.textTransform; } void SymbolLayer::setTextTransform(PropertyValue<TextTransformType> value) { if (value == getTextTransform()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextTransform>() = value; + impl_->layout.textTransform = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -618,14 +655,14 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextOffset() { } PropertyValue<std::array<float, 2>> SymbolLayer::getTextOffset() const { - return impl().layout.get<TextOffset>(); + return impl().layout.textOffset; } void SymbolLayer::setTextOffset(PropertyValue<std::array<float, 2>> value) { if (value == getTextOffset()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextOffset>() = value; + impl_->layout.textOffset = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -634,14 +671,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextAllowOverlap() { } PropertyValue<bool> SymbolLayer::getTextAllowOverlap() const { - return impl().layout.get<TextAllowOverlap>(); + return impl().layout.textAllowOverlap; } void SymbolLayer::setTextAllowOverlap(PropertyValue<bool> value) { if (value == getTextAllowOverlap()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextAllowOverlap>() = value; + impl_->layout.textAllowOverlap = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -650,14 +687,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextIgnorePlacement() { } PropertyValue<bool> SymbolLayer::getTextIgnorePlacement() const { - return impl().layout.get<TextIgnorePlacement>(); + return impl().layout.textIgnorePlacement; } void SymbolLayer::setTextIgnorePlacement(PropertyValue<bool> value) { if (value == getTextIgnorePlacement()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextIgnorePlacement>() = value; + impl_->layout.textIgnorePlacement = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -666,14 +703,14 @@ PropertyValue<bool> SymbolLayer::getDefaultTextOptional() { } PropertyValue<bool> SymbolLayer::getTextOptional() const { - return impl().layout.get<TextOptional>(); + return impl().layout.textOptional; } void SymbolLayer::setTextOptional(PropertyValue<bool> value) { if (value == getTextOptional()) return; auto impl_ = mutableImpl(); - impl_->layout.get<TextOptional>() = value; + impl_->layout.textOptional = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } @@ -685,26 +722,26 @@ PropertyValue<float> SymbolLayer::getDefaultIconOpacity() { } PropertyValue<float> SymbolLayer::getIconOpacity() const { - return impl().paint.template get<IconOpacity>().value; + return impl().paint.iconOpacity.value; } void SymbolLayer::setIconOpacity(PropertyValue<float> value) { if (value == getIconOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconOpacity>().value = value; + impl_->paint.iconOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconOpacity>().options = options; + impl_->paint.iconOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconOpacityTransition() const { - return impl().paint.template get<IconOpacity>().options; + return impl().paint.iconOpacity.options; } PropertyValue<Color> SymbolLayer::getDefaultIconColor() { @@ -712,26 +749,26 @@ PropertyValue<Color> SymbolLayer::getDefaultIconColor() { } PropertyValue<Color> SymbolLayer::getIconColor() const { - return impl().paint.template get<IconColor>().value; + return impl().paint.iconColor.value; } void SymbolLayer::setIconColor(PropertyValue<Color> value) { if (value == getIconColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconColor>().value = value; + impl_->paint.iconColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconColor>().options = options; + impl_->paint.iconColor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconColorTransition() const { - return impl().paint.template get<IconColor>().options; + return impl().paint.iconColor.options; } PropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() { @@ -739,26 +776,26 @@ PropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() { } PropertyValue<Color> SymbolLayer::getIconHaloColor() const { - return impl().paint.template get<IconHaloColor>().value; + return impl().paint.iconHaloColor.value; } void SymbolLayer::setIconHaloColor(PropertyValue<Color> value) { if (value == getIconHaloColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloColor>().value = value; + impl_->paint.iconHaloColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconHaloColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloColor>().options = options; + impl_->paint.iconHaloColor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconHaloColorTransition() const { - return impl().paint.template get<IconHaloColor>().options; + return impl().paint.iconHaloColor.options; } PropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() { @@ -766,26 +803,26 @@ PropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() { } PropertyValue<float> SymbolLayer::getIconHaloWidth() const { - return impl().paint.template get<IconHaloWidth>().value; + return impl().paint.iconHaloWidth.value; } void SymbolLayer::setIconHaloWidth(PropertyValue<float> value) { if (value == getIconHaloWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloWidth>().value = value; + impl_->paint.iconHaloWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconHaloWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloWidth>().options = options; + impl_->paint.iconHaloWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconHaloWidthTransition() const { - return impl().paint.template get<IconHaloWidth>().options; + return impl().paint.iconHaloWidth.options; } PropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() { @@ -793,26 +830,26 @@ PropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() { } PropertyValue<float> SymbolLayer::getIconHaloBlur() const { - return impl().paint.template get<IconHaloBlur>().value; + return impl().paint.iconHaloBlur.value; } void SymbolLayer::setIconHaloBlur(PropertyValue<float> value) { if (value == getIconHaloBlur()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloBlur>().value = value; + impl_->paint.iconHaloBlur.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconHaloBlurTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconHaloBlur>().options = options; + impl_->paint.iconHaloBlur.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconHaloBlurTransition() const { - return impl().paint.template get<IconHaloBlur>().options; + return impl().paint.iconHaloBlur.options; } PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() { @@ -820,26 +857,26 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() { } PropertyValue<std::array<float, 2>> SymbolLayer::getIconTranslate() const { - return impl().paint.template get<IconTranslate>().value; + return impl().paint.iconTranslate.value; } void SymbolLayer::setIconTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getIconTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconTranslate>().value = value; + impl_->paint.iconTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconTranslate>().options = options; + impl_->paint.iconTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconTranslateTransition() const { - return impl().paint.template get<IconTranslate>().options; + return impl().paint.iconTranslate.options; } PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor() { @@ -847,26 +884,26 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor() } PropertyValue<TranslateAnchorType> SymbolLayer::getIconTranslateAnchor() const { - return impl().paint.template get<IconTranslateAnchor>().value; + return impl().paint.iconTranslateAnchor.value; } void SymbolLayer::setIconTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getIconTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<IconTranslateAnchor>().value = value; + impl_->paint.iconTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setIconTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<IconTranslateAnchor>().options = options; + impl_->paint.iconTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getIconTranslateAnchorTransition() const { - return impl().paint.template get<IconTranslateAnchor>().options; + return impl().paint.iconTranslateAnchor.options; } PropertyValue<float> SymbolLayer::getDefaultTextOpacity() { @@ -874,26 +911,26 @@ PropertyValue<float> SymbolLayer::getDefaultTextOpacity() { } PropertyValue<float> SymbolLayer::getTextOpacity() const { - return impl().paint.template get<TextOpacity>().value; + return impl().paint.textOpacity.value; } void SymbolLayer::setTextOpacity(PropertyValue<float> value) { if (value == getTextOpacity()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextOpacity>().value = value; + impl_->paint.textOpacity.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextOpacityTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextOpacity>().options = options; + impl_->paint.textOpacity.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextOpacityTransition() const { - return impl().paint.template get<TextOpacity>().options; + return impl().paint.textOpacity.options; } PropertyValue<Color> SymbolLayer::getDefaultTextColor() { @@ -901,26 +938,26 @@ PropertyValue<Color> SymbolLayer::getDefaultTextColor() { } PropertyValue<Color> SymbolLayer::getTextColor() const { - return impl().paint.template get<TextColor>().value; + return impl().paint.textColor.value; } void SymbolLayer::setTextColor(PropertyValue<Color> value) { if (value == getTextColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextColor>().value = value; + impl_->paint.textColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextColor>().options = options; + impl_->paint.textColor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextColorTransition() const { - return impl().paint.template get<TextColor>().options; + return impl().paint.textColor.options; } PropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() { @@ -928,26 +965,26 @@ PropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() { } PropertyValue<Color> SymbolLayer::getTextHaloColor() const { - return impl().paint.template get<TextHaloColor>().value; + return impl().paint.textHaloColor.value; } void SymbolLayer::setTextHaloColor(PropertyValue<Color> value) { if (value == getTextHaloColor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloColor>().value = value; + impl_->paint.textHaloColor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextHaloColorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloColor>().options = options; + impl_->paint.textHaloColor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextHaloColorTransition() const { - return impl().paint.template get<TextHaloColor>().options; + return impl().paint.textHaloColor.options; } PropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() { @@ -955,26 +992,26 @@ PropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() { } PropertyValue<float> SymbolLayer::getTextHaloWidth() const { - return impl().paint.template get<TextHaloWidth>().value; + return impl().paint.textHaloWidth.value; } void SymbolLayer::setTextHaloWidth(PropertyValue<float> value) { if (value == getTextHaloWidth()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloWidth>().value = value; + impl_->paint.textHaloWidth.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextHaloWidthTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloWidth>().options = options; + impl_->paint.textHaloWidth.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextHaloWidthTransition() const { - return impl().paint.template get<TextHaloWidth>().options; + return impl().paint.textHaloWidth.options; } PropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() { @@ -982,26 +1019,26 @@ PropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() { } PropertyValue<float> SymbolLayer::getTextHaloBlur() const { - return impl().paint.template get<TextHaloBlur>().value; + return impl().paint.textHaloBlur.value; } void SymbolLayer::setTextHaloBlur(PropertyValue<float> value) { if (value == getTextHaloBlur()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloBlur>().value = value; + impl_->paint.textHaloBlur.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextHaloBlurTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextHaloBlur>().options = options; + impl_->paint.textHaloBlur.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextHaloBlurTransition() const { - return impl().paint.template get<TextHaloBlur>().options; + return impl().paint.textHaloBlur.options; } PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() { @@ -1009,26 +1046,26 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() { } PropertyValue<std::array<float, 2>> SymbolLayer::getTextTranslate() const { - return impl().paint.template get<TextTranslate>().value; + return impl().paint.textTranslate.value; } void SymbolLayer::setTextTranslate(PropertyValue<std::array<float, 2>> value) { if (value == getTextTranslate()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextTranslate>().value = value; + impl_->paint.textTranslate.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextTranslateTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextTranslate>().options = options; + impl_->paint.textTranslate.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextTranslateTransition() const { - return impl().paint.template get<TextTranslate>().options; + return impl().paint.textTranslate.options; } PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor() { @@ -1036,26 +1073,26 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor() } PropertyValue<TranslateAnchorType> SymbolLayer::getTextTranslateAnchor() const { - return impl().paint.template get<TextTranslateAnchor>().value; + return impl().paint.textTranslateAnchor.value; } void SymbolLayer::setTextTranslateAnchor(PropertyValue<TranslateAnchorType> value) { if (value == getTextTranslateAnchor()) return; auto impl_ = mutableImpl(); - impl_->paint.template get<TextTranslateAnchor>().value = value; + impl_->paint.textTranslateAnchor.value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void SymbolLayer::setTextTranslateAnchorTransition(const TransitionOptions& options) { auto impl_ = mutableImpl(); - impl_->paint.template get<TextTranslateAnchor>().options = options; + impl_->paint.textTranslateAnchor.options = options; baseImpl = std::move(impl_); } TransitionOptions SymbolLayer::getTextTranslateAnchorTransition() const { - return impl().paint.template get<TextTranslateAnchor>().options; + return impl().paint.textTranslateAnchor.options; } using namespace conversion; diff --git a/src/mbgl/style/layers/symbol_layer_properties.cpp b/src/mbgl/style/layers/symbol_layer_properties.cpp index 5a1ce713ba..8d2cc597e0 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.cpp +++ b/src/mbgl/style/layers/symbol_layer_properties.cpp @@ -5,5 +5,431 @@ namespace mbgl { namespace style { +bool operator==(const SymbolLayoutProperties::Unevaluated& lhs, const SymbolLayoutProperties::Unevaluated& rhs) { + return true + && lhs.symbolPlacement == rhs.symbolPlacement + && lhs.symbolSpacing == rhs.symbolSpacing + && lhs.symbolAvoidEdges == rhs.symbolAvoidEdges + && lhs.iconAllowOverlap == rhs.iconAllowOverlap + && lhs.iconIgnorePlacement == rhs.iconIgnorePlacement + && lhs.iconOptional == rhs.iconOptional + && lhs.iconRotationAlignment == rhs.iconRotationAlignment + && lhs.iconSize == rhs.iconSize + && lhs.iconTextFit == rhs.iconTextFit + && lhs.iconTextFitPadding == rhs.iconTextFitPadding + && lhs.iconImage == rhs.iconImage + && lhs.iconRotate == rhs.iconRotate + && lhs.iconPadding == rhs.iconPadding + && lhs.iconKeepUpright == rhs.iconKeepUpright + && lhs.iconOffset == rhs.iconOffset + && lhs.iconAnchor == rhs.iconAnchor + && lhs.iconPitchAlignment == rhs.iconPitchAlignment + && lhs.textPitchAlignment == rhs.textPitchAlignment + && lhs.textRotationAlignment == rhs.textRotationAlignment + && lhs.textField == rhs.textField + && lhs.textFont == rhs.textFont + && lhs.textSize == rhs.textSize + && lhs.textMaxWidth == rhs.textMaxWidth + && lhs.textLineHeight == rhs.textLineHeight + && lhs.textLetterSpacing == rhs.textLetterSpacing + && lhs.textJustify == rhs.textJustify + && lhs.textAnchor == rhs.textAnchor + && lhs.textMaxAngle == rhs.textMaxAngle + && lhs.textRotate == rhs.textRotate + && lhs.textPadding == rhs.textPadding + && lhs.textKeepUpright == rhs.textKeepUpright + && lhs.textTransform == rhs.textTransform + && lhs.textOffset == rhs.textOffset + && lhs.textAllowOverlap == rhs.textAllowOverlap + && lhs.textIgnorePlacement == rhs.textIgnorePlacement + && lhs.textOptional == rhs.textOptional + ; +} + +SymbolLayoutProperties::PossiblyEvaluated SymbolLayoutProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + symbolPlacement.evaluate(typename SymbolPlacement::EvaluatorType(parameters, SymbolPlacement::defaultValue()), parameters.now), + symbolSpacing.evaluate(typename SymbolSpacing::EvaluatorType(parameters, SymbolSpacing::defaultValue()), parameters.now), + symbolAvoidEdges.evaluate(typename SymbolAvoidEdges::EvaluatorType(parameters, SymbolAvoidEdges::defaultValue()), parameters.now), + iconAllowOverlap.evaluate(typename IconAllowOverlap::EvaluatorType(parameters, IconAllowOverlap::defaultValue()), parameters.now), + iconIgnorePlacement.evaluate(typename IconIgnorePlacement::EvaluatorType(parameters, IconIgnorePlacement::defaultValue()), parameters.now), + iconOptional.evaluate(typename IconOptional::EvaluatorType(parameters, IconOptional::defaultValue()), parameters.now), + iconRotationAlignment.evaluate(typename IconRotationAlignment::EvaluatorType(parameters, IconRotationAlignment::defaultValue()), parameters.now), + iconSize.evaluate(typename IconSize::EvaluatorType(parameters, IconSize::defaultValue()), parameters.now), + iconTextFit.evaluate(typename IconTextFit::EvaluatorType(parameters, IconTextFit::defaultValue()), parameters.now), + iconTextFitPadding.evaluate(typename IconTextFitPadding::EvaluatorType(parameters, IconTextFitPadding::defaultValue()), parameters.now), + iconImage.evaluate(typename IconImage::EvaluatorType(parameters, IconImage::defaultValue()), parameters.now), + iconRotate.evaluate(typename IconRotate::EvaluatorType(parameters, IconRotate::defaultValue()), parameters.now), + iconPadding.evaluate(typename IconPadding::EvaluatorType(parameters, IconPadding::defaultValue()), parameters.now), + iconKeepUpright.evaluate(typename IconKeepUpright::EvaluatorType(parameters, IconKeepUpright::defaultValue()), parameters.now), + iconOffset.evaluate(typename IconOffset::EvaluatorType(parameters, IconOffset::defaultValue()), parameters.now), + iconAnchor.evaluate(typename IconAnchor::EvaluatorType(parameters, IconAnchor::defaultValue()), parameters.now), + iconPitchAlignment.evaluate(typename IconPitchAlignment::EvaluatorType(parameters, IconPitchAlignment::defaultValue()), parameters.now), + textPitchAlignment.evaluate(typename TextPitchAlignment::EvaluatorType(parameters, TextPitchAlignment::defaultValue()), parameters.now), + textRotationAlignment.evaluate(typename TextRotationAlignment::EvaluatorType(parameters, TextRotationAlignment::defaultValue()), parameters.now), + textField.evaluate(typename TextField::EvaluatorType(parameters, TextField::defaultValue()), parameters.now), + textFont.evaluate(typename TextFont::EvaluatorType(parameters, TextFont::defaultValue()), parameters.now), + textSize.evaluate(typename TextSize::EvaluatorType(parameters, TextSize::defaultValue()), parameters.now), + textMaxWidth.evaluate(typename TextMaxWidth::EvaluatorType(parameters, TextMaxWidth::defaultValue()), parameters.now), + textLineHeight.evaluate(typename TextLineHeight::EvaluatorType(parameters, TextLineHeight::defaultValue()), parameters.now), + textLetterSpacing.evaluate(typename TextLetterSpacing::EvaluatorType(parameters, TextLetterSpacing::defaultValue()), parameters.now), + textJustify.evaluate(typename TextJustify::EvaluatorType(parameters, TextJustify::defaultValue()), parameters.now), + textAnchor.evaluate(typename TextAnchor::EvaluatorType(parameters, TextAnchor::defaultValue()), parameters.now), + textMaxAngle.evaluate(typename TextMaxAngle::EvaluatorType(parameters, TextMaxAngle::defaultValue()), parameters.now), + textRotate.evaluate(typename TextRotate::EvaluatorType(parameters, TextRotate::defaultValue()), parameters.now), + textPadding.evaluate(typename TextPadding::EvaluatorType(parameters, TextPadding::defaultValue()), parameters.now), + textKeepUpright.evaluate(typename TextKeepUpright::EvaluatorType(parameters, TextKeepUpright::defaultValue()), parameters.now), + textTransform.evaluate(typename TextTransform::EvaluatorType(parameters, TextTransform::defaultValue()), parameters.now), + textOffset.evaluate(typename TextOffset::EvaluatorType(parameters, TextOffset::defaultValue()), parameters.now), + textAllowOverlap.evaluate(typename TextAllowOverlap::EvaluatorType(parameters, TextAllowOverlap::defaultValue()), parameters.now), + textIgnorePlacement.evaluate(typename TextIgnorePlacement::EvaluatorType(parameters, TextIgnorePlacement::defaultValue()), parameters.now), + textOptional.evaluate(typename TextOptional::EvaluatorType(parameters, TextOptional::defaultValue()), parameters.now), + }; +} + +SymbolLayoutProperties::Evaluated SymbolLayoutProperties::PossiblyEvaluated::evaluate(float z, const GeometryTileFeature& feature) const { + return Evaluated { + symbolPlacement, + symbolSpacing, + symbolAvoidEdges, + iconAllowOverlap, + iconIgnorePlacement, + iconOptional, + iconRotationAlignment, + iconSize.evaluate(feature, z, IconSize::defaultValue()), + iconTextFit, + iconTextFitPadding, + iconImage.evaluate(feature, z, IconImage::defaultValue()), + iconRotate.evaluate(feature, z, IconRotate::defaultValue()), + iconPadding, + iconKeepUpright, + iconOffset.evaluate(feature, z, IconOffset::defaultValue()), + iconAnchor.evaluate(feature, z, IconAnchor::defaultValue()), + iconPitchAlignment, + textPitchAlignment, + textRotationAlignment, + textField.evaluate(feature, z, TextField::defaultValue()), + textFont.evaluate(feature, z, TextFont::defaultValue()), + textSize.evaluate(feature, z, TextSize::defaultValue()), + textMaxWidth.evaluate(feature, z, TextMaxWidth::defaultValue()), + textLineHeight, + textLetterSpacing.evaluate(feature, z, TextLetterSpacing::defaultValue()), + textJustify.evaluate(feature, z, TextJustify::defaultValue()), + textAnchor.evaluate(feature, z, TextAnchor::defaultValue()), + textMaxAngle, + textRotate.evaluate(feature, z, TextRotate::defaultValue()), + textPadding, + textKeepUpright, + textTransform.evaluate(feature, z, TextTransform::defaultValue()), + textOffset.evaluate(feature, z, TextOffset::defaultValue()), + textAllowOverlap, + textIgnorePlacement, + textOptional, + }; +} + +SymbolPaintProperties::Unevaluated SymbolPaintProperties::Transitionable::transitioned(const TransitionParameters& parameters, Unevaluated&& prior) const { + return Unevaluated { + iconOpacity.transition(parameters, std::move(prior.iconOpacity)), + iconColor.transition(parameters, std::move(prior.iconColor)), + iconHaloColor.transition(parameters, std::move(prior.iconHaloColor)), + iconHaloWidth.transition(parameters, std::move(prior.iconHaloWidth)), + iconHaloBlur.transition(parameters, std::move(prior.iconHaloBlur)), + iconTranslate.transition(parameters, std::move(prior.iconTranslate)), + iconTranslateAnchor.transition(parameters, std::move(prior.iconTranslateAnchor)), + textOpacity.transition(parameters, std::move(prior.textOpacity)), + textColor.transition(parameters, std::move(prior.textColor)), + textHaloColor.transition(parameters, std::move(prior.textHaloColor)), + textHaloWidth.transition(parameters, std::move(prior.textHaloWidth)), + textHaloBlur.transition(parameters, std::move(prior.textHaloBlur)), + textTranslate.transition(parameters, std::move(prior.textTranslate)), + textTranslateAnchor.transition(parameters, std::move(prior.textTranslateAnchor)), + }; +} + +SymbolPaintProperties::Unevaluated SymbolPaintProperties::Transitionable::untransitioned() const { + return Unevaluated { + Transitioning<PropertyValue<float>>(iconOpacity.value), + Transitioning<PropertyValue<Color>>(iconColor.value), + Transitioning<PropertyValue<Color>>(iconHaloColor.value), + Transitioning<PropertyValue<float>>(iconHaloWidth.value), + Transitioning<PropertyValue<float>>(iconHaloBlur.value), + Transitioning<PropertyValue<std::array<float, 2>>>(iconTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(iconTranslateAnchor.value), + Transitioning<PropertyValue<float>>(textOpacity.value), + Transitioning<PropertyValue<Color>>(textColor.value), + Transitioning<PropertyValue<Color>>(textHaloColor.value), + Transitioning<PropertyValue<float>>(textHaloWidth.value), + Transitioning<PropertyValue<float>>(textHaloBlur.value), + Transitioning<PropertyValue<std::array<float, 2>>>(textTranslate.value), + Transitioning<PropertyValue<TranslateAnchorType>>(textTranslateAnchor.value), + }; +} + +bool SymbolPaintProperties::Transitionable::hasDataDrivenPropertyDifference(const Transitionable& other) const { + return false + || iconOpacity.value.hasDataDrivenPropertyDifference(other.iconOpacity.value) + || iconColor.value.hasDataDrivenPropertyDifference(other.iconColor.value) + || iconHaloColor.value.hasDataDrivenPropertyDifference(other.iconHaloColor.value) + || iconHaloWidth.value.hasDataDrivenPropertyDifference(other.iconHaloWidth.value) + || iconHaloBlur.value.hasDataDrivenPropertyDifference(other.iconHaloBlur.value) + || iconTranslate.value.hasDataDrivenPropertyDifference(other.iconTranslate.value) + || iconTranslateAnchor.value.hasDataDrivenPropertyDifference(other.iconTranslateAnchor.value) + || textOpacity.value.hasDataDrivenPropertyDifference(other.textOpacity.value) + || textColor.value.hasDataDrivenPropertyDifference(other.textColor.value) + || textHaloColor.value.hasDataDrivenPropertyDifference(other.textHaloColor.value) + || textHaloWidth.value.hasDataDrivenPropertyDifference(other.textHaloWidth.value) + || textHaloBlur.value.hasDataDrivenPropertyDifference(other.textHaloBlur.value) + || textTranslate.value.hasDataDrivenPropertyDifference(other.textTranslate.value) + || textTranslateAnchor.value.hasDataDrivenPropertyDifference(other.textTranslateAnchor.value) + ; +} + +bool SymbolPaintProperties::Unevaluated::hasTransition() const { + return false + || iconOpacity.hasTransition() + || iconColor.hasTransition() + || iconHaloColor.hasTransition() + || iconHaloWidth.hasTransition() + || iconHaloBlur.hasTransition() + || iconTranslate.hasTransition() + || iconTranslateAnchor.hasTransition() + || textOpacity.hasTransition() + || textColor.hasTransition() + || textHaloColor.hasTransition() + || textHaloWidth.hasTransition() + || textHaloBlur.hasTransition() + || textTranslate.hasTransition() + || textTranslateAnchor.hasTransition() + ; +} + +SymbolPaintProperties::PossiblyEvaluated SymbolPaintProperties::Unevaluated::evaluate(const PropertyEvaluationParameters& parameters) const { + return PossiblyEvaluated { + iconOpacity.evaluate(typename IconOpacity::EvaluatorType(parameters, IconOpacity::defaultValue()), parameters.now), + iconColor.evaluate(typename IconColor::EvaluatorType(parameters, IconColor::defaultValue()), parameters.now), + iconHaloColor.evaluate(typename IconHaloColor::EvaluatorType(parameters, IconHaloColor::defaultValue()), parameters.now), + iconHaloWidth.evaluate(typename IconHaloWidth::EvaluatorType(parameters, IconHaloWidth::defaultValue()), parameters.now), + iconHaloBlur.evaluate(typename IconHaloBlur::EvaluatorType(parameters, IconHaloBlur::defaultValue()), parameters.now), + iconTranslate.evaluate(typename IconTranslate::EvaluatorType(parameters, IconTranslate::defaultValue()), parameters.now), + iconTranslateAnchor.evaluate(typename IconTranslateAnchor::EvaluatorType(parameters, IconTranslateAnchor::defaultValue()), parameters.now), + textOpacity.evaluate(typename TextOpacity::EvaluatorType(parameters, TextOpacity::defaultValue()), parameters.now), + textColor.evaluate(typename TextColor::EvaluatorType(parameters, TextColor::defaultValue()), parameters.now), + textHaloColor.evaluate(typename TextHaloColor::EvaluatorType(parameters, TextHaloColor::defaultValue()), parameters.now), + textHaloWidth.evaluate(typename TextHaloWidth::EvaluatorType(parameters, TextHaloWidth::defaultValue()), parameters.now), + textHaloBlur.evaluate(typename TextHaloBlur::EvaluatorType(parameters, TextHaloBlur::defaultValue()), parameters.now), + textTranslate.evaluate(typename TextTranslate::EvaluatorType(parameters, TextTranslate::defaultValue()), parameters.now), + textTranslateAnchor.evaluate(typename TextTranslateAnchor::EvaluatorType(parameters, TextTranslateAnchor::defaultValue()), parameters.now), + }; +} + + + + +IconPaintProperties::Binders IconPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(iconOpacity, z, IconOpacity::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_fill_color::Type>::create(iconColor, z, IconColor::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_halo_color::Type>::create(iconHaloColor, z, IconHaloColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_halo_width::Type>::create(iconHaloWidth, z, IconHaloWidth::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_halo_blur::Type>::create(iconHaloBlur, z, IconHaloBlur::defaultValue()), + }; +} + +std::bitset<8> IconPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, iconOpacity.isConstant()); + result.set(1, iconColor.isConstant()); + result.set(2, iconHaloColor.isConstant()); + result.set(3, iconHaloWidth.isConstant()); + result.set(4, iconHaloBlur.isConstant()); + return result; +} + +std::vector<std::string> IconPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(iconOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconOpacity::Uniform::name() + : std::string()); + result.push_back(iconColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconColor::Uniform::name() + : std::string()); + result.push_back(iconHaloColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconHaloColor::Uniform::name() + : std::string()); + result.push_back(iconHaloWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconHaloWidth::Uniform::name() + : std::string()); + result.push_back(iconHaloBlur.isConstant() + ? std::string("#define HAS_UNIFORM_") + IconHaloBlur::Uniform::name() + : std::string()); + return result; +} + +void IconPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + iconOpacity->populateVertexVector(feature, length); + iconColor->populateVertexVector(feature, length); + iconHaloColor->populateVertexVector(feature, length); + iconHaloWidth->populateVertexVector(feature, length); + iconHaloBlur->populateVertexVector(feature, length); +} + +void IconPaintProperties::Binders::upload(gl::Context& context) { + iconOpacity->upload(context); + iconColor->upload(context); + iconHaloColor->upload(context); + iconHaloWidth->upload(context); + iconHaloBlur->upload(context); +} + +IconPaintProperties::Binders::AttributeBindings IconPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + iconOpacity->attributeBinding(currentProperties.iconOpacity), + iconColor->attributeBinding(currentProperties.iconColor), + iconHaloColor->attributeBinding(currentProperties.iconHaloColor), + iconHaloWidth->attributeBinding(currentProperties.iconHaloWidth), + iconHaloBlur->attributeBinding(currentProperties.iconHaloBlur), + }; +} + +IconPaintProperties::Binders::UniformValues IconPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_opacity>::Value { + iconOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_fill_color>::Value { + iconColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_color>::Value { + iconHaloColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_width>::Value { + iconHaloWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_blur>::Value { + iconHaloBlur->interpolationFactor(currentZoom) + }, + typename uniforms::u_opacity::Value { + iconOpacity->uniformValue(currentProperties.iconOpacity) + }, + typename uniforms::u_fill_color::Value { + iconColor->uniformValue(currentProperties.iconColor) + }, + typename uniforms::u_halo_color::Value { + iconHaloColor->uniformValue(currentProperties.iconHaloColor) + }, + typename uniforms::u_halo_width::Value { + iconHaloWidth->uniformValue(currentProperties.iconHaloWidth) + }, + typename uniforms::u_halo_blur::Value { + iconHaloBlur->uniformValue(currentProperties.iconHaloBlur) + }, + }; +} + + + +TextPaintProperties::Binders TextPaintProperties::PossiblyEvaluated::createBinders(float z) const { + return Binders { + PaintPropertyBinder<float, typename attributes::a_opacity::Type>::create(textOpacity, z, TextOpacity::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_fill_color::Type>::create(textColor, z, TextColor::defaultValue()), + PaintPropertyBinder<Color, typename attributes::a_halo_color::Type>::create(textHaloColor, z, TextHaloColor::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_halo_width::Type>::create(textHaloWidth, z, TextHaloWidth::defaultValue()), + PaintPropertyBinder<float, typename attributes::a_halo_blur::Type>::create(textHaloBlur, z, TextHaloBlur::defaultValue()), + }; +} + +std::bitset<8> TextPaintProperties::PossiblyEvaluated::constants() const { + std::bitset<8> result; + result.set(0, textOpacity.isConstant()); + result.set(1, textColor.isConstant()); + result.set(2, textHaloColor.isConstant()); + result.set(3, textHaloWidth.isConstant()); + result.set(4, textHaloBlur.isConstant()); + return result; +} + +std::vector<std::string> TextPaintProperties::PossiblyEvaluated::defines() const { + std::vector<std::string> result; + result.push_back(textOpacity.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextOpacity::Uniform::name() + : std::string()); + result.push_back(textColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextColor::Uniform::name() + : std::string()); + result.push_back(textHaloColor.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextHaloColor::Uniform::name() + : std::string()); + result.push_back(textHaloWidth.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextHaloWidth::Uniform::name() + : std::string()); + result.push_back(textHaloBlur.isConstant() + ? std::string("#define HAS_UNIFORM_") + TextHaloBlur::Uniform::name() + : std::string()); + return result; +} + +void TextPaintProperties::Binders::populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + textOpacity->populateVertexVector(feature, length); + textColor->populateVertexVector(feature, length); + textHaloColor->populateVertexVector(feature, length); + textHaloWidth->populateVertexVector(feature, length); + textHaloBlur->populateVertexVector(feature, length); +} + +void TextPaintProperties::Binders::upload(gl::Context& context) { + textOpacity->upload(context); + textColor->upload(context); + textHaloColor->upload(context); + textHaloWidth->upload(context); + textHaloBlur->upload(context); +} + +TextPaintProperties::Binders::AttributeBindings TextPaintProperties::Binders::attributeBindings(const PossiblyEvaluated& currentProperties) const { + return AttributeBindings { + textOpacity->attributeBinding(currentProperties.textOpacity), + textColor->attributeBinding(currentProperties.textColor), + textHaloColor->attributeBinding(currentProperties.textHaloColor), + textHaloWidth->attributeBinding(currentProperties.textHaloWidth), + textHaloBlur->attributeBinding(currentProperties.textHaloBlur), + }; +} + +TextPaintProperties::Binders::UniformValues TextPaintProperties::Binders::uniformValues(float currentZoom, const PossiblyEvaluated& currentProperties) const { + return UniformValues { + typename InterpolationUniform<attributes::a_opacity>::Value { + textOpacity->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_fill_color>::Value { + textColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_color>::Value { + textHaloColor->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_width>::Value { + textHaloWidth->interpolationFactor(currentZoom) + }, + typename InterpolationUniform<attributes::a_halo_blur>::Value { + textHaloBlur->interpolationFactor(currentZoom) + }, + typename uniforms::u_opacity::Value { + textOpacity->uniformValue(currentProperties.textOpacity) + }, + typename uniforms::u_fill_color::Value { + textColor->uniformValue(currentProperties.textColor) + }, + typename uniforms::u_halo_color::Value { + textHaloColor->uniformValue(currentProperties.textHaloColor) + }, + typename uniforms::u_halo_width::Value { + textHaloWidth->uniformValue(currentProperties.textHaloWidth) + }, + typename uniforms::u_halo_blur::Value { + textHaloBlur->uniformValue(currentProperties.textHaloBlur) + }, + }; +} + + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index e70ac28d59..d8f4d42d41 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -248,61 +248,328 @@ struct TextTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -class SymbolLayoutProperties : public Properties< - SymbolPlacement, - SymbolSpacing, - SymbolAvoidEdges, - IconAllowOverlap, - IconIgnorePlacement, - IconOptional, - IconRotationAlignment, - IconSize, - IconTextFit, - IconTextFitPadding, - IconImage, - IconRotate, - IconPadding, - IconKeepUpright, - IconOffset, - IconAnchor, - IconPitchAlignment, - TextPitchAlignment, - TextRotationAlignment, - TextField, - TextFont, - TextSize, - TextMaxWidth, - TextLineHeight, - TextLetterSpacing, - TextJustify, - TextAnchor, - TextMaxAngle, - TextRotate, - TextPadding, - TextKeepUpright, - TextTransform, - TextOffset, - TextAllowOverlap, - TextIgnorePlacement, - TextOptional -> {}; - -class SymbolPaintProperties : public Properties< - IconOpacity, - IconColor, - IconHaloColor, - IconHaloWidth, - IconHaloBlur, - IconTranslate, - IconTranslateAnchor, - TextOpacity, - TextColor, - TextHaloColor, - TextHaloWidth, - TextHaloBlur, - TextTranslate, - TextTranslateAnchor -> {}; +class SymbolLayoutProperties { +public: + class Evaluated { + public: + SymbolPlacementType symbolPlacement; + float symbolSpacing; + bool symbolAvoidEdges; + bool iconAllowOverlap; + bool iconIgnorePlacement; + bool iconOptional; + AlignmentType iconRotationAlignment; + float iconSize; + IconTextFitType iconTextFit; + std::array<float, 4> iconTextFitPadding; + std::string iconImage; + float iconRotate; + float iconPadding; + bool iconKeepUpright; + std::array<float, 2> iconOffset; + SymbolAnchorType iconAnchor; + AlignmentType iconPitchAlignment; + AlignmentType textPitchAlignment; + AlignmentType textRotationAlignment; + std::string textField; + std::vector<std::string> textFont; + float textSize; + float textMaxWidth; + float textLineHeight; + float textLetterSpacing; + TextJustifyType textJustify; + SymbolAnchorType textAnchor; + float textMaxAngle; + float textRotate; + float textPadding; + bool textKeepUpright; + TextTransformType textTransform; + std::array<float, 2> textOffset; + bool textAllowOverlap; + bool textIgnorePlacement; + bool textOptional; + }; + + class PossiblyEvaluated { + public: + SymbolPlacementType symbolPlacement; + float symbolSpacing; + bool symbolAvoidEdges; + bool iconAllowOverlap; + bool iconIgnorePlacement; + bool iconOptional; + AlignmentType iconRotationAlignment; + PossiblyEvaluatedPropertyValue<float> iconSize; + IconTextFitType iconTextFit; + std::array<float, 4> iconTextFitPadding; + PossiblyEvaluatedPropertyValue<std::string> iconImage; + PossiblyEvaluatedPropertyValue<float> iconRotate; + float iconPadding; + bool iconKeepUpright; + PossiblyEvaluatedPropertyValue<std::array<float, 2>> iconOffset; + PossiblyEvaluatedPropertyValue<SymbolAnchorType> iconAnchor; + AlignmentType iconPitchAlignment; + AlignmentType textPitchAlignment; + AlignmentType textRotationAlignment; + PossiblyEvaluatedPropertyValue<std::string> textField; + PossiblyEvaluatedPropertyValue<std::vector<std::string>> textFont; + PossiblyEvaluatedPropertyValue<float> textSize; + PossiblyEvaluatedPropertyValue<float> textMaxWidth; + float textLineHeight; + PossiblyEvaluatedPropertyValue<float> textLetterSpacing; + PossiblyEvaluatedPropertyValue<TextJustifyType> textJustify; + PossiblyEvaluatedPropertyValue<SymbolAnchorType> textAnchor; + float textMaxAngle; + PossiblyEvaluatedPropertyValue<float> textRotate; + float textPadding; + bool textKeepUpright; + PossiblyEvaluatedPropertyValue<TextTransformType> textTransform; + PossiblyEvaluatedPropertyValue<std::array<float, 2>> textOffset; + bool textAllowOverlap; + bool textIgnorePlacement; + bool textOptional; + + Evaluated evaluate(float z, const GeometryTileFeature& feature) const; + }; + + class Unevaluated { + public: + PropertyValue<SymbolPlacementType> symbolPlacement; + PropertyValue<float> symbolSpacing; + PropertyValue<bool> symbolAvoidEdges; + PropertyValue<bool> iconAllowOverlap; + PropertyValue<bool> iconIgnorePlacement; + PropertyValue<bool> iconOptional; + PropertyValue<AlignmentType> iconRotationAlignment; + PropertyValue<float> iconSize; + PropertyValue<IconTextFitType> iconTextFit; + PropertyValue<std::array<float, 4>> iconTextFitPadding; + PropertyValue<std::string> iconImage; + PropertyValue<float> iconRotate; + PropertyValue<float> iconPadding; + PropertyValue<bool> iconKeepUpright; + PropertyValue<std::array<float, 2>> iconOffset; + PropertyValue<SymbolAnchorType> iconAnchor; + PropertyValue<AlignmentType> iconPitchAlignment; + PropertyValue<AlignmentType> textPitchAlignment; + PropertyValue<AlignmentType> textRotationAlignment; + PropertyValue<std::string> textField; + PropertyValue<std::vector<std::string>> textFont; + PropertyValue<float> textSize; + PropertyValue<float> textMaxWidth; + PropertyValue<float> textLineHeight; + PropertyValue<float> textLetterSpacing; + PropertyValue<TextJustifyType> textJustify; + PropertyValue<SymbolAnchorType> textAnchor; + PropertyValue<float> textMaxAngle; + PropertyValue<float> textRotate; + PropertyValue<float> textPadding; + PropertyValue<bool> textKeepUpright; + PropertyValue<TextTransformType> textTransform; + PropertyValue<std::array<float, 2>> textOffset; + PropertyValue<bool> textAllowOverlap; + PropertyValue<bool> textIgnorePlacement; + PropertyValue<bool> textOptional; + + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + + friend bool operator==(const Unevaluated&, const Unevaluated&); + friend inline bool operator!=(const Unevaluated& lhs, const Unevaluated& rhs) { return !(lhs == rhs); } + }; +}; + +class SymbolPaintProperties { +public: + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> iconOpacity; + PossiblyEvaluatedPropertyValue<Color> iconColor; + PossiblyEvaluatedPropertyValue<Color> iconHaloColor; + PossiblyEvaluatedPropertyValue<float> iconHaloWidth; + PossiblyEvaluatedPropertyValue<float> iconHaloBlur; + std::array<float, 2> iconTranslate; + TranslateAnchorType iconTranslateAnchor; + PossiblyEvaluatedPropertyValue<float> textOpacity; + PossiblyEvaluatedPropertyValue<Color> textColor; + PossiblyEvaluatedPropertyValue<Color> textHaloColor; + PossiblyEvaluatedPropertyValue<float> textHaloWidth; + PossiblyEvaluatedPropertyValue<float> textHaloBlur; + std::array<float, 2> textTranslate; + TranslateAnchorType textTranslateAnchor; + }; + + class Unevaluated { + public: + style::Transitioning<PropertyValue<float>> iconOpacity; + style::Transitioning<PropertyValue<Color>> iconColor; + style::Transitioning<PropertyValue<Color>> iconHaloColor; + style::Transitioning<PropertyValue<float>> iconHaloWidth; + style::Transitioning<PropertyValue<float>> iconHaloBlur; + style::Transitioning<PropertyValue<std::array<float, 2>>> iconTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> iconTranslateAnchor; + style::Transitioning<PropertyValue<float>> textOpacity; + style::Transitioning<PropertyValue<Color>> textColor; + style::Transitioning<PropertyValue<Color>> textHaloColor; + style::Transitioning<PropertyValue<float>> textHaloWidth; + style::Transitioning<PropertyValue<float>> textHaloBlur; + style::Transitioning<PropertyValue<std::array<float, 2>>> textTranslate; + style::Transitioning<PropertyValue<TranslateAnchorType>> textTranslateAnchor; + + bool hasTransition() const; + PossiblyEvaluated evaluate(const PropertyEvaluationParameters&) const; + }; + + class Transitionable { + public: + style::Transitionable<PropertyValue<float>> iconOpacity; + style::Transitionable<PropertyValue<Color>> iconColor; + style::Transitionable<PropertyValue<Color>> iconHaloColor; + style::Transitionable<PropertyValue<float>> iconHaloWidth; + style::Transitionable<PropertyValue<float>> iconHaloBlur; + style::Transitionable<PropertyValue<std::array<float, 2>>> iconTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> iconTranslateAnchor; + style::Transitionable<PropertyValue<float>> textOpacity; + style::Transitionable<PropertyValue<Color>> textColor; + style::Transitionable<PropertyValue<Color>> textHaloColor; + style::Transitionable<PropertyValue<float>> textHaloWidth; + style::Transitionable<PropertyValue<float>> textHaloBlur; + style::Transitionable<PropertyValue<std::array<float, 2>>> textTranslate; + style::Transitionable<PropertyValue<TranslateAnchorType>> textTranslateAnchor; + + Unevaluated transitioned(const TransitionParameters&, Unevaluated&& prior) const; + Unevaluated untransitioned() const; + + bool hasDataDrivenPropertyDifference(const Transitionable& other) const; + }; +}; + +// {icon,text}-specific paint-property packs for use in the symbol Programs. +// Since each program deals either with icons or text, using a smaller property set +// lets us avoid unnecessarily binding attributes for properties the program wouldn't use. + + +class IconPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> iconOpacity; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_fill_color::Type>> iconColor; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_halo_color::Type>> iconHaloColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_halo_width::Type>> iconHaloWidth; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_halo_blur::Type>> iconHaloBlur; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_fill_color>, + ZoomInterpolatedAttribute<attributes::a_halo_color>, + ZoomInterpolatedAttribute<attributes::a_halo_width>, + ZoomInterpolatedAttribute<attributes::a_halo_blur> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_fill_color>, + InterpolationUniform<attributes::a_halo_color>, + InterpolationUniform<attributes::a_halo_width>, + InterpolationUniform<attributes::a_halo_blur>, + uniforms::u_opacity, + uniforms::u_fill_color, + uniforms::u_halo_color, + uniforms::u_halo_width, + uniforms::u_halo_blur + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> iconOpacity; + PossiblyEvaluatedPropertyValue<Color> iconColor; + PossiblyEvaluatedPropertyValue<Color> iconHaloColor; + PossiblyEvaluatedPropertyValue<float> iconHaloWidth; + PossiblyEvaluatedPropertyValue<float> iconHaloBlur; + std::array<float, 2> iconTranslate; + TranslateAnchorType iconTranslateAnchor; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; +}; + + +class TextPaintProperties { +public: + class PossiblyEvaluated; + + class Binders { + public: + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_opacity::Type>> textOpacity; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_fill_color::Type>> textColor; + std::unique_ptr<PaintPropertyBinder<Color, typename attributes::a_halo_color::Type>> textHaloColor; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_halo_width::Type>> textHaloWidth; + std::unique_ptr<PaintPropertyBinder<float, typename attributes::a_halo_blur::Type>> textHaloBlur; + + void populateVertexVectors(const GeometryTileFeature&, std::size_t length); + void upload(gl::Context&); + + using Attributes = gl::Attributes< + ZoomInterpolatedAttribute<attributes::a_opacity>, + ZoomInterpolatedAttribute<attributes::a_fill_color>, + ZoomInterpolatedAttribute<attributes::a_halo_color>, + ZoomInterpolatedAttribute<attributes::a_halo_width>, + ZoomInterpolatedAttribute<attributes::a_halo_blur> + >; + + using Uniforms = gl::Uniforms< + InterpolationUniform<attributes::a_opacity>, + InterpolationUniform<attributes::a_fill_color>, + InterpolationUniform<attributes::a_halo_color>, + InterpolationUniform<attributes::a_halo_width>, + InterpolationUniform<attributes::a_halo_blur>, + uniforms::u_opacity, + uniforms::u_fill_color, + uniforms::u_halo_color, + uniforms::u_halo_width, + uniforms::u_halo_blur + >; + + using AttributeBindings = typename Attributes::Bindings; + using UniformValues = typename Uniforms::Values; + + AttributeBindings attributeBindings(const PossiblyEvaluated&) const; + UniformValues uniformValues(float z, const PossiblyEvaluated&) const; + }; + + class PossiblyEvaluated { + public: + PossiblyEvaluatedPropertyValue<float> textOpacity; + PossiblyEvaluatedPropertyValue<Color> textColor; + PossiblyEvaluatedPropertyValue<Color> textHaloColor; + PossiblyEvaluatedPropertyValue<float> textHaloWidth; + PossiblyEvaluatedPropertyValue<float> textHaloBlur; + std::array<float, 2> textTranslate; + TranslateAnchorType textTranslateAnchor; + + Binders createBinders(float z) const; + + std::bitset<8> constants() const; + std::vector<std::string> defines() const; + }; +}; + } // namespace style } // namespace mbgl |