From b7f04ee7c231d8165411161ff3f88138945da702 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 9 Mar 2015 17:39:37 -0700 Subject: [PATCH] Use single geometry format --- src/mbgl/geometry/pbf_geometry.hpp | 6 +- src/mbgl/map/geometry_tile.hpp | 8 +- src/mbgl/map/vector_tile.cpp | 51 +-- src/mbgl/renderer/fill_bucket.cpp | 13 +- src/mbgl/renderer/line_bucket.cpp | 510 ++++++++++++++-------------- src/mbgl/renderer/line_bucket.hpp | 1 + src/mbgl/renderer/symbol_bucket.cpp | 4 +- 7 files changed, 281 insertions(+), 312 deletions(-) diff --git a/src/mbgl/geometry/pbf_geometry.hpp b/src/mbgl/geometry/pbf_geometry.hpp index 46380e6fe..84e15d101 100644 --- a/src/mbgl/geometry/pbf_geometry.hpp +++ b/src/mbgl/geometry/pbf_geometry.hpp @@ -11,7 +11,7 @@ namespace mbgl { class PBFGeometry : private util::noncopyable { public: - inline explicit PBFGeometry(pbf& data); + inline explicit PBFGeometry(pbf data); enum command : uint8_t { end = 0, @@ -23,14 +23,14 @@ public: inline command next(int32_t &rx, int32_t &ry); private: - pbf& data; + pbf data; uint8_t cmd; uint32_t length; int32_t x, y; int32_t ox, oy; }; -PBFGeometry::PBFGeometry(pbf& data_) +PBFGeometry::PBFGeometry(pbf data_) : data(data_), cmd(1), length(0), diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 40a820274..037b7a0db 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -26,13 +26,7 @@ enum class GeometryFeatureType : uint8_t { Polygon = 3 }; -typedef Coordinate GeometryPoint; -typedef std::vector GeometryLine; -typedef std::vector GeometryPolygon; - -using Geometry = mapbox::util::variant; - -typedef std::vector GeometryCollection; +typedef std::vector> GeometryCollection; class GeometryTileFeature : public mbgl::util::noncopyable { public: diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 7f472400a..b90237e72 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -53,52 +53,25 @@ mapbox::util::optional VectorTileFeature::getValue(const std::string& key GeometryCollection VectorTileFeature::getGeometries() const { GeometryCollection result; - pbf geom_pbf = geometry_pbf; - while (geom_pbf.next(4)) { // geometry - pbf current_geometry_pbf = geom_pbf.message(); - PBFGeometry current_geometry(current_geometry_pbf); - PBFGeometry::command cmd; - int32_t x, y; + PBFGeometry geometry(geometry_pbf); + PBFGeometry::command cmd; + int32_t x, y; - if (type == GeometryFeatureType::Point) { - if ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { - GeometryPoint point(x, y); - result.emplace_back(GeometryPoint(x, y)); - } - } else if (type == GeometryFeatureType::LineString) { - GeometryLine line; - while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { - if (cmd == PBFGeometry::move_to) { - if (!line.empty()) { - result.push_back(line); - line.clear(); - } - } - line.emplace_back(x, y); - } - if (line.size()) { - result.push_back(line); - } - } else if (type == GeometryFeatureType::Polygon) { - GeometryLine line; - while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { - if (cmd == PBFGeometry::move_to) { - if (line.size()) { - result.push_back(line); - line.clear(); - } - } - line.emplace_back(x, y); - } + std::vector line; - if (line.size()) { + while ((cmd = geometry.next(x, y)) != PBFGeometry::end) { + if (cmd == PBFGeometry::move_to) { + if (!line.empty()) { result.push_back(line); line.clear(); } - } else { - throw std::runtime_error("unrecognized geometry type"); } + line.emplace_back(x, y); + } + + if (!line.empty()) { + result.push_back(line); } return std::move(result); diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index 18e337f91..19ee30212 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -66,13 +66,14 @@ FillBucket::~FillBucket() { void FillBucket::addGeometry(const GeometryCollection& geometryCollection) { for (auto& line_ : geometryCollection) { - const GeometryLine& vertices = line_.get(); - for (auto& v : vertices) { - line.emplace_back(ClipperLib::IntPoint(v.x, v.y)); + for (auto& v : line_) { + line.emplace_back(v.x, v.y); + } + if (line.size()) { + clipper.AddPath(line, ClipperLib::ptSubject, true); + line.clear(); + hasVertices = true; } - clipper.AddPath(line, ClipperLib::ptSubject, true); - line.clear(); - hasVertices = true; } tessellate(); diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 1f2e26c16..6eea0d8d0 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -43,290 +43,292 @@ typedef uint16_t PointElement; void LineBucket::addGeometry(const GeometryCollection& geometryCollection) { for (auto& line : geometryCollection) { - const GeometryLine& vertices = line.get(); + addGeometry(line); + } +} - auto &layout = *styleLayout; - // TODO: use roundLimit - // const float roundLimit = geometry.round_limit; +void LineBucket::addGeometry(const std::vector& vertices) { + 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; + 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; + } + + CapType beginCap = layout.cap; + CapType endCap = closed ? CapType::Butt : layout.cap; + + JoinType currentJoin = JoinType::Miter; + + Coordinate currentVertex = Coordinate::null(), + prevVertex = Coordinate::null(), + nextVertex = Coordinate::null(); + vec2 prevNormal = vec2::null(), + nextNormal = vec2::null(); + + int32_t e1 = -1, e2 = -1, e3 = -1; + + int8_t flip = 1; + double distance = 0; + + if (closed) { + currentVertex = vertices[vertices.size() - 2]; + nextNormal = util::normal(currentVertex, lastVertex); + } + + int32_t start_vertex = (int32_t)vertexBuffer.index(); + + std::vector triangle_store; + std::vector point_store; + + for (size_t i = 0; i < vertices.size(); ++i) { + if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y }; + if (currentVertex) prevVertex = currentVertex; + + currentVertex = vertices[i]; + currentJoin = layout.join; + + if (prevVertex) distance += util::dist(currentVertex, prevVertex); + + // Find the next vertex. + if (i + 1 < vertices.size()) { + nextVertex = vertices[i + 1]; + } else { + nextVertex = Coordinate::null(); } - 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 the line is closed, we treat the last vertex like the first vertex. + if (!nextVertex && closed) { + nextVertex = vertices[1]; } - CapType beginCap = layout.cap; - CapType endCap = closed ? CapType::Butt : layout.cap; - - JoinType currentJoin = JoinType::Miter; - - Coordinate currentVertex = Coordinate::null(), - prevVertex = Coordinate::null(), - nextVertex = Coordinate::null(); - vec2 prevNormal = vec2::null(), - nextNormal = vec2::null(); - - int32_t e1 = -1, e2 = -1, e3 = -1; - - int8_t flip = 1; - double distance = 0; - - if (closed) { - currentVertex = vertices[vertices.size() - 2]; - nextNormal = util::normal(currentVertex, lastVertex); + if (nextVertex) { + // if two consecutive vertices exist, skip one + if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue; } - int32_t start_vertex = (int32_t)vertexBuffer.index(); + // 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(currentVertex, nextVertex); + } else { + nextNormal = { -prevNormal.x, -prevNormal.y }; + } - std::vector triangle_store; - std::vector point_store; + // 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 }; + } - for (size_t i = 0; i < vertices.size(); ++i) { - if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y }; - if (currentVertex) prevVertex = currentVertex; + // Determine the normal of the join extrusion. It is the angle bisector + // of the segments between the previous line and the next line. + vec2 joinNormal = { + prevNormal.x + nextNormal.x, + prevNormal.y + nextNormal.y + }; - currentVertex = vertices[i]; - currentJoin = layout.join; + // 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)); - if (prevVertex) distance += util::dist(currentVertex, prevVertex); - // Find the next vertex. - if (i + 1 < vertices.size()) { - nextVertex = vertices[i + 1]; - } else { - nextVertex = Coordinate::null(); + // 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 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; + + // 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; + } + + // 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; + + // 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 (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; } - // If the line is closed, we treat the last vertex like the first vertex. - if (!nextVertex && closed) { - nextVertex = vertices[1]; + if (roundness > layout.miter_limit) { + flip = -flip; } - if (nextVertex) { - // if two consecutive vertices exist, skip one - if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue; + // 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; + + // 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 + + 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); + } + } + + 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; + + // 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; + + prevNormal = { -nextNormal.x, -nextNormal.y }; + flip = 1; + + + // begin/end caps + if ((!prevVertex && beginCap == CapType::Round) || + (!nextVertex && endCap == CapType::Round)) { + point_store.emplace_back(e1); } - // 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(currentVertex, nextVertex); - } else { - nextNormal = { -prevNormal.x, -prevNormal.y }; - } - // 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 }; - } - - // Determine the normal of the join extrusion. It is the angle bisector - // of the segments between the previous line and the next line. - vec2 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 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; - - // 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; - } - - // 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; - - // 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 (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; - } - - if (roundness > layout.miter_limit) { - flip = -flip; - } - - // 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; - - // 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 - - 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); - } - } - - 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; - - // 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; - - prevNormal = { -nextNormal.x, -nextNormal.y }; - flip = 1; - - - // begin/end caps - if ((!prevVertex && beginCap == CapType::Round) || - (!nextVertex && endCap == CapType::Round)) { + if (currentJoin == JoinType::Round) { + if (prevVertex && nextVertex && (!closed || i > 0)) { point_store.emplace_back(e1); } - - if (currentJoin == JoinType::Round) { - if (prevVertex && nextVertex && (!closed || i > 0)) { - 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 (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 - flip * nextNormal.y, -flip * nextNormal.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; + // 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 (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 + flip * nextNormal.y, -flip * nextNormal.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; + } + } + + size_t end_vertex = vertexBuffer.index(); + size_t vertex_count = end_vertex - start_vertex; + + // 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()); } - size_t end_vertex = vertexBuffer.index(); - size_t vertex_count = end_vertex - start_vertex; - - // 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()); - } - - 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 - ); - } - - group.vertex_length += vertex_count; - group.elements_length += triangle_store.size(); + 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 + ); } - // 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()); - } + group.vertex_length += vertex_count; + group.elements_length += triangle_store.size(); + } - 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(); + // 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()); } + + 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 4190b79f5..25b219017 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -38,6 +38,7 @@ public: bool hasData() const override; void addGeometry(const GeometryCollection&); + void addGeometry(const std::vector& line); bool hasPoints() const; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 1d94714f7..c755573df 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -107,9 +107,7 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer auto &multiline = ft.geometry; GeometryCollection geometryCollection = feature->getGeometries(); - multiline.emplace_back(); - for (auto& geometry : geometryCollection) { - const GeometryLine& line = geometry.get(); + for (auto& line : geometryCollection) { multiline.emplace_back(); for (auto& point : line) { multiline.back().emplace_back(point.x, point.y);