summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin R. Miller <incanus@codesorcery.net>2015-03-06 17:47:14 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-03-09 11:57:33 -0700
commit405137700becde67e4eca33b2d31ce34e32c4dd8 (patch)
treebed3267599ae7dc0703ad05ecd2df256304b6f3f /src
parent685aa01043e765eb9b0a176fea6524a5b0ac0f6e (diff)
downloadqtlocation-mapboxgl-405137700becde67e4eca33b2d31ce34e32c4dd8.tar.gz
parse geometry collections from the pbfs; iterate geometries in buckets
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/geometry_tile.hpp4
-rw-r--r--src/mbgl/map/tile_parser.cpp6
-rw-r--r--src/mbgl/map/vector_tile.cpp43
-rw-r--r--src/mbgl/map/vector_tile.hpp3
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp11
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp2
-rw-r--r--src/mbgl/renderer/line_bucket.cpp448
-rw-r--r--src/mbgl/renderer/line_bucket.hpp2
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp15
9 files changed, 270 insertions, 264 deletions
diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp
index 4a7e05b902..81960c981e 100644
--- a/src/mbgl/map/geometry_tile.hpp
+++ b/src/mbgl/map/geometry_tile.hpp
@@ -32,13 +32,15 @@ typedef std::vector<GeometryLine> GeometryPolygon;
using Geometry = mapbox::util::variant<std::false_type, GeometryPoint, GeometryLine, GeometryPolygon>;
+typedef std::vector<Geometry> GeometryCollection;
+
std::ostream& operator<<(std::ostream&, const GeometryFeatureType& type);
class GeometryTileLayer;
class GeometryTileFeature {
public:
- virtual Geometry nextGeometry() = 0;
+ virtual GeometryCollection nextGeometry() = 0;
public:
uint64_t id = 0;
diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp
index de89143ae3..861141b1fa 100644
--- a/src/mbgl/map/tile_parser.cpp
+++ b/src/mbgl/map/tile_parser.cpp
@@ -220,10 +220,12 @@ template <class Bucket>
if (obsolete())
return;
- Geometry geometry = feature->nextGeometry();
- while (!geometry.is<std::false_type>()) {
+ GeometryCollection geometry = feature->nextGeometry();
+ if (geometry.size()) {
bucket->addGeometry(geometry);
geometry = feature->nextGeometry();
+ } else if (debug::tileParseWarnings) {
+ fprintf(stderr, "[WARNING] geometry is empty\n");
}
feature = filtered_layer->nextMatchingFeature();
diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp
index 235a4151d7..332534f25a 100644
--- a/src/mbgl/map/vector_tile.cpp
+++ b/src/mbgl/map/vector_tile.cpp
@@ -43,47 +43,50 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const util::ptr<GeometryTi
}
}
-Geometry VectorTileFeature::nextGeometry() {
+GeometryCollection VectorTileFeature::nextGeometry() {
+
+ GeometryCollection result;
+
pbf current_geometry_pbf = geometry_pbf.message();
PBFGeometry current_geometry(current_geometry_pbf);
int32_t x, y;
- Geometry result;
- result.set<std::false_type>();
- if (multigeometry || geometry_pbf.next(4)) {
+ while (geometry_pbf.next(4)) { // geometry
if (type == GeometryFeatureType::Point) {
current_geometry.next(x, y);
GeometryPoint point(x, y);
- result.set<GeometryPoint>(point);
+ result.emplace_back(GeometryPoint(x, y));
} else if (type == GeometryFeatureType::LineString) {
GeometryLine line;
PBFGeometry::command cmd;
while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) {
if (cmd == PBFGeometry::move_to) {
- multigeometry = true;
- result.set<GeometryLine>(line);
- break;
- } else {
- line.emplace_back(x, y);
+ if (!line.empty()) {
+ result.push_back(line);
+ line.clear();
+ }
}
+ line.emplace_back(x, y);
}
- if (!multigeometry) {
- result.set<GeometryLine>(line);
+ if (line.size()) {
+ result.push_back(line);
}
} else if (type == GeometryFeatureType::Polygon) {
- GeometryPolygon polygon;
+ GeometryLine line;
PBFGeometry::command cmd;
while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) {
if (cmd == PBFGeometry::move_to) {
- multigeometry = true;
- result.set<GeometryPolygon>(polygon);
- break;
- } else {
-// polygon.emplace_back(x, y);
+ if (line.size()) {
+ result.push_back(line);
+ line.clear();
+ }
}
+ line.emplace_back(x, y);
}
- if (!multigeometry) {
- result.set<GeometryPolygon>(polygon);
+
+ if (line.size()) {
+ result.push_back(line);
+ line.clear();
}
} else {
throw std::runtime_error("unrecognized geometry type");
diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp
index f16e98c3bd..85ec09bede 100644
--- a/src/mbgl/map/vector_tile.hpp
+++ b/src/mbgl/map/vector_tile.hpp
@@ -15,11 +15,10 @@ class VectorTileFeature : public GeometryTileFeature {
public:
VectorTileFeature(pbf, const util::ptr<GeometryTileLayer>);
- Geometry nextGeometry();
+ GeometryCollection nextGeometry();
private:
pbf geometry_pbf;
- bool multigeometry = false;
};
class FilteredVectorTileLayer : public GeometryFilteredTileLayer {
diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp
index 86b9daeada..18e337f911 100644
--- a/src/mbgl/renderer/fill_bucket.cpp
+++ b/src/mbgl/renderer/fill_bucket.cpp
@@ -64,12 +64,11 @@ FillBucket::~FillBucket() {
}
}
-void FillBucket::addGeometry(const Geometry& fill) {
- const GeometryPolygon& polygon = fill.get<GeometryPolygon>();
-
- for (auto line_it = polygon.begin(); line_it != polygon.end(); line_it++) {
- for (auto point_it = line_it->begin(); point_it != line_it->end(); point_it++) {
- line.emplace_back(point_it->x, point_it->y);
+void FillBucket::addGeometry(const GeometryCollection& geometryCollection) {
+ for (auto& line_ : geometryCollection) {
+ const GeometryLine& vertices = line_.get<GeometryLine>();
+ for (auto& v : vertices) {
+ line.emplace_back(ClipperLib::IntPoint(v.x, v.y));
}
clipper.AddPath(line, ClipperLib::ptSubject, true);
line.clear();
diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp
index bec4826057..46b8f53857 100644
--- a/src/mbgl/renderer/fill_bucket.hpp
+++ b/src/mbgl/renderer/fill_bucket.hpp
@@ -49,7 +49,7 @@ public:
const mat4 &matrix) override;
bool hasData() const override;
- void addGeometry(const Geometry& fill);
+ void addGeometry(const GeometryCollection&);
void tessellate();
void drawElements(PlainShader& shader);
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 40b69a0ab5..1f2e26c166 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -41,290 +41,292 @@ struct TriangleElement {
typedef uint16_t PointElement;
-void LineBucket::addGeometry(const Geometry &line) {
- const GeometryLine& vertices = line.get<GeometryLine>();
+void LineBucket::addGeometry(const GeometryCollection& geometryCollection) {
+ for (auto& line : geometryCollection) {
+ const GeometryLine& vertices = line.get<GeometryLine>();
- auto &layout = *styleLayout;
- // TODO: use roundLimit
- // const float roundLimit = geometry.round_limit;
+ auto &layout = *styleLayout;
+ // TODO: use roundLimit
+ // const float roundLimit = geometry.round_limit;
- if (vertices.size() < 2) {
- // fprintf(stderr, "a line must have at least two vertices\n");
- return;
- }
-
- Coordinate firstVertex = vertices.front();
- Coordinate lastVertex = vertices.back();
- bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y;
-
- if (vertices.size() == 2 && closed) {
- // fprintf(stderr, "a line may not have coincident points\n");
- return;
- }
+ if (vertices.size() < 2) {
+ // fprintf(stderr, "a line must have at least two vertices\n");
+ return;
+ }
- CapType beginCap = layout.cap;
- CapType endCap = closed ? CapType::Butt : layout.cap;
+ Coordinate firstVertex = vertices.front();
+ Coordinate lastVertex = vertices.back();
+ bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y;
- JoinType currentJoin = JoinType::Miter;
+ if (vertices.size() == 2 && closed) {
+ // fprintf(stderr, "a line may not have coincident points\n");
+ return;
+ }
- Coordinate currentVertex = Coordinate::null(),
- prevVertex = Coordinate::null(),
- nextVertex = Coordinate::null();
- vec2<double> prevNormal = vec2<double>::null(),
- nextNormal = vec2<double>::null();
+ CapType beginCap = layout.cap;
+ CapType endCap = closed ? CapType::Butt : layout.cap;
- int32_t e1 = -1, e2 = -1, e3 = -1;
+ JoinType currentJoin = JoinType::Miter;
- int8_t flip = 1;
- double distance = 0;
+ Coordinate currentVertex = Coordinate::null(),
+ prevVertex = Coordinate::null(),
+ nextVertex = Coordinate::null();
+ vec2<double> prevNormal = vec2<double>::null(),
+ nextNormal = vec2<double>::null();
- if (closed) {
- currentVertex = vertices[vertices.size() - 2];
- nextNormal = util::normal<double>(currentVertex, lastVertex);
- }
+ int32_t e1 = -1, e2 = -1, e3 = -1;
- int32_t start_vertex = (int32_t)vertexBuffer.index();
+ int8_t flip = 1;
+ double distance = 0;
- std::vector<TriangleElement> triangle_store;
- std::vector<PointElement> point_store;
+ if (closed) {
+ currentVertex = vertices[vertices.size() - 2];
+ nextNormal = util::normal<double>(currentVertex, lastVertex);
+ }
- for (size_t i = 0; i < vertices.size(); ++i) {
- if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y };
- if (currentVertex) prevVertex = currentVertex;
+ int32_t start_vertex = (int32_t)vertexBuffer.index();
- currentVertex = vertices[i];
- currentJoin = layout.join;
+ std::vector<TriangleElement> triangle_store;
+ std::vector<PointElement> point_store;
- if (prevVertex) distance += util::dist<double>(currentVertex, prevVertex);
+ for (size_t i = 0; i < vertices.size(); ++i) {
+ if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y };
+ if (currentVertex) prevVertex = currentVertex;
- // Find the next vertex.
- if (i + 1 < vertices.size()) {
- nextVertex = vertices[i + 1];
- } else {
- nextVertex = Coordinate::null();
- }
+ currentVertex = vertices[i];
+ currentJoin = layout.join;
- // If the line is closed, we treat the last vertex like the first vertex.
- if (!nextVertex && closed) {
- nextVertex = vertices[1];
- }
+ if (prevVertex) distance += util::dist<double>(currentVertex, prevVertex);
- if (nextVertex) {
- // if two consecutive vertices exist, skip one
- if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue;
- }
+ // Find the next vertex.
+ if (i + 1 < vertices.size()) {
+ nextVertex = vertices[i + 1];
+ } else {
+ nextVertex = Coordinate::null();
+ }
- // Calculate the normal towards the next vertex in this line. In case
- // there is no next vertex, pretend that the line is continuing straight,
- // meaning that we are just reversing the previous normal
- if (nextVertex) {
- nextNormal = util::normal<double>(currentVertex, nextVertex);
- } else {
- nextNormal = { -prevNormal.x, -prevNormal.y };
- }
+ // If the line is closed, we treat the last vertex like the first vertex.
+ if (!nextVertex && closed) {
+ nextVertex = vertices[1];
+ }
- // If we still don't have a previous normal, this is the beginning of a
- // non-closed line, so we're doing a straight "join".
- if (!prevNormal) {
- prevNormal = { -nextNormal.x, -nextNormal.y };
- }
+ if (nextVertex) {
+ // if two consecutive vertices exist, skip one
+ if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue;
+ }
- // Determine the normal of the join extrusion. It is the angle bisector
- // of the segments between the previous line and the next line.
- vec2<double> joinNormal = {
- prevNormal.x + nextNormal.x,
- prevNormal.y + nextNormal.y
- };
-
- // Cross product yields 0..1 depending on whether they are parallel
- // or perpendicular.
- double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x;
- joinNormal.x /= joinAngularity;
- joinNormal.y /= joinAngularity;
- double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y));
-
-
- // Switch to miter joins if the angle is very low.
- if (currentJoin != JoinType::Miter) {
- if (std::fabs(joinAngularity) < 0.5 && roundness < layout.miter_limit) {
- currentJoin = JoinType::Miter;
+ // Calculate the normal towards the next vertex in this line. In case
+ // there is no next vertex, pretend that the line is continuing straight,
+ // meaning that we are just reversing the previous normal
+ if (nextVertex) {
+ nextNormal = util::normal<double>(currentVertex, nextVertex);
+ } else {
+ nextNormal = { -prevNormal.x, -prevNormal.y };
}
- }
- // Add offset square begin cap.
- if (!prevVertex && beginCap == CapType::Square) {
- // Add first vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal
- 0, 0, distance) - start_vertex; // texture normal
+ // If we still don't have a previous normal, this is the beginning of a
+ // non-closed line, so we're doing a straight "join".
+ if (!prevNormal) {
+ prevNormal = { -nextNormal.x, -nextNormal.y };
+ }
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
+ // Determine the normal of the join extrusion. It is the angle bisector
+ // of the segments between the previous line and the next line.
+ vec2<double> joinNormal = {
+ prevNormal.x + nextNormal.x,
+ prevNormal.y + nextNormal.y
+ };
+
+ // Cross product yields 0..1 depending on whether they are parallel
+ // or perpendicular.
+ double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x;
+ joinNormal.x /= joinAngularity;
+ joinNormal.y /= joinAngularity;
+ double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y));
+
+
+ // Switch to miter joins if the angle is very low.
+ if (currentJoin != JoinType::Miter) {
+ if (std::fabs(joinAngularity) < 0.5 && roundness < layout.miter_limit) {
+ currentJoin = JoinType::Miter;
+ }
+ }
- // Add second vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal
- 0, 1, distance) - start_vertex; // texture normal
+ // Add offset square begin cap.
+ if (!prevVertex && beginCap == CapType::Square) {
+ // Add first vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal
+ 0, 0, distance) - start_vertex; // texture normal
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
- }
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
- // Add offset square end cap.
- else if (!nextVertex && endCap == CapType::Square) {
- // Add first vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal
- 0, 0, distance) - start_vertex; // texture normal
+ // Add second vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal
+ 0, 1, distance) - start_vertex; // texture normal
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
+ }
- // Add second vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal
- 0, 1, distance) - start_vertex; // texture normal
+ // Add offset square end cap.
+ else if (!nextVertex && endCap == CapType::Square) {
+ // Add first vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal
+ 0, 0, distance) - start_vertex; // texture normal
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
- }
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
- else if (currentJoin == JoinType::Miter) {
- // MITER JOIN
- if (std::fabs(joinAngularity) < 0.01) {
- // The two normals are almost parallel.
- joinNormal.x = -nextNormal.y;
- joinNormal.y = nextNormal.x;
- } else if (roundness > layout.miter_limit) {
- // If the miter grows too large, flip the direction to make a
- // bevel join.
- joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity;
- joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity;
- }
+ // Add second vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal
+ 0, 1, distance) - start_vertex; // texture normal
- if (roundness > layout.miter_limit) {
- flip = -flip;
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
}
- // Add first vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- flip * joinNormal.x, flip * joinNormal.y, // extrude normal
- 0, 0, distance) - start_vertex; // texture normal
+ else if (currentJoin == JoinType::Miter) {
+ // MITER JOIN
+ if (std::fabs(joinAngularity) < 0.01) {
+ // The two normals are almost parallel.
+ joinNormal.x = -nextNormal.y;
+ joinNormal.y = nextNormal.x;
+ } else if (roundness > layout.miter_limit) {
+ // If the miter grows too large, flip the direction to make a
+ // bevel join.
+ joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity;
+ joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity;
+ }
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
+ if (roundness > layout.miter_limit) {
+ flip = -flip;
+ }
- // Add second vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal
- 0, 1, distance) - start_vertex; // texture normal
+ // Add first vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * joinNormal.x, flip * joinNormal.y, // extrude normal
+ 0, 0, distance) - start_vertex; // texture normal
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
- if ((!prevVertex && beginCap == CapType::Round) ||
- (!nextVertex && endCap == CapType::Round)) {
- point_store.emplace_back(e1);
- }
- }
+ // Add second vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal
+ 0, 1, distance) - start_vertex; // texture normal
- else {
- // Close up the previous line
- // Add first vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- flip * prevNormal.y, -flip * prevNormal.x, // extrude normal
- 0, 0, distance) - start_vertex; // texture normal
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
+ if ((!prevVertex && beginCap == CapType::Round) ||
+ (!nextVertex && endCap == CapType::Round)) {
+ point_store.emplace_back(e1);
+ }
+ }
- // Add second vertex.
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- -flip * prevNormal.y, flip * prevNormal.x, // extrude normal
- 0, 1, distance) - start_vertex; // texture normal
+ else {
+ // Close up the previous line
+ // Add first vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * prevNormal.y, -flip * prevNormal.x, // extrude normal
+ 0, 0, distance) - start_vertex; // texture normal
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
- prevNormal = { -nextNormal.x, -nextNormal.y };
- flip = 1;
+ // Add second vertex.
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ -flip * prevNormal.y, flip * prevNormal.x, // extrude normal
+ 0, 1, distance) - start_vertex; // texture normal
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
- // begin/end caps
- if ((!prevVertex && beginCap == CapType::Round) ||
- (!nextVertex && endCap == CapType::Round)) {
- point_store.emplace_back(e1);
- }
+ prevNormal = { -nextNormal.x, -nextNormal.y };
+ flip = 1;
- if (currentJoin == JoinType::Round) {
- if (prevVertex && nextVertex && (!closed || i > 0)) {
+ // begin/end caps
+ if ((!prevVertex && beginCap == CapType::Round) ||
+ (!nextVertex && endCap == CapType::Round)) {
point_store.emplace_back(e1);
}
- // Reset the previous vertices so that we don't accidentally create
- // any triangles.
- e1 = -1; e2 = -1; e3 = -1;
- }
- // Start the new quad.
- // Add first vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- -flip * nextNormal.y, flip * nextNormal.x, // extrude normal
- 0, 0, distance) - start_vertex; // texture normal
+ if (currentJoin == JoinType::Round) {
+ if (prevVertex && nextVertex && (!closed || i > 0)) {
+ point_store.emplace_back(e1);
+ }
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
+ // Reset the previous vertices so that we don't accidentally create
+ // any triangles.
+ e1 = -1; e2 = -1; e3 = -1;
+ }
- // Add second vertex
- e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
- flip * nextNormal.y, -flip * nextNormal.x, // extrude normal
- 0, 1, distance) - start_vertex; // texture normal
+ // Start the new quad.
+ // Add first vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ -flip * nextNormal.y, flip * nextNormal.x, // extrude normal
+ 0, 0, distance) - start_vertex; // texture normal
- if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
- e1 = e2; e2 = e3;
- }
- }
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
- size_t end_vertex = vertexBuffer.index();
- size_t vertex_count = end_vertex - start_vertex;
+ // Add second vertex
+ e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
+ flip * nextNormal.y, -flip * nextNormal.x, // extrude normal
+ 0, 1, distance) - start_vertex; // texture normal
- // Store the triangle/line groups.
- {
- if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) {
- // Move to a new group because the old one can't hold the geometry.
- triangleGroups.emplace_back(util::make_unique<triangle_group_type>());
+ if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
+ e1 = e2; e2 = e3;
+ }
}
- assert(triangleGroups.back());
- triangle_group_type& group = *triangleGroups.back();
- for (const TriangleElement& triangle : triangle_store) {
- triangleElementsBuffer.add(
- group.vertex_length + triangle.a,
- group.vertex_length + triangle.b,
- group.vertex_length + triangle.c
- );
- }
+ size_t end_vertex = vertexBuffer.index();
+ size_t vertex_count = end_vertex - start_vertex;
- group.vertex_length += vertex_count;
- group.elements_length += triangle_store.size();
- }
+ // Store the triangle/line groups.
+ {
+ if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) {
+ // Move to a new group because the old one can't hold the geometry.
+ triangleGroups.emplace_back(util::make_unique<triangle_group_type>());
+ }
- // Store the line join/cap groups.
- {
- if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) {
- // Move to a new group because the old one can't hold the geometry.
- pointGroups.emplace_back(util::make_unique<point_group_type>());
- }
+ assert(triangleGroups.back());
+ triangle_group_type& group = *triangleGroups.back();
+ for (const TriangleElement& triangle : triangle_store) {
+ triangleElementsBuffer.add(
+ group.vertex_length + triangle.a,
+ group.vertex_length + triangle.b,
+ group.vertex_length + triangle.c
+ );
+ }
- assert(pointGroups.back());
- point_group_type& group = *pointGroups.back();
- for (PointElement point : point_store) {
- pointElementsBuffer.add(group.vertex_length + point);
+ group.vertex_length += vertex_count;
+ group.elements_length += triangle_store.size();
}
- group.vertex_length += vertex_count;
- group.elements_length += point_store.size();
+ // Store the line join/cap groups.
+ {
+ if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) {
+ // Move to a new group because the old one can't hold the geometry.
+ pointGroups.emplace_back(util::make_unique<point_group_type>());
+ }
+
+ assert(pointGroups.back());
+ point_group_type& group = *pointGroups.back();
+ for (PointElement point : point_store) {
+ pointElementsBuffer.add(group.vertex_length + point);
+ }
+
+ group.vertex_length += vertex_count;
+ group.elements_length += point_store.size();
+ }
}
}
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index 9239634332..4190b79f57 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -37,7 +37,7 @@ public:
const mat4 &matrix) override;
bool hasData() const override;
- void addGeometry(const Geometry& line);
+ void addGeometry(const GeometryCollection&);
bool hasPoints() const;
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index 60315c8fe0..462ac72ab7 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -97,15 +97,14 @@ std::vector<SymbolFeature> SymbolBucket::processFeatures(const util::ptr<Geometr
auto &multiline = ft.geometry;
- Geometry geometry = feature->nextGeometry();
- const GeometryLine& line = geometry.get<GeometryLine>();
- bool first = true;
- for (auto point_it = line.begin(); point_it != line.end(); point_it++) {
- if (first) {
- multiline.emplace_back();
- first = false;
+ GeometryCollection geometryCollection = feature->nextGeometry();
+ multiline.emplace_back();
+ for (auto& geometry : geometryCollection) {
+ const GeometryLine& line = geometry.get<GeometryLine>();
+ multiline.emplace_back();
+ for (auto& point : line) {
+ multiline.back().emplace_back(point.x, point.y);
}
- multiline.back().emplace_back(point_it->x, point_it->y);
}
features.push_back(std::move(ft));