diff options
author | zmiao <miao.zhao@mapbox.com> | 2019-08-30 08:24:03 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-30 08:24:03 +0300 |
commit | 6ef2710e5cfb5ee4258583a20d55320e90faa8a5 (patch) | |
tree | 1c840291ea93ec38c2745348678879f10217bf7c /src | |
parent | 29b11a503766efb469036b38f010400cea57967e (diff) | |
download | qtlocation-mapboxgl-6ef2710e5cfb5ee4258583a20d55320e90faa8a5.tar.gz |
[core] fix collisionBox alignment when Icon/text translation is enabled (#15467)
* add initial fix
* fix bug for collision circle
* refind code structure
* fix indentation
* update test
* refind code structure
* Add changelog
* Add comment for boolean
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 44 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.cpp | 58 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.hpp | 34 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.cpp | 130 | ||||
-rw-r--r-- | src/mbgl/text/placement.cpp | 71 |
5 files changed, 195 insertions, 142 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index fe169785ce..0ee4143894 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -812,12 +812,15 @@ void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) { return; } - for (const SymbolInstance &symbolInstance : symbolInstances) { - auto populateCollisionBox = [&](const auto& feature) { - SymbolBucket::CollisionBuffer& collisionBuffer = feature.alongLine ? - static_cast<SymbolBucket::CollisionBuffer&>(bucket.getOrCreateCollisionCircleBuffer()) : - static_cast<SymbolBucket::CollisionBuffer&>(bucket.getOrCreateCollisionBox()); - for (const CollisionBox &box : feature.boxes) { + for (const SymbolInstance& symbolInstance : symbolInstances) { + auto populateCollisionBox = [&](const auto& feature, bool isText) { + SymbolBucket::CollisionBuffer& collisionBuffer = + feature.alongLine ? (isText ? static_cast<SymbolBucket::CollisionBuffer&>(bucket.getOrCreateTextCollisionCircleBuffer()) + : static_cast<SymbolBucket::CollisionBuffer&>(bucket.getOrCreateIconCollisionCircleBuffer())) + : (isText ? static_cast<SymbolBucket::CollisionBuffer&>(bucket.getOrCreateTextCollisionBox()) + : static_cast<SymbolBucket::CollisionBuffer&>(bucket.getOrCreateIconCollisionBox())); + + for (const CollisionBox& box : feature.boxes) { auto& anchor = box.anchor; Point<float> tl{box.x1, box.y1}; @@ -829,8 +832,11 @@ void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) { const std::size_t indexLength = feature.alongLine ? 6 : 8; if (collisionBuffer.segments.empty() || collisionBuffer.segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) { - collisionBuffer.segments.emplace_back(collisionBuffer.vertices.elements(), - feature.alongLine ? bucket.collisionCircle->triangles.elements() : bucket.collisionBox->lines.elements()); + collisionBuffer.segments.emplace_back( + collisionBuffer.vertices.elements(), + feature.alongLine + ? (isText ? bucket.textCollisionCircle->triangles.elements() : bucket.iconCollisionCircle->triangles.elements()) + : (isText ? bucket.textCollisionBox->lines.elements() : bucket.iconCollisionBox->lines.elements())); } auto& segment = collisionBuffer.segments.back(); @@ -850,27 +856,29 @@ void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) { collisionBuffer.dynamicVertices.emplace_back(dynamicVertex); if (feature.alongLine) { - bucket.collisionCircle->triangles.emplace_back(index, index + 1, index + 2); - bucket.collisionCircle->triangles.emplace_back(index, index + 2, index + 3); + auto& collisionCircle = (isText ? bucket.textCollisionCircle : bucket.iconCollisionCircle); + collisionCircle->triangles.emplace_back(index, index + 1, index + 2); + collisionCircle->triangles.emplace_back(index, index + 2, index + 3); } else { - bucket.collisionBox->lines.emplace_back(index + 0, index + 1); - bucket.collisionBox->lines.emplace_back(index + 1, index + 2); - bucket.collisionBox->lines.emplace_back(index + 2, index + 3); - bucket.collisionBox->lines.emplace_back(index + 3, index + 0); + auto& collisionBox = (isText ? bucket.textCollisionBox : bucket.iconCollisionBox); + collisionBox->lines.emplace_back(index + 0, index + 1); + collisionBox->lines.emplace_back(index + 1, index + 2); + collisionBox->lines.emplace_back(index + 2, index + 3); + collisionBox->lines.emplace_back(index + 3, index + 0); } segment.vertexLength += vertexLength; segment.indexLength += indexLength; } }; - populateCollisionBox(symbolInstance.textCollisionFeature); + populateCollisionBox(symbolInstance.textCollisionFeature, true /*isText*/); if (symbolInstance.verticalTextCollisionFeature) { - populateCollisionBox(*symbolInstance.verticalTextCollisionFeature); + populateCollisionBox(*symbolInstance.verticalTextCollisionFeature, true /*isText*/); } if (symbolInstance.verticalIconCollisionFeature) { - populateCollisionBox(*symbolInstance.verticalIconCollisionFeature); + populateCollisionBox(*symbolInstance.verticalIconCollisionFeature, false /*isText*/); } - populateCollisionBox(symbolInstance.iconCollisionFeature); + populateCollisionBox(symbolInstance.iconCollisionFeature, false /*isText*/); } } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index a46c25a13b..ff201e9c2c 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -113,37 +113,50 @@ void SymbolBucket::upload(gfx::UploadPass& uploadPass) { if (hasIconData()) { updateIconBuffer(icon); } - if (hasSdfIconData()) { updateIconBuffer(sdfIcon); } - if (hasCollisionBoxData()) { + const auto updateCollisionBox = [&](CollisionBoxBuffer& collisionBox) { if (!staticUploaded) { - collisionBox->indexBuffer = uploadPass.createIndexBuffer(std::move(collisionBox->lines)); - collisionBox->vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox->vertices)); + collisionBox.indexBuffer = uploadPass.createIndexBuffer(std::move(collisionBox.lines)); + collisionBox.vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox.vertices)); } if (!placementChangesUploaded) { - if (!collisionBox->dynamicVertexBuffer) { - collisionBox->dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox->dynamicVertices), gfx::BufferUsageType::StreamDraw); + if (!collisionBox.dynamicVertexBuffer) { + collisionBox.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox.dynamicVertices), gfx::BufferUsageType::StreamDraw); } else { - uploadPass.updateVertexBuffer(*collisionBox->dynamicVertexBuffer, std::move(collisionBox->dynamicVertices)); + uploadPass.updateVertexBuffer(*collisionBox.dynamicVertexBuffer, std::move(collisionBox.dynamicVertices)); } } + }; + if (hasIconCollisionBoxData()) { + updateCollisionBox(*iconCollisionBox); + } + + if (hasTextCollisionBoxData()) { + updateCollisionBox(*textCollisionBox); } - if (hasCollisionCircleData()) { + const auto updateCollisionCircle = [&](CollisionCircleBuffer& collisionCircle) { if (!staticUploaded) { - collisionCircle->indexBuffer = uploadPass.createIndexBuffer(std::move(collisionCircle->triangles)); - collisionCircle->vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle->vertices)); + collisionCircle.indexBuffer = uploadPass.createIndexBuffer(std::move(collisionCircle.triangles)); + collisionCircle.vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle.vertices)); } if (!placementChangesUploaded) { - if (!collisionCircle->dynamicVertexBuffer) { - collisionCircle->dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle->dynamicVertices), gfx::BufferUsageType::StreamDraw); + if (!collisionCircle.dynamicVertexBuffer) { + collisionCircle.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle.dynamicVertices), gfx::BufferUsageType::StreamDraw); } else { - uploadPass.updateVertexBuffer(*collisionCircle->dynamicVertexBuffer, std::move(collisionCircle->dynamicVertices)); + uploadPass.updateVertexBuffer(*collisionCircle.dynamicVertexBuffer, std::move(collisionCircle.dynamicVertices)); } } + }; + if (hasIconCollisionCircleData()) { + updateCollisionCircle(*iconCollisionCircle); + } + + if (hasTextCollisionCircleData()) { + updateCollisionCircle(*textCollisionCircle); } uploaded = true; @@ -154,7 +167,8 @@ void SymbolBucket::upload(gfx::UploadPass& uploadPass) { } bool SymbolBucket::hasData() const { - return hasTextData() || hasIconData() || hasSdfIconData() || hasCollisionBoxData(); + return hasTextData() || hasIconData() || hasSdfIconData() || hasIconCollisionBoxData() || + hasTextCollisionBoxData() || hasIconCollisionCircleData() || hasTextCollisionCircleData(); } bool SymbolBucket::hasTextData() const { @@ -169,12 +183,20 @@ bool SymbolBucket::hasSdfIconData() const { return !sdfIcon.segments.empty(); } -bool SymbolBucket::hasCollisionBoxData() const { - return collisionBox && !collisionBox->segments.empty(); +bool SymbolBucket::hasIconCollisionBoxData() const { + return iconCollisionBox && !iconCollisionBox->segments.empty(); +} + +bool SymbolBucket::hasIconCollisionCircleData() const { + return iconCollisionCircle && !iconCollisionCircle->segments.empty(); +} + +bool SymbolBucket::hasTextCollisionBoxData() const { + return textCollisionBox && !textCollisionBox->segments.empty(); } -bool SymbolBucket::hasCollisionCircleData() const { - return collisionCircle && !collisionCircle->segments.empty(); +bool SymbolBucket::hasTextCollisionCircleData() const { + return textCollisionCircle && !textCollisionCircle->segments.empty(); } void addPlacedSymbol(gfx::IndexVector<gfx::Triangles>& triangles, const PlacedSymbol& placedSymbol) { diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index d813707c2f..020190b81f 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -72,8 +72,10 @@ public: bool hasTextData() const; bool hasIconData() const; bool hasSdfIconData() const; - bool hasCollisionBoxData() const; - bool hasCollisionCircleData() const; + bool hasIconCollisionBoxData() const; + bool hasIconCollisionCircleData() const; + bool hasTextCollisionBoxData() const; + bool hasTextCollisionCircleData() const; bool hasFormatSectionOverrides() const; @@ -138,22 +140,34 @@ public: gfx::IndexVector<gfx::Lines> lines; optional<gfx::IndexBuffer> indexBuffer; }; - std::unique_ptr<CollisionBoxBuffer> collisionBox; + std::unique_ptr<CollisionBoxBuffer> iconCollisionBox; + std::unique_ptr<CollisionBoxBuffer> textCollisionBox; - CollisionBoxBuffer& getOrCreateCollisionBox() { - if (!collisionBox) collisionBox = std::make_unique<CollisionBoxBuffer>(); - return *collisionBox; + CollisionBoxBuffer& getOrCreateIconCollisionBox() { + if (!iconCollisionBox) iconCollisionBox = std::make_unique<CollisionBoxBuffer>(); + return *iconCollisionBox; + } + + CollisionBoxBuffer& getOrCreateTextCollisionBox() { + if (!textCollisionBox) textCollisionBox = std::make_unique<CollisionBoxBuffer>(); + return *textCollisionBox; } struct CollisionCircleBuffer : public CollisionBuffer { gfx::IndexVector<gfx::Triangles> triangles; optional<gfx::IndexBuffer> indexBuffer; }; - std::unique_ptr<CollisionCircleBuffer> collisionCircle; + std::unique_ptr<CollisionCircleBuffer> iconCollisionCircle; + std::unique_ptr<CollisionCircleBuffer> textCollisionCircle; + + CollisionCircleBuffer& getOrCreateIconCollisionCircleBuffer() { + if (!iconCollisionCircle) iconCollisionCircle = std::make_unique<CollisionCircleBuffer>(); + return *iconCollisionCircle; + } - CollisionCircleBuffer& getOrCreateCollisionCircleBuffer() { - if (!collisionCircle) collisionCircle = std::make_unique<CollisionCircleBuffer>(); - return *collisionCircle; + CollisionCircleBuffer& getOrCreateTextCollisionCircleBuffer() { + if (!textCollisionCircle) textCollisionCircle = std::make_unique<CollisionCircleBuffer>(); + return *textCollisionCircle; } const float tilePixelRatio; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index d0c038222a..06eacc041b 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -392,46 +392,11 @@ void RenderSymbolLayer::render(PaintParameters& parameters) { } } - if (bucket.hasCollisionBoxData()) { - static const style::Properties<>::PossiblyEvaluated properties {}; - static const CollisionBoxProgram::Binders paintAttributeData(properties, 0); + const auto drawCollisonData = [&](const bool isText, const bool hasCollisionBox, const bool hasCollisionCircle) { + if (!hasCollisionBox && !hasCollisionCircle) return; - auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom()); - const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ); - std::array<float,2> extrudeScale = - {{ - parameters.pixelsToGLUnits[0] / (pixelRatio * scale), - parameters.pixelsToGLUnits[1] / (pixelRatio * scale) - }}; - parameters.programs.getSymbolLayerPrograms().collisionBox.draw( - parameters.context, - *parameters.renderPass, - gfx::Lines { 1.0f }, - gfx::DepthMode::disabled(), - gfx::StencilMode::disabled(), - parameters.colorModeForRenderPass(), - gfx::CullFaceMode::disabled(), - CollisionBoxProgram::LayoutUniformValues { - uniforms::matrix::Value( tile.matrix ), - uniforms::extrude_scale::Value( extrudeScale ), - uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ) - }, - *bucket.collisionBox->vertexBuffer, - *bucket.collisionBox->dynamicVertexBuffer, - *bucket.collisionBox->indexBuffer, - bucket.collisionBox->segments, - paintAttributeData, - properties, - CollisionBoxProgram::TextureBindings{}, - parameters.state.getZoom(), - getID() - ); - } - - if (bucket.hasCollisionCircleData()) { - static const style::Properties<>::PossiblyEvaluated properties {}; + static const style::Properties<>::PossiblyEvaluated properties{}; static const CollisionBoxProgram::Binders paintAttributeData(properties, 0); - auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom()); const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ); std::array<float,2> extrudeScale = @@ -439,32 +404,69 @@ void RenderSymbolLayer::render(PaintParameters& parameters) { parameters.pixelsToGLUnits[0] / (pixelRatio * scale), parameters.pixelsToGLUnits[1] / (pixelRatio * scale) }}; - - parameters.programs.getSymbolLayerPrograms().collisionCircle.draw( - parameters.context, - *parameters.renderPass, - gfx::Triangles(), - gfx::DepthMode::disabled(), - gfx::StencilMode::disabled(), - parameters.colorModeForRenderPass(), - gfx::CullFaceMode::disabled(), - CollisionCircleProgram::LayoutUniformValues { - uniforms::matrix::Value( tile.matrix ), - uniforms::extrude_scale::Value( extrudeScale ), - uniforms::overscale_factor::Value( float(tile.getOverscaledTileID().overscaleFactor()) ), - uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ) - }, - *bucket.collisionCircle->vertexBuffer, - *bucket.collisionCircle->dynamicVertexBuffer, - *bucket.collisionCircle->indexBuffer, - bucket.collisionCircle->segments, - paintAttributeData, - properties, - CollisionCircleProgram::TextureBindings{}, - parameters.state.getZoom(), - getID() - ); - } + const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData->layerProperties); + const auto& layout = *bucket.layout; + const auto values = isText ? textPropertyValues(evaluated, layout): iconPropertyValues(evaluated, layout); + const bool needTranslate = values.translate[0] != 0 || values.translate[1] != 0; + + if (hasCollisionBox) { + const auto& collisionBox = isText ? bucket.textCollisionBox : bucket.iconCollisionBox; + parameters.programs.getSymbolLayerPrograms().collisionBox.draw( + parameters.context, + *parameters.renderPass, + gfx::Lines{ 1.0f }, + gfx::DepthMode::disabled(), + gfx::StencilMode::disabled(), + parameters.colorModeForRenderPass(), + gfx::CullFaceMode::disabled(), + CollisionBoxProgram::LayoutUniformValues { + uniforms::matrix::Value((needTranslate + ? tile.translatedMatrix(values.translate, values.translateAnchor, parameters.state) + : tile.matrix)), + uniforms::extrude_scale::Value(extrudeScale), + uniforms::camera_to_center_distance::Value(parameters.state.getCameraToCenterDistance()) + }, + *collisionBox->vertexBuffer, + *collisionBox->dynamicVertexBuffer, + *collisionBox->indexBuffer, + collisionBox->segments, + paintAttributeData, + properties, + CollisionBoxProgram::TextureBindings{}, + parameters.state.getZoom(), + getID()); + } + if (hasCollisionCircle) { + const auto& collisionCircle = isText ? bucket.textCollisionCircle : bucket.iconCollisionCircle; + parameters.programs.getSymbolLayerPrograms().collisionCircle.draw( + parameters.context, + *parameters.renderPass, + gfx::Triangles(), + gfx::DepthMode::disabled(), + gfx::StencilMode::disabled(), + parameters.colorModeForRenderPass(), + gfx::CullFaceMode::disabled(), + CollisionCircleProgram::LayoutUniformValues { + uniforms::matrix::Value((needTranslate + ? tile.translatedMatrix(values.translate, values.translateAnchor, parameters.state) + : tile.matrix)), + uniforms::extrude_scale::Value(extrudeScale), + uniforms::overscale_factor::Value(float(tile.getOverscaledTileID().overscaleFactor())), + uniforms::camera_to_center_distance::Value(parameters.state.getCameraToCenterDistance()) + }, + *collisionCircle->vertexBuffer, + *collisionCircle->dynamicVertexBuffer, + *collisionCircle->indexBuffer, + collisionCircle->segments, + paintAttributeData, + properties, + CollisionCircleProgram::TextureBindings{}, + parameters.state.getZoom(), + getID()); + } + }; + drawCollisonData(false /*isText*/, bucket.hasIconCollisionBoxData(), bucket.hasIconCollisionCircleData()); + drawCollisonData(true /*isText*/, bucket.hasTextCollisionBoxData(), bucket.hasTextCollisionCircleData()); } if (sortFeaturesByKey) { diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 9bc87911de..4cf69a11b6 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -159,7 +159,6 @@ void Placement::placeBucket( const bool rotateWithMap = layout.get<style::TextRotationAlignment>() == style::AlignmentType::Map; const bool pitchWithMap = layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map; const bool hasIconTextFit = layout.get<style::IconTextFit>() != style::IconTextFitType::None; - const bool hasCollisionCircleData = bucket.hasCollisionCircleData(); const bool zOrderByViewportY = layout.get<style::SymbolZOrder>() == style::SymbolZOrderType::ViewportY; std::vector<ProjectedCollisionBox> textBoxes; @@ -418,13 +417,14 @@ void Placement::placeBucket( } } - if (hasCollisionCircleData) { - if (symbolInstance.iconCollisionFeature.alongLine && !iconBoxes.empty()) { - collisionCircles[&symbolInstance.iconCollisionFeature] = iconBoxes; - } - if (symbolInstance.textCollisionFeature.alongLine && !textBoxes.empty()) { - collisionCircles[&symbolInstance.textCollisionFeature] = textBoxes; - } + const bool hasIconCollisionCircleData = bucket.hasIconCollisionCircleData(); + const bool hasTextCollisionCircleData = bucket.hasTextCollisionCircleData(); + + if (hasIconCollisionCircleData && symbolInstance.iconCollisionFeature.alongLine && !iconBoxes.empty()) { + collisionCircles[&symbolInstance.iconCollisionFeature] = iconBoxes; + } + if (hasTextCollisionCircleData && symbolInstance.textCollisionFeature.alongLine && !textBoxes.empty()) { + collisionCircles[&symbolInstance.textCollisionFeature] = textBoxes; } assert(symbolInstance.crossTileID != 0); @@ -696,8 +696,10 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState if (bucket.hasTextData()) bucket.text.opacityVertices.clear(); if (bucket.hasIconData()) bucket.icon.opacityVertices.clear(); if (bucket.hasSdfIconData()) bucket.sdfIcon.opacityVertices.clear(); - if (bucket.hasCollisionBoxData()) bucket.collisionBox->dynamicVertices.clear(); - if (bucket.hasCollisionCircleData()) bucket.collisionCircle->dynamicVertices.clear(); + if (bucket.hasIconCollisionBoxData()) bucket.iconCollisionBox->dynamicVertices.clear(); + if (bucket.hasIconCollisionCircleData()) bucket.iconCollisionCircle->dynamicVertices.clear(); + if (bucket.hasTextCollisionBoxData()) bucket.textCollisionBox->dynamicVertices.clear(); + if (bucket.hasTextCollisionCircleData()) bucket.textCollisionCircle->dynamicVertices.clear(); JointOpacityState duplicateOpacityState(false, false, true); @@ -788,15 +790,15 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState } } - auto updateCollisionBox = [&](const auto& feature, const bool placed, const Point<float>& shift) { + auto updateIconCollisionBox = [&](const auto& feature, const bool placed, const Point<float>& shift) { if (feature.alongLine) { return; } const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false, shift); - bucket.collisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex); + bucket.iconCollisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex); }; - auto updateCollisionTextBox = [this, &bucket, &symbolInstance, &state, variablePlacement, rotateWithMap, pitchWithMap](const auto& feature, const bool placed) { + auto updateTextCollisionBox = [this, &bucket, &symbolInstance, &state, variablePlacement, rotateWithMap, pitchWithMap](const auto& feature, const bool placed) { Point<float> shift{0.0f, 0.0f}; if (feature.alongLine) { return shift; @@ -826,11 +828,11 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState } } const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !used, shift); - bucket.collisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex); + bucket.textCollisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex); return shift; }; - auto updateCollisionCircles = [&](const auto& feature, const bool placed) { + auto updateCollisionCircles = [&](const auto& feature, const bool placed, bool isText) { if (!feature.alongLine) { return; } @@ -838,31 +840,36 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState if (circles != collisionCircles.end()) { for (const auto& circle : circles->second) { const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !circle.isCircle(), {}); - bucket.collisionCircle->dynamicVertices.extend(4, dynamicVertex); + isText ? bucket.textCollisionCircle->dynamicVertices.extend(4, dynamicVertex): + bucket.iconCollisionCircle->dynamicVertices.extend(4, dynamicVertex); } } else { // This feature was not placed, because it was not loaded or from a fading tile. Apply default values. static const auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false /*not used*/, {}); - bucket.collisionCircle->dynamicVertices.extend(4 * feature.boxes.size(), dynamicVertex); + isText ? bucket.textCollisionCircle->dynamicVertices.extend(4 * feature.boxes.size(), dynamicVertex): + bucket.iconCollisionCircle->dynamicVertices.extend(4 * feature.boxes.size(), dynamicVertex); } }; - - if (bucket.hasCollisionBoxData()) { - const auto& textShift = updateCollisionTextBox(symbolInstance.textCollisionFeature, opacityState.text.placed); - if (bucket.allowVerticalPlacement) { - Point<float> verticalTextShift{0.0f, 0.0f}; - if (symbolInstance.verticalTextCollisionFeature) { - verticalTextShift = updateCollisionTextBox(*symbolInstance.verticalTextCollisionFeature, opacityState.text.placed); - } - if (symbolInstance.verticalIconCollisionFeature) { - updateCollisionBox(*symbolInstance.verticalIconCollisionFeature, opacityState.text.placed, hasIconTextFit ? verticalTextShift : Point<float>{0.0f, 0.0f}); - } + Point<float> textShift{0.0f, 0.0f}; + Point<float> verticalTextShift{0.0f, 0.0f}; + if (bucket.hasTextCollisionBoxData()) { + textShift = updateTextCollisionBox(symbolInstance.textCollisionFeature, opacityState.text.placed); + if (bucket.allowVerticalPlacement && symbolInstance.verticalTextCollisionFeature) { + verticalTextShift = updateTextCollisionBox(*symbolInstance.verticalTextCollisionFeature, opacityState.text.placed); + } + } + if (bucket.hasIconCollisionBoxData()) { + updateIconCollisionBox(symbolInstance.iconCollisionFeature, opacityState.icon.placed, hasIconTextFit ? textShift : Point<float>{0.0f, 0.0f}); + if (bucket.allowVerticalPlacement && symbolInstance.verticalIconCollisionFeature) { + updateIconCollisionBox(*symbolInstance.verticalIconCollisionFeature, opacityState.text.placed, hasIconTextFit ? verticalTextShift : Point<float>{0.0f, 0.0f}); } - updateCollisionBox(symbolInstance.iconCollisionFeature, opacityState.icon.placed, hasIconTextFit ? textShift : Point<float>{0.0f, 0.0f}); } - if (bucket.hasCollisionCircleData()) { - updateCollisionCircles(symbolInstance.textCollisionFeature, opacityState.text.placed); - updateCollisionCircles(symbolInstance.iconCollisionFeature, opacityState.icon.placed); + + if (bucket.hasIconCollisionCircleData()) { + updateCollisionCircles(symbolInstance.iconCollisionFeature, opacityState.icon.placed, false); + } + if (bucket.hasTextCollisionCircleData()) { + updateCollisionCircles(symbolInstance.textCollisionFeature, opacityState.text.placed, true); } } |