diff options
author | Juha Alanen <juha.alanen@mapbox.com> | 2019-10-30 12:10:28 +0200 |
---|---|---|
committer | Juha Alanen <juha.alanen@mapbox.com> | 2019-11-21 12:31:34 +0200 |
commit | 18bf745049e1df650cbd40dcfb5f36361678c7c7 (patch) | |
tree | 91d3e67d56f4836d75b25f23bba2dfe8e7ca6550 | |
parent | 63005548e0d8e74076e01344772d6df2884452a1 (diff) | |
download | qtlocation-mapboxgl-18bf745049e1df650cbd40dcfb5f36361678c7c7.tar.gz |
[core] Add feature state support to composite crossfade binder
-rw-r--r-- | src/mbgl/renderer/paint_property_binder.hpp | 94 |
1 files changed, 85 insertions, 9 deletions
diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index 5237061067..7f95d73a65 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -453,7 +453,9 @@ public: crossfade = crossfade_; }; - void populateVertexVector(const GeometryTileFeature&, std::size_t length, std::size_t /* index */, + void populateVertexVector(const GeometryTileFeature& feature, + std::size_t length, + std::size_t index, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value&) override { @@ -461,11 +463,16 @@ public: // Unlike other propperties with expressions that evaluate to null, the default value for `*-pattern` properties is an empty // string and will not have a valid entry in patternPositions. We still need to populate the attribute buffers to avoid crashes // when we try to draw the layer because we don't know at draw time if all features were evaluated to valid pattern dependencies. - for (std::size_t i = zoomInVertexVector.elements(); i < length; ++i) { + auto elements = zoomInVertexVector.elements(); + for (std::size_t i = elements; i < length; ++i) { patternToVertexVector.emplace_back(Vertex { std::array<uint16_t, 4>{{0, 0, 0, 0}} }); zoomInVertexVector.emplace_back(Vertex2 { std::array<uint16_t, 4>{{0, 0, 0, 0}} } ); zoomOutVertexVector.emplace_back(Vertex2 { std::array<uint16_t, 4>{{0, 0, 0, 0}} }); } + optional<std::string> idStr = featureIDtoString(feature.getID()); + if (idStr) { + featureMap[*idStr].emplace_back(FeatureVertexRange{index, elements, length}); + } } else if (!patternPositions.empty()) { const auto min = patternPositions.find(patternDependencies->min); const auto mid = patternPositions.find(patternDependencies->mid); @@ -478,20 +485,88 @@ public: const ImagePosition imageMid = mid->second; const ImagePosition imageMax = max->second; - for (std::size_t i = zoomInVertexVector.elements(); i < length; ++i) { + auto elements = zoomInVertexVector.elements(); + for (std::size_t i = elements; i < length; ++i) { patternToVertexVector.emplace_back(Vertex { imageMid.tlbr() }); zoomInVertexVector.emplace_back(Vertex2 { imageMin.tlbr() }); zoomOutVertexVector.emplace_back(Vertex2 { imageMax.tlbr() }); } + optional<std::string> idStr = featureIDtoString(feature.getID()); + if (idStr) { + featureMap[*idStr].emplace_back(FeatureVertexRange{index, elements, length}); + } } } - void updateVertexVector(std::size_t, - std::size_t, - const GeometryTileFeature&, - const FeatureState&, - const ImagePositions&, - GeometryTile&) override {} + bool updateVertexVectors(const FeatureStates& states, + const GeometryTileLayer& layer, + const ImagePositions& patternPositions, + GeometryTile& tile) override { + bool updated = false; + for (const auto& it : states) { + const auto positions = featureMap.find(it.first); + if (positions == featureMap.end()) { + continue; + } + + for (const auto& pos : positions->second) { + std::unique_ptr<GeometryTileFeature> feature = layer.getFeature(pos.featureIndex); + if (feature) { + updateVertexVector(pos.start, pos.end, *feature, it.second, patternPositions, tile); + updated = true; + } + } + } + return updated; + } + + void updateVertexVector(std::size_t start, + std::size_t end, + const GeometryTileFeature& feature, + const FeatureState& state, + const ImagePositions& patternPositions, + GeometryTile& tile) override { + if (!patternPositions.empty()) { + using style::expression::EvaluationContext; + const auto evaluatedMin = + toString(expression.evaluate(EvaluationContext(zoomRange.min - 1, &feature, &state), defaultValue)); + const auto evaluatedMid = + toString(expression.evaluate(EvaluationContext(zoomRange.min, &feature, &state), defaultValue)); + const auto evaluatedMax = + toString(expression.evaluate(EvaluationContext(zoomRange.max, &feature, &state), defaultValue)); + + auto min = patternPositions.find(evaluatedMin); + auto mid = patternPositions.find(evaluatedMid); + auto max = patternPositions.find(evaluatedMax); + + auto endPos = patternPositions.end(); + if (min == endPos || mid == endPos || max == endPos) { + ImageDependencies dependencies; + dependencies.emplace(evaluatedMin, ImageType::Pattern); + dependencies.emplace(evaluatedMid, ImageType::Pattern); + dependencies.emplace(evaluatedMax, ImageType::Pattern); + + tile.getMissingImages(dependencies); + + min = patternPositions.find(evaluatedMin); + mid = patternPositions.find(evaluatedMid); + max = patternPositions.find(evaluatedMax); + + endPos = patternPositions.end(); + if (min == endPos || mid == endPos || max == endPos) return; + } + + const ImagePosition imageMin = min->second; + const ImagePosition imageMid = mid->second; + const ImagePosition imageMax = max->second; + + for (std::size_t i = start; i < end; ++i) { + patternToVertexVector.at(i) = Vertex{imageMid.tlbr()}; + zoomInVertexVector.at(i) = Vertex2{imageMin.tlbr()}; + zoomOutVertexVector.at(i) = Vertex2{imageMax.tlbr()}; + } + } + } void upload(gfx::UploadPass& uploadPass) override { if (!patternToVertexVector.empty()) { @@ -540,6 +615,7 @@ private: optional<gfx::VertexBuffer<Vertex2>> zoomInVertexBuffer; optional<gfx::VertexBuffer<Vertex2>> zoomOutVertexBuffer; CrossfadeParameters crossfade; + FeatureVertexRangeMap featureMap; }; template <class T, class PossiblyEvaluatedType> |