Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Placement order matches viewport-y sort
Browse files Browse the repository at this point in the history
Symbols are placed accordingly to their viewport Y order,
if the style `symbol-z-order` is set to `viewport-y`.

This improves rendering of symbol layers, where icons are allowed
to overlap but not text.
  • Loading branch information
pozdnyakov committed Apr 23, 2019
1 parent 8580971 commit 3f60469
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 166 deletions.
49 changes: 22 additions & 27 deletions src/mbgl/renderer/buckets/symbol_bucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,38 +182,16 @@ void SymbolBucket::sortFeatures(const float angle) {
sortUploaded = false;
uploaded = false;

// If the symbols are allowed to overlap sort them by their vertical screen position.
// The index array buffer is rewritten to reference the (unchanged) vertices in the
// sorted order.

// To avoid sorting the actual symbolInstance array we sort an array of indexes.
std::vector<size_t> symbolInstanceIndexes;
symbolInstanceIndexes.reserve(symbolInstances.size());
for (size_t i = 0; i < symbolInstances.size(); i++) {
symbolInstanceIndexes.push_back(i);
}

const float sin = std::sin(angle);
const float cos = std::cos(angle);

std::sort(symbolInstanceIndexes.begin(), symbolInstanceIndexes.end(), [sin, cos, this](size_t &aIndex, size_t &bIndex) {
const SymbolInstance& a = symbolInstances[aIndex];
const SymbolInstance& b = symbolInstances[bIndex];
const auto aRotated = static_cast<int32_t>(::lround(sin * a.anchor.point.x + cos * a.anchor.point.y));
const auto bRotated = static_cast<int32_t>(::lround(sin * b.anchor.point.x + cos * b.anchor.point.y));
return aRotated != bRotated ?
aRotated < bRotated :
a.dataFeatureIndex > b.dataFeatureIndex;
});

text.triangles.clear();
icon.triangles.clear();

featureSortOrder = std::make_unique<std::vector<size_t>>();
featureSortOrder->reserve(symbolInstanceIndexes.size());
featureSortOrder->reserve(symbolInstances.size());

for (auto i : symbolInstanceIndexes) {
const SymbolInstance& symbolInstance = symbolInstances[i];
// If the symbols are allowed to overlap sort them by their vertical screen position.
// The index array buffer is rewritten to reference the (unchanged) vertices in the
// sorted order.
for (const SymbolInstance& symbolInstance : getSortedSymbols(angle)) {
featureSortOrder->push_back(symbolInstance.dataFeatureIndex);

if (symbolInstance.placedRightTextIndex) {
Expand All @@ -238,6 +216,23 @@ void SymbolBucket::sortFeatures(const float angle) {
}
}

std::vector<std::reference_wrapper<SymbolInstance>> SymbolBucket::getSortedSymbols(const float angle) {
std::vector<std::reference_wrapper<SymbolInstance>> result(symbolInstances.begin(), symbolInstances.end());
const float sin = std::sin(angle);
const float cos = std::cos(angle);

std::sort(result.begin(), result.end(), [sin, cos](const SymbolInstance& a, const SymbolInstance& b) {
const auto aRotated = ::lround(sin * a.anchor.point.x + cos * a.anchor.point.y);
const auto bRotated = ::lround(sin * b.anchor.point.x + cos * b.anchor.point.y);
if (aRotated != bRotated) {
return aRotated < bRotated;
}
return a.dataFeatureIndex > b.dataFeatureIndex; // aRotated == bRotated
});

return result;
}

bool SymbolBucket::hasFormatSectionOverrides() const {
if (!hasFormatSectionOverrides_) {
hasFormatSectionOverrides_= SymbolLayerPaintPropertyOverrides::hasOverrides(layout.get<TextField>());
Expand Down
2 changes: 2 additions & 0 deletions src/mbgl/renderer/buckets/symbol_bucket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class SymbolBucket final : public Bucket {

void updateOpacity();
void sortFeatures(const float angle);
// The result contains references to the `symbolInstances` items, sorted by viewport Y.
std::vector<std::reference_wrapper<SymbolInstance>> getSortedSymbols(const float angle);

const style::SymbolLayoutProperties::PossiblyEvaluated layout;
const bool sdfIcons;
Expand Down
Loading

0 comments on commit 3f60469

Please sign in to comment.