From 8fd42f371fd5e5581d3ce8307873664deb40a371 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Tue, 31 Mar 2015 18:53:49 -0700 Subject: [PATCH] start porting CollisionTile and CollisionFeature --- src/mbgl/renderer/symbol_bucket.cpp | 11 +++-- src/mbgl/renderer/symbol_bucket.hpp | 5 ++- src/mbgl/text/collision_feature.cpp | 33 +++++++++++++++ src/mbgl/text/collision_feature.hpp | 62 +++++++++++++++++++++++++++++ src/mbgl/text/collision_tile.cpp | 31 +++++++++++++++ src/mbgl/text/collision_tile.hpp | 57 ++++++++++++++++++++++++++ 6 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 src/mbgl/text/collision_feature.cpp create mode 100644 src/mbgl/text/collision_feature.hpp create mode 100644 src/mbgl/text/collision_tile.cpp create mode 100644 src/mbgl/text/collision_tile.hpp diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index e684c3afd..bcf02b432 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -25,16 +25,19 @@ namespace mbgl { SymbolInstance::SymbolInstance(Anchor &anchor, const std::vector &line, const Shaping &shapedText, const PositionedIcon &shapedIcon, const StyleLayoutSymbol &layout, const bool inside, - const float textBoxScale, const float /*textPadding*/, const float textAlongLine, - const float /*iconBoxScale*/, const float /*iconPadding*/, const float iconAlongLine, + const float textBoxScale, const float textPadding, const float textAlongLine, + const float iconBoxScale, const float iconPadding, const float iconAlongLine, const GlyphPositions &face) : - hasText(shapedText), hasIcon(shapedIcon), + hasText(shapedText), + hasIcon(shapedIcon), glyphQuads(inside && shapedText ? getGlyphQuads(anchor, shapedText, textBoxScale, line, layout, textAlongLine, face) : PlacedGlyphs()), iconQuads(inside && shapedIcon ? getIconQuads(anchor, shapedIcon, line, layout, iconAlongLine) : - PlacedGlyphs()) {}; + PlacedGlyphs()), + textCollisionFeature(line, anchor, shapedText, textBoxScale, textPadding, textAlongLine), + iconCollisionFeature(line, anchor, shapedIcon, iconBoxScale, iconPadding, iconAlongLine) {}; SymbolBucket::SymbolBucket(std::unique_ptr styleLayout_, Collision &collision_) : styleLayout(std::move(styleLayout_)), collision(collision_) { diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index d1abe0a2c..d11417311 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -52,8 +53,8 @@ class SymbolInstance { const bool hasIcon; const PlacedGlyphs glyphQuads; const PlacedGlyphs iconQuads; - // text collision feature - // icon collision feature + const CollisionFeature textCollisionFeature; + const CollisionFeature iconCollisionFeature; }; class SymbolBucket : public Bucket { diff --git a/src/mbgl/text/collision_feature.cpp b/src/mbgl/text/collision_feature.cpp new file mode 100644 index 000000000..e68774600 --- /dev/null +++ b/src/mbgl/text/collision_feature.cpp @@ -0,0 +1,33 @@ +#include + +namespace mbgl { + +CollisionFeature::CollisionFeature(const std::vector &line, const Anchor &anchor, + const float top, const float bottom, const float left, const float right, + const float boxScale, const float padding, const bool alongLine) { + + const float y1 = top * boxScale - padding; + const float y2 = bottom * boxScale + padding; + const float x1 = left * boxScale - padding; + const float x2 = right * boxScale + padding; + + if (alongLine) { + const float height = y2 - y1; + const float length = x2 - x1; + + bboxifyLabel(line, anchor, length, height); + } else { + boxes.emplace_back(anchor, x1, y2, x2, y2, std::numeric_limits::infinity()); + } +} + +void CollisionFeature::bboxifyLabel(const std::vector &line, + const Anchor &anchor, const float length, const float height) { + + if (length && height && line.size() && anchor.x) { + fprintf(stderr, ""); + } +} + + +} diff --git a/src/mbgl/text/collision_feature.hpp b/src/mbgl/text/collision_feature.hpp new file mode 100644 index 000000000..a16f58c8e --- /dev/null +++ b/src/mbgl/text/collision_feature.hpp @@ -0,0 +1,62 @@ +#ifndef MBGL_TEXT_COLLISION_FEATURE +#define MBGL_TEXT_COLLISION_FEATURE + +#include +#include +#include +#include + +namespace mbgl { + class CollisionBox { + public: + explicit CollisionBox(const Anchor &_anchor, float _x1, float _y1, float _x2, float _y2, float _maxScale) : + anchor(_anchor), x1(_x1), y1(_y1), x2(_x2), y2(_y2), maxScale(_maxScale) {} + + // the box is centered around the anchor point + const Anchor anchor; + + // distances to the edges from the anchor + const float x1; + const float y1; + const float x2; + const float y2; + + // the box is only valid for scales < maxScale. + // The box does not block other boxes at scales >= maxScale; + const float maxScale; + + // the scale at which the label can first be shown + float placementScale = 0.0f; + }; + + class CollisionFeature { + public: + // for text + inline explicit CollisionFeature(const std::vector &line, const Anchor &anchor, + const Shaping &shapedText, + const float boxScale, const float padding, const bool alongLine) + : CollisionFeature(line, anchor, + shapedText.top, shapedText.bottom, shapedText.left, shapedText.right, + boxScale, padding, alongLine) {} + + // for icons + inline explicit CollisionFeature(const std::vector &line, const Anchor &anchor, + const PositionedIcon &shapedIcon, + const float boxScale, const float padding, const bool alongLine) + : CollisionFeature(line, anchor, + shapedIcon.top, shapedIcon.bottom, shapedIcon.left, shapedIcon.right, + boxScale, padding, alongLine) {} + + explicit CollisionFeature(const std::vector &line, const Anchor &anchor, + const float top, const float bottom, const float left, const float right, + const float boxScale, const float padding, const bool alongLine); + + + std::vector boxes; + + private: + void bboxifyLabel(const std::vector &line, const Anchor &anchor, const float length, const float height); + }; +} + +#endif diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp new file mode 100644 index 000000000..688e9b7f3 --- /dev/null +++ b/src/mbgl/text/collision_tile.cpp @@ -0,0 +1,31 @@ +#include +#include + +namespace mbgl { + +void CollisionTile::reset(const float _angle, const float pitch) { + tree.clear(); + angle = _angle; + + // Compute the transformation matrix. + float angle_sin = std::sin(_angle); + float angle_cos = std::cos(_angle); + matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}}; + + // Stretch boxes in y direction to account for the map tilt. + const float _yStretch = 1.0f / std::cos(pitch / 180 * M_PI); + + // The amount the map is squished depends on the y position. + // Sort of account for this by making all boxes a bit bigger. + yStretch = std::pow(_yStretch, 1.3); +} + +void CollisionTile::placeFeature(CollisionFeature &) { +//void CollisionTile::placeFeature(CollisionFeature &feature) { +} + +void CollisionTile::insertFeature(CollisionFeature &, const float ) { +//void CollisionTile::insertFeature(CollisionFeature &feature, const float minPlacementScale) { +} + +} diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp new file mode 100644 index 000000000..9c209d9e2 --- /dev/null +++ b/src/mbgl/text/collision_tile.hpp @@ -0,0 +1,57 @@ +#ifndef MBGL_TEXT_COLLISION_TILE +#define MBGL_TEXT_COLLISION_TILE + +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wshadow" +#ifdef __clang__ +#pragma GCC diagnostic ignored "-Wdeprecated-register" +#pragma GCC diagnostic ignored "-Wshorten-64-to-32" +#else +#pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif +#include +#include +#include +#include +#pragma GCC diagnostic pop + +namespace mbgl { + + namespace bg = boost::geometry; + namespace bgm = bg::model; + namespace bgi = bg::index; + typedef bgm::point Point; + typedef bgm::box Box; + typedef std::pair CollisionTreeBox; + typedef bgi::rtree> Tree; + +class CollisionTile { + + public: + inline explicit CollisionTile(float _zoom, float tileExtent, float tileSize) : + zoom(_zoom), tilePixelRatio(tileExtent / tileSize) {} + + void reset(const float angle, const float pitch); + void placeFeature(CollisionFeature &feature); + void insertFeature(CollisionFeature &feature, const float minPlacementScale); + + const float zoom; + const float tilePixelRatio; + float angle = 0; + + private: + + Tree tree; + std::array matrix; + float yStretch; + +}; +} + +#endif