diff options
author | Lauren Budorick <lauren@mapbox.com> | 2017-04-27 15:56:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-27 15:56:55 -0700 |
commit | f6e79d70735361438655f279c8699a786d25458c (patch) | |
tree | cc01ae7aba097bae4aa84beb12ac6b8f34f4d51a /src/mbgl/style | |
parent | 839ad87f37a4880804fb4c79157d998ac59954b5 (diff) | |
download | qtlocation-mapboxgl-f6e79d70735361438655f279c8699a786d25458c.tar.gz |
[core] Render fill-extrusion layers (#8431)
Diffstat (limited to 'src/mbgl/style')
-rw-r--r-- | src/mbgl/style/layers/fill_extrusion_layer_impl.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/light_impl.hpp | 74 | ||||
-rw-r--r-- | src/mbgl/style/paint_property.hpp | 75 | ||||
-rw-r--r-- | src/mbgl/style/parser.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/style/parser.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/style/source_impl.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/style/source_impl.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/style/style.cpp | 22 | ||||
-rw-r--r-- | src/mbgl/style/style.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/style/transitioning_property.hpp | 77 | ||||
-rw-r--r-- | src/mbgl/style/types.cpp | 5 |
11 files changed, 209 insertions, 80 deletions
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp index f6f9753460..2353bd99fe 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp @@ -16,8 +16,6 @@ public: std::unique_ptr<RenderLayer> createRenderLayer() const override; FillExtrusionPaintProperties::Cascading cascading; - - //style::FillExtrusionLayer::Impl* const impl; }; } // namespace style diff --git a/src/mbgl/style/light_impl.hpp b/src/mbgl/style/light_impl.hpp new file mode 100644 index 0000000000..d1825090fc --- /dev/null +++ b/src/mbgl/style/light_impl.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include <mbgl/style/light.hpp> +#include <mbgl/style/transitioning_property.hpp> +#include <mbgl/style/cascade_parameters.hpp> +#include <mbgl/style/property_evaluator.hpp> +#include <mbgl/style/property_evaluation_parameters.hpp> +#include <mbgl/util/ignore.hpp> + +namespace mbgl { +namespace style { + +template <class TypeList> +class Transitioning; + +template <class... Ps> +class Transitioning<TypeList<Ps...>> : public IndexedTuple< + TypeList<Ps...>, + TypeList<TransitioningProperty<typename Ps::ValueType>...>> +{ +private: + using Properties = TypeList<Ps...>; + using Raw = IndexedTuple<Properties, Properties>; + using Super = IndexedTuple< + TypeList<Ps...>, + TypeList<TransitioningProperty<typename Ps::ValueType>...>>; + +public: + Transitioning() = default; + Transitioning(const Raw& raw, Transitioning&& prior, const CascadeParameters& params) + : Super { + TransitioningProperty<typename Ps::ValueType>( + raw.template get<Ps>().value, + std::move(prior.template get<Ps>()), + raw.template get<Ps>().transition.reverseMerge(params.transition), + params.now)... + } {} + + bool hasTransition() const { + bool result = false; + util::ignore({ result |= this->template get<Ps>().hasTransition()... }); + return result; + } +}; + +template <class TypeList> +class Evaluated; + +template <class... Ps> +class Evaluated<TypeList<Ps...>> : public IndexedTuple< + TypeList<Ps...>, + TypeList<typename Ps::Type...>> +{ +private: + using Properties = TypeList<Ps...>; + using TransitioningPs = Transitioning<Properties>; + using Super = IndexedTuple< + TypeList<Ps...>, + TypeList<typename Ps::Type...>>; + +public: + Evaluated() = default; + Evaluated(TransitioningPs& transitioning, const PropertyEvaluationParameters& params) + : Super { + transitioning.template get<Ps>() + .evaluate(PropertyEvaluator<typename Ps::Type>(params, Ps::defaultValue()), params.now)... + } {} +}; + +using TransitioningLight = Transitioning<LightProperties>; +using EvaluatedLight = Evaluated<LightProperties>; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index 7f7018748c..dd8d6c0b50 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -1,5 +1,6 @@ #pragma once +#include <mbgl/style/transitioning_property.hpp> #include <mbgl/style/class_dictionary.hpp> #include <mbgl/style/property_value.hpp> #include <mbgl/style/data_driven_property_value.hpp> @@ -24,68 +25,6 @@ class GeometryTileFeature; namespace style { template <class Value> -class UnevaluatedPaintProperty { -public: - UnevaluatedPaintProperty() = default; - - UnevaluatedPaintProperty(Value value_, - UnevaluatedPaintProperty<Value> prior_, - TransitionOptions transition, - TimePoint now) - : begin(now + transition.delay.value_or(Duration::zero())), - end(begin + transition.duration.value_or(Duration::zero())), - value(std::move(value_)) { - if (transition.isDefined()) { - prior = { std::move(prior_) }; - } - } - - template <class Evaluator> - auto evaluate(const Evaluator& evaluator, TimePoint now) { - auto finalValue = value.evaluate(evaluator); - if (!prior) { - // No prior value. - return finalValue; - } else if (now >= end) { - // Transition from prior value is now complete. - prior = {}; - return finalValue; - } else if (value.isDataDriven()) { - // Transitions to data-driven properties are not supported. - // We snap immediately to the data-driven value so that, when we perform layout, - // we see the data-driven function and can use it to populate vertex buffers. - prior = {}; - return finalValue; - } else if (now < begin) { - // Transition hasn't started yet. - return prior->get().evaluate(evaluator, now); - } else { - // Interpolate between recursively-calculated prior value and final. - float t = std::chrono::duration<float>(now - begin) / (end - begin); - return util::interpolate(prior->get().evaluate(evaluator, now), finalValue, util::DEFAULT_TRANSITION_EASE.solve(t, 0.001)); - } - } - - bool hasTransition() const { - return bool(prior); - } - - bool isUndefined() const { - return value.isUndefined(); - } - - const Value& getValue() const { - return value; - } - -private: - optional<mapbox::util::recursive_wrapper<UnevaluatedPaintProperty<Value>>> prior; - TimePoint begin; - TimePoint end; - Value value; -}; - -template <class Value> class CascadingPaintProperty { public: bool isUndefined() const { @@ -112,8 +51,8 @@ public: transitions[klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default] = transition; } - template <class UnevaluatedPaintProperty> - UnevaluatedPaintProperty cascade(const CascadeParameters& params, UnevaluatedPaintProperty prior) const { + template <class TransitioningProperty> + TransitioningProperty cascade(const CascadeParameters& params, TransitioningProperty prior) const { TransitionOptions transition; Value value; @@ -131,7 +70,7 @@ public: } } - return UnevaluatedPaintProperty(std::move(value), + return TransitioningProperty(std::move(value), std::move(prior), transition.reverseMerge(params.transition), params.now); @@ -147,7 +86,7 @@ class PaintProperty { public: using ValueType = PropertyValue<T>; using CascadingType = CascadingPaintProperty<ValueType>; - using UnevaluatedType = UnevaluatedPaintProperty<ValueType>; + using UnevaluatedType = TransitioningProperty<ValueType>; using EvaluatorType = PropertyEvaluator<T>; using EvaluatedType = T; static constexpr bool IsDataDriven = false; @@ -158,7 +97,7 @@ class DataDrivenPaintProperty { public: using ValueType = DataDrivenPropertyValue<T>; using CascadingType = CascadingPaintProperty<ValueType>; - using UnevaluatedType = UnevaluatedPaintProperty<ValueType>; + using UnevaluatedType = TransitioningProperty<ValueType>; using EvaluatorType = DataDrivenPropertyEvaluator<T>; using EvaluatedType = PossiblyEvaluatedPropertyValue<T>; static constexpr bool IsDataDriven = true; @@ -172,7 +111,7 @@ class CrossFadedPaintProperty { public: using ValueType = PropertyValue<T>; using CascadingType = CascadingPaintProperty<ValueType>; - using UnevaluatedType = UnevaluatedPaintProperty<ValueType>; + using UnevaluatedType = TransitioningProperty<ValueType>; using EvaluatorType = CrossFadedPropertyEvaluator<T>; using EvaluatedType = Faded<T>; static constexpr bool IsDataDriven = false; diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp index 19ea8cefee..c407e438fb 100644 --- a/src/mbgl/style/parser.cpp +++ b/src/mbgl/style/parser.cpp @@ -4,6 +4,7 @@ #include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/source.hpp> #include <mbgl/style/conversion/layer.hpp> +#include <mbgl/style/conversion/light.hpp> #include <mbgl/util/logging.hpp> @@ -82,6 +83,10 @@ StyleParseResult Parser::parse(const std::string& json) { } } + if (document.HasMember("light")) { + parseLight(document["light"]); + } + if (document.HasMember("sources")) { parseSources(document["sources"]); } @@ -107,6 +112,17 @@ StyleParseResult Parser::parse(const std::string& json) { return nullptr; } +void Parser::parseLight(const JSValue& value) { + conversion::Error error; + optional<Light> converted = conversion::convert<Light>(value, error); + if (!converted) { + Log::Warning(Event::ParseStyle, error.message); + return; + } + + light = *converted; +} + void Parser::parseSources(const JSValue& value) { if (!value.IsObject()) { Log::Warning(Event::ParseStyle, "sources must be an object"); diff --git a/src/mbgl/style/parser.hpp b/src/mbgl/style/parser.hpp index a05a0b316a..32b8a7a8bc 100644 --- a/src/mbgl/style/parser.hpp +++ b/src/mbgl/style/parser.hpp @@ -2,6 +2,7 @@ #include <mbgl/style/layer.hpp> #include <mbgl/style/source.hpp> +#include <mbgl/style/light.hpp> #include <mbgl/util/rapidjson.hpp> #include <mbgl/util/font_stack.hpp> @@ -31,6 +32,8 @@ public: std::vector<std::unique_ptr<Source>> sources; std::vector<std::unique_ptr<Layer>> layers; + Light light; + std::string name; LatLng latLng; double zoom = 0; @@ -41,6 +44,7 @@ public: std::vector<FontStack> fontStacks() const; private: + void parseLight(const JSValue&); void parseSources(const JSValue&); void parseLayers(const JSValue&); void parseLayer(const std::string& id, const JSValue&, std::unique_ptr<Layer>&); diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp index 9fabc54f7d..7a65dd1ded 100644 --- a/src/mbgl/style/source_impl.cpp +++ b/src/mbgl/style/source_impl.cpp @@ -57,8 +57,9 @@ void Source::Impl::invalidateTiles() { } void Source::Impl::startRender(algorithm::ClipIDGenerator& generator, - const mat4& projMatrix, - const TransformState& transform) { + const mat4& projMatrix, + const mat4& clipMatrix, + const TransformState& transform) { if (type == SourceType::Vector || type == SourceType::GeoJSON || type == SourceType::Annotations) { @@ -67,8 +68,7 @@ void Source::Impl::startRender(algorithm::ClipIDGenerator& generator, for (auto& pair : renderTiles) { auto& tile = pair.second; - transform.matrixFor(tile.matrix, tile.id); - matrix::multiply(tile.matrix, projMatrix, tile.matrix); + tile.calculateMatrices(projMatrix, clipMatrix, transform); } } diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp index b4473cbc84..387428ec59 100644 --- a/src/mbgl/style/source_impl.hpp +++ b/src/mbgl/style/source_impl.hpp @@ -60,6 +60,7 @@ public: void startRender(algorithm::ClipIDGenerator&, const mat4& projMatrix, + const mat4& clipMatrix, const TransformState&); void finishRender(Painter&); diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index e8141c3c6b..8dfe7eac06 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -54,6 +54,7 @@ Style::Style(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio) glyphAtlas(std::make_unique<GlyphAtlas>(Size{ 2048, 2048 }, fileSource)), spriteAtlas(std::make_unique<SpriteAtlas>(Size{ 1024, 1024 }, pixelRatio)), lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })), + light(std::make_unique<Light>()), observer(&nullObserver) { glyphAtlas->setObserver(this); spriteAtlas->setObserver(this); @@ -141,6 +142,7 @@ void Style::setJSON(const std::string& json) { defaultZoom = parser.zoom; defaultBearing = parser.bearing; defaultPitch = parser.pitch; + light = std::make_unique<Light>(parser.light); glyphAtlas->setURL(parser.glyphURL); spriteAtlas->load(parser.spriteURL, scheduler, fileSource); @@ -352,6 +354,8 @@ void Style::cascade(const TimePoint& timePoint, MapMode mode) { for (const auto& layer : renderLayers) { layer->cascade(parameters); } + + transitioningLight = TransitioningLight(*light, std::move(transitioningLight), parameters); } void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) { @@ -370,7 +374,7 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) { mode == MapMode::Continuous ? util::DEFAULT_FADE_DURATION : Duration::zero() }; - hasPendingTransitions = false; + hasPendingTransitions = transitioningLight.hasTransition(); for (const auto& layer : renderLayers) { hasPendingTransitions |= layer->evaluate(parameters); @@ -389,6 +393,8 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) { } } + evaluatedLight = EvaluatedLight(transitioningLight, parameters); + // Remove the existing tiles if we didn't end up re-enabling the source. for (const auto& source : sources) { if (!source->baseImpl->enabled) { @@ -509,8 +515,9 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const }); } - for (auto& tileRef : sortedTiles) { - auto& tile = tileRef.get(); + std::vector<std::reference_wrapper<RenderTile>> sortedTilesForInsertion; + for (auto tileIt = sortedTiles.begin(); tileIt != sortedTiles.end(); ++tileIt) { + auto& tile = tileIt->get(); if (!tile.tile.isRenderable()) { continue; } @@ -523,8 +530,9 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const // Look back through the buckets we decided to render to find out whether there is // already a bucket from this layer that is a parent of this tile. Tiles are ordered // by zoom level when we obtain them from getTiles(). - for (auto it = result.order.rbegin(); it != result.order.rend() && (&it->layer == layer.get()); ++it) { - if (tile.tile.id.isChildOf(it->tile->tile.id)) { + for (auto it = sortedTilesForInsertion.rbegin(); + it != sortedTilesForInsertion.rend(); ++it) { + if (tile.tile.id.isChildOf(it->get().tile.id)) { skip = true; break; } @@ -536,10 +544,12 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const auto bucket = tile.tile.getBucket(*layer); if (bucket) { - result.order.emplace_back(*layer, &tile, bucket); + sortedTilesForInsertion.emplace_back(tile); tile.used = true; } } + + result.order.emplace_back(*layer, std::move(sortedTilesForInsertion)); } return result; diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 127430a89f..26959c9fbf 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -6,6 +6,7 @@ #include <mbgl/style/layer_observer.hpp> #include <mbgl/style/update_batch.hpp> #include <mbgl/renderer/render_layer.hpp> +#include <mbgl/style/light_impl.hpp> #include <mbgl/text/glyph_atlas_observer.hpp> #include <mbgl/sprite/sprite_atlas_observer.hpp> #include <mbgl/map/mode.hpp> @@ -120,6 +121,10 @@ public: std::unique_ptr<SpriteAtlas> spriteAtlas; std::unique_ptr<LineAtlas> lineAtlas; + std::unique_ptr<Light> light; + TransitioningLight transitioningLight; + EvaluatedLight evaluatedLight; + private: std::vector<std::unique_ptr<Source>> sources; std::vector<std::unique_ptr<Layer>> layers; diff --git a/src/mbgl/style/transitioning_property.hpp b/src/mbgl/style/transitioning_property.hpp new file mode 100644 index 0000000000..5456322b33 --- /dev/null +++ b/src/mbgl/style/transitioning_property.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include <mbgl/style/property_value.hpp> +#include <mbgl/style/data_driven_property_value.hpp> +#include <mbgl/style/transition_options.hpp> +#include <mbgl/util/interpolate.hpp> + +#include <utility> + +namespace mbgl { +namespace style { + +template <class Value> +class TransitioningProperty { +public: + TransitioningProperty() = default; + + TransitioningProperty(Value value_, + TransitioningProperty<Value> prior_, + TransitionOptions transition, + TimePoint now) + : begin(now + transition.delay.value_or(Duration::zero())), + end(begin + transition.duration.value_or(Duration::zero())), + value(std::move(value_)) { + if (transition.isDefined()) { + prior = { std::move(prior_) }; + } + } + + template <class Evaluator> + auto evaluate(const Evaluator& evaluator, TimePoint now) { + auto finalValue = value.evaluate(evaluator); + if (!prior) { + // No prior value. + return finalValue; + } else if (now >= end) { + // Transition from prior value is now complete. + prior = {}; + return finalValue; + } else if (value.isDataDriven()) { + // Transitions to data-driven properties are not supported. + // We snap immediately to the data-driven value so that, when we perform layout, + // we see the data-driven function and can use it to populate vertex buffers. + prior = {}; + return finalValue; + } else if (now < begin) { + // Transition hasn't started yet. + return prior->get().evaluate(evaluator, now); + } else { + // Interpolate between recursively-calculated prior value and final. + float t = std::chrono::duration<float>(now - begin) / (end - begin); + return util::interpolate(prior->get().evaluate(evaluator, now), finalValue, + util::DEFAULT_TRANSITION_EASE.solve(t, 0.001)); + } + } + + bool hasTransition() const { + return bool(prior); + } + + bool isUndefined() const { + return value.isUndefined(); + } + + const Value& getValue() const { + return value; + } + +private: + optional<mapbox::util::recursive_wrapper<TransitioningProperty<Value>>> prior; + TimePoint begin; + TimePoint end; + Value value; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp index bf2ba8a793..b37e73ffb1 100644 --- a/src/mbgl/style/types.cpp +++ b/src/mbgl/style/types.cpp @@ -89,4 +89,9 @@ MBGL_DEFINE_ENUM(IconTextFitType, { { IconTextFitType::Height, "height" }, }); +MBGL_DEFINE_ENUM(LightAnchorType, { + { LightAnchorType::Map, "map" }, + { LightAnchorType::Viewport, "viewport" } +}); + } // namespace mbgl |