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

[core] Placement order matches viewport-y sort #14486

Merged
merged 1 commit into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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