From 703464aa1626d306fa08ec07711a64954905fd7d Mon Sep 17 00:00:00 2001 From: Tymofii Baga <3448+fester@users.noreply.github.com> Date: Tue, 15 Jan 2019 12:46:17 +0100 Subject: [PATCH 1/7] Compute vertex normals in Mesh. Signed-off-by: Tymofii Baga <3448+fester@users.noreply.github.com> --- include/tntn/Mesh.h | 8 +++++-- include/tntn/geometrix.h | 2 ++ src/Mesh.cpp | 45 +++++++++++++++++++++++++++++++++++++++- test/src/Mesh_tests.cpp | 29 ++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/include/tntn/Mesh.h b/include/tntn/Mesh.h index 89e77dd..47febbb 100644 --- a/include/tntn/Mesh.h +++ b/include/tntn/Mesh.h @@ -44,7 +44,8 @@ class Mesh SimpleRange triangles() const; SimpleRange faces() const; SimpleRange vertices() const; - + SimpleRange vertex_normals() const; + void grab_triangles(std::vector& into); void grab_decomposed(std::vector& vertices, std::vector& faces); @@ -62,6 +63,8 @@ class Mesh bool is_square() const; bool check_for_holes_in_square_mesh() const; + void compute_vertex_normals(); + private: bool semantic_equal_tri_tri(const Mesh& other) const; bool semantic_equal_dec_dec(const Mesh& other) const; @@ -70,7 +73,8 @@ class Mesh std::vector m_vertices; std::vector m_faces; std::vector m_triangles; - + std::vector m_normals; + void decompose_triangle(const Triangle& t); }; diff --git a/include/tntn/geometrix.h b/include/tntn/geometrix.h index 48322a9..6183fd6 100644 --- a/include/tntn/geometrix.h +++ b/include/tntn/geometrix.h @@ -18,6 +18,8 @@ typedef std::array Triangle; typedef size_t VertexIndex; //0-based index into an array/vector of vertices typedef std::array Face; +typedef glm::dvec3 Normal; + struct Edge { Edge() = default; diff --git a/src/Mesh.cpp b/src/Mesh.cpp index fe478f5..8526387 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -5,11 +5,11 @@ #include #include #include +#include #include "tntn/tntn_assert.h" #include "tntn/logging.h" #include "tntn/geometrix.h" - namespace tntn { void Mesh::clear() @@ -217,6 +217,15 @@ SimpleRange Mesh::vertices() const return {m_vertices.data(), m_vertices.data() + m_vertices.size()}; } +SimpleRange Mesh::vertex_normals() const +{ + if(m_normals.empty()) + { + return {nullptr, nullptr}; + } + return {m_normals.data(), m_normals.data() + m_normals.size()}; +} + void Mesh::grab_triangles(std::vector& into) { into.clear(); @@ -710,4 +719,38 @@ bool Mesh::check_tin_properties() const return true; } +void Mesh::compute_vertex_normals() +{ + using namespace glm; + + std::vector face_normals; + face_normals.reserve(m_faces.size()); + m_normals.resize(m_vertices.size()); + + auto face_normal = [](const Triangle& t) { + return normalize(cross(t[0] - t[2], t[1] - t[2])); + }; + + std::transform(m_triangles.begin(), m_triangles.end(), face_normals.begin(), face_normal); + + const int faces_count = m_faces.size(); + + for(int f = 0; f < faces_count; f++) + { + const auto& face = m_faces[f]; + const auto& face_normal = face_normals[f]; + + for(int v = 0; v < 3; v++) + { + const int vertex_id = face[v]; + m_normals[vertex_id] += face_normal; + } + } + + for(auto& vertex_normal : m_normals) + { + vertex_normal = normalize(vertex_normal); + } +} + } //namespace tntn diff --git a/test/src/Mesh_tests.cpp b/test/src/Mesh_tests.cpp index 2da3c01..eb8e3e6 100644 --- a/test/src/Mesh_tests.cpp +++ b/test/src/Mesh_tests.cpp @@ -322,5 +322,34 @@ TEST_CASE("Mesh::check_tin_properties detects unreferenced vertices") CHECK(!m.check_tin_properties()); } +TEST_CASE("Mesh::compute_normals normals") +{ + Mesh m; + + m.from_decomposed( + { + {0, 0, 1}, + {1, 0, 2}, + {1, 1, 3}, + {0, 1, 4}, + {0.5, -1, 5}, + }, + { + {{0, 1, 2}}, //ccw + {{0, 2, 3}}, //ccw + {{0, 4, 1}}, //ccw + }); + m.generate_triangles(); + m.compute_vertex_normals(); + + const auto vnormals = m.vertex_normals(); + CHECK(std::distance(vnormals.begin, vnormals.end) == 5); + + for(auto n = vnormals.begin; n != vnormals.end; ++n) + { + CHECK((glm::length(*n) - 1.0) < 0.00001); + } +} + } //namespace unittests } //namespace tntn From 9bf2414b36d5027d870d32f38e697e530541331b Mon Sep 17 00:00:00 2001 From: Tymofii Baga <3448+fester@users.noreply.github.com> Date: Fri, 25 Jan 2019 11:09:52 +0100 Subject: [PATCH 2/7] Added has_normals() to Mesh. Signed-off-by: Tymofii Baga <3448+fester@users.noreply.github.com> --- include/tntn/Mesh.h | 1 + src/Mesh.cpp | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/tntn/Mesh.h b/include/tntn/Mesh.h index 47febbb..8b08324 100644 --- a/include/tntn/Mesh.h +++ b/include/tntn/Mesh.h @@ -64,6 +64,7 @@ class Mesh bool check_for_holes_in_square_mesh() const; void compute_vertex_normals(); + bool has_normals() const; private: bool semantic_equal_tri_tri(const Mesh& other) const; diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 8526387..7c64a0e 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -17,6 +17,7 @@ void Mesh::clear() m_triangles.clear(); m_vertices.clear(); m_faces.clear(); + m_normals.clear(); } void Mesh::clear_triangles() @@ -36,6 +37,7 @@ Mesh Mesh::clone() const out.m_faces = m_faces; out.m_vertices = m_vertices; out.m_triangles = m_triangles; + out.m_normals = m_normals; return out; } @@ -719,6 +721,11 @@ bool Mesh::check_tin_properties() const return true; } +bool Mesh::has_normals() const +{ + return !m_normals.empty(); +} + void Mesh::compute_vertex_normals() { using namespace glm; @@ -747,10 +754,8 @@ void Mesh::compute_vertex_normals() } } - for(auto& vertex_normal : m_normals) - { - vertex_normal = normalize(vertex_normal); - } + std::transform(m_normals.begin(), m_normals.end(), m_normals.begin(), + [](const auto &n) { return normalize(n); }); } } //namespace tntn From cc2b9b7afef17320e5bb5dc2592cdc126bbe5086 Mon Sep 17 00:00:00 2001 From: Tymofii Baga <3448+fester@users.noreply.github.com> Date: Fri, 25 Jan 2019 11:12:21 +0100 Subject: [PATCH 3/7] QuantizedMeshIO can write mesh normals. Signed-off-by: Tymofii Baga <3448+fester@users.noreply.github.com> --- src/QuantizedMeshIO.cpp | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/QuantizedMeshIO.cpp b/src/QuantizedMeshIO.cpp index a865878..881e1da 100644 --- a/src/QuantizedMeshIO.cpp +++ b/src/QuantizedMeshIO.cpp @@ -91,6 +91,12 @@ struct QuantizedMeshHeader // double HorizonOcclusionPointZ; }; +enum QuantizedMeshExtensionList +{ + QMExtensionNormals = 1, + QMExtensionWaterMask = 2 +}; + namespace detail { uint16_t zig_zag_encode(int16_t i) @@ -317,6 +323,37 @@ bool point_to_ecef(Vertex& p) return (bool)tr->Transform(1, &p.x, &p.y, &p.z); } +void oct_encode(const Normal& v, uint8_t out[2]) +{ + const glm::dvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z))); + const auto signNotZero = glm::dvec2(v.x >= 0 ? 1.0 : -1.0, v.y > 0 ? 1.0 : -1.0); + const glm::dvec2 abs_v = p.yx; + glm::dvec2 ov = (v.z <= 0.0) ? ((1.0 - glm::abs(abs_v)) * signNotZero) : p; + + ov = (ov + 1.0) / 2.0; + + out[0] = static_cast(ov.x * 255); + out[1] = static_cast(ov.y * 255); +} + +void write_normals(BinaryIO& bio, + BinaryIOErrorTracker& e, + const SimpleRange& normals) +{ + // Write extension header + bio.write_byte(QMExtensionNormals, e); + bio.write_uint32(normals.distance() * 2, e); + + uint8_t oct_normal[2]; + + for(auto n = normals.begin; n != normals.end; n++) + { + oct_encode(*n, oct_normal); + bio.write_byte(oct_normal[0], e); + bio.write_byte(oct_normal[1], e); + } +} + bool write_mesh_as_qm(const std::shared_ptr& f, const Mesh& m, const BBox3D& bbox, @@ -496,6 +533,11 @@ bool write_mesh_as_qm(const std::shared_ptr& f, write_indices(bio, e, northlings); } + if(m.has_normals()) + { + write_normals(bio, e, m.vertex_normals()); + } + if(e.has_error()) { TNTN_LOG_ERROR("{} in file {}", e.to_string(), f->name()); @@ -503,6 +545,7 @@ bool write_mesh_as_qm(const std::shared_ptr& f, } TNTN_LOG_INFO("writer log: {}", log.to_string()); + return true; } From 8b85cedcc8733ff2460ffda121c6ce386e279488 Mon Sep 17 00:00:00 2001 From: Tymofii Baga <3448+fester@users.noreply.github.com> Date: Fri, 25 Jan 2019 17:54:42 +0100 Subject: [PATCH 4/7] Addded a command line switch to write QM normals. Signed-off-by: Tymofii Baga <3448+fester@users.noreply.github.com> --- include/tntn/TileMaker.h | 7 +++++-- include/tntn/dem2tintiles_workflow.h | 1 + src/TileMaker.cpp | 16 ++++++++++++---- src/cmd.cpp | 4 ++++ src/dem2tintiles_workflow.cpp | 3 ++- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/include/tntn/TileMaker.h b/include/tntn/TileMaker.h index f007c2c..2a6635a 100644 --- a/include/tntn/TileMaker.h +++ b/include/tntn/TileMaker.h @@ -10,10 +10,13 @@ namespace tntn { class TileMaker { std::unique_ptr m_mesh; - + bool m_normals_enabled; + public: - TileMaker() : m_mesh(std::make_unique()) {} + TileMaker(bool normals_enabled=false) : m_mesh(std::make_unique()), + m_normals_enabled(normals_enabled) {} + bool normals_enabled() const; void setMeshWriter(MeshWriter* w); bool loadObj(const char* filename); void loadMesh(std::unique_ptr mesh); diff --git a/include/tntn/dem2tintiles_workflow.h b/include/tntn/dem2tintiles_workflow.h index b50f3c9..cb1dc93 100644 --- a/include/tntn/dem2tintiles_workflow.h +++ b/include/tntn/dem2tintiles_workflow.h @@ -21,6 +21,7 @@ std::vector create_partitions_for_zoom_level(const RasterDouble& dem, bool create_tiles_for_zoom_level(const RasterDouble& dem, const std::vector& partitions, int zoom, + bool include_normals, const std::string& output_basedir, const double method_parameter, const std::string& meshing_method, diff --git a/src/TileMaker.cpp b/src/TileMaker.cpp index 8615d1a..5e26961 100644 --- a/src/TileMaker.cpp +++ b/src/TileMaker.cpp @@ -41,6 +41,11 @@ void TileMaker::loadMesh(std::unique_ptr mesh) m_mesh = std::move(mesh); } +bool TileMaker::normals_enabled() const +{ + return m_normals_enabled; +} + // Dump a tile into an terrain tile in format determined by a MeshWriter bool TileMaker::dumpTile(int tx, int ty, int zoom, const char* filename, MeshWriter& mesh_writer) { @@ -82,10 +87,8 @@ bool TileMaker::dumpTile(int tx, int ty, int zoom, const char* filename, MeshWri { for(int i = 0; i < 3; i++) { - if(triangle[i].z < tileSpaceBbox.min.z) - tileSpaceBbox.min.z = triangle[i].z; - if(triangle[i].z > tileSpaceBbox.max.z) - tileSpaceBbox.max.z = triangle[i].z; + if(triangle[i].z < tileSpaceBbox.min.z) tileSpaceBbox.min.z = triangle[i].z; + if(triangle[i].z > tileSpaceBbox.max.z) tileSpaceBbox.max.z = triangle[i].z; } } @@ -120,6 +123,11 @@ bool TileMaker::dumpTile(int tx, int ty, int zoom, const char* filename, MeshWri tileMesh.from_triangles(std::move(trianglesInTile)); tileMesh.generate_decomposed(); + if(normals_enabled()) + { + tileMesh.compute_vertex_normals(); + } + return mesh_writer.write_mesh_to_file(filename, tileMesh, tileSpaceBbox); } diff --git a/src/cmd.cpp b/src/cmd.cpp index c303e12..d2f917a 100644 --- a/src/cmd.cpp +++ b/src/cmd.cpp @@ -55,6 +55,7 @@ static int subcommand_dem2tintiles(bool need_help, ("max-error", po::value(), "max error parameter when using terra or zemlya method") ("step", po::value()->default_value(1), "grid spacing in pixels when using dense method") ("output-format", po::value()->default_value("terrain"), "output tiles in terrain (quantized mesh) or obj") + ("normals", po::bool_switch()->default_value(false), "generate normals for terrain") #if defined(TNTN_USE_ADDONS) && TNTN_USE_ADDONS ("method", po::value()->default_value("terra"), "meshing algorithm. one of: terra, zemlya, curvature or dense") ("threshold", po::value(), "threshold when using curvature method"); @@ -176,6 +177,8 @@ static int subcommand_dem2tintiles(bool need_help, throw po::error(std::string("unknown method ") + meshing_method); } + bool write_normals = local_varmap["normals"].as(); + RasterOverviews overviews(std::move(input_raster), min_zoom, max_zoom); RasterOverview overview; @@ -214,6 +217,7 @@ static int subcommand_dem2tintiles(bool need_help, if(!create_tiles_for_zoom_level(*overview.raster, partitions, zoom_level, + write_normals, output_basedir, max_error, meshing_method, diff --git a/src/dem2tintiles_workflow.cpp b/src/dem2tintiles_workflow.cpp index 4310145..d9a80b5 100644 --- a/src/dem2tintiles_workflow.cpp +++ b/src/dem2tintiles_workflow.cpp @@ -66,6 +66,7 @@ std::vector create_partitions_for_zoom_level(const RasterDouble& dem, bool create_tiles_for_zoom_level(const RasterDouble& dem, const std::vector& partitions, int zoom, + bool include_normals, const std::string& output_basedir, const double method_parameter, const std::string& meshing_method, @@ -128,7 +129,7 @@ bool create_tiles_for_zoom_level(const RasterDouble& dem, } // Cut the TIN into tiles - TileMaker tm; + TileMaker tm(include_normals); tm.loadMesh(std::move(mesh)); fs::create_directory(fs::path(output_basedir)); From 002aeee956f5c8e9d45df4f02d82fcc4b8f054bb Mon Sep 17 00:00:00 2001 From: Tymofii Baga <3448+fester@users.noreply.github.com> Date: Mon, 28 Jan 2019 10:49:31 +0100 Subject: [PATCH 5/7] Fix formatting. Signed-off-by: Tymofii Baga <3448+fester@users.noreply.github.com> --- include/tntn/Mesh.h | 14 +++++++------- include/tntn/TileMaker.h | 2 +- include/tntn/dem2tintiles_workflow.h | 2 +- src/Mesh.cpp | 11 ++++++----- src/cmd.cpp | 6 +++--- src/dem2tintiles_workflow.cpp | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/tntn/Mesh.h b/include/tntn/Mesh.h index 8b08324..8f961d4 100644 --- a/include/tntn/Mesh.h +++ b/include/tntn/Mesh.h @@ -44,8 +44,8 @@ class Mesh SimpleRange triangles() const; SimpleRange faces() const; SimpleRange vertices() const; - SimpleRange vertex_normals() const; - + SimpleRange vertex_normals() const; + void grab_triangles(std::vector& into); void grab_decomposed(std::vector& vertices, std::vector& faces); @@ -63,9 +63,9 @@ class Mesh bool is_square() const; bool check_for_holes_in_square_mesh() const; - void compute_vertex_normals(); - bool has_normals() const; - + void compute_vertex_normals(); + bool has_normals() const; + private: bool semantic_equal_tri_tri(const Mesh& other) const; bool semantic_equal_dec_dec(const Mesh& other) const; @@ -74,8 +74,8 @@ class Mesh std::vector m_vertices; std::vector m_faces; std::vector m_triangles; - std::vector m_normals; - + std::vector m_normals; + void decompose_triangle(const Triangle& t); }; diff --git a/include/tntn/TileMaker.h b/include/tntn/TileMaker.h index 2a6635a..20e0ec5 100644 --- a/include/tntn/TileMaker.h +++ b/include/tntn/TileMaker.h @@ -16,7 +16,7 @@ class TileMaker TileMaker(bool normals_enabled=false) : m_mesh(std::make_unique()), m_normals_enabled(normals_enabled) {} - bool normals_enabled() const; + bool normals_enabled() const; void setMeshWriter(MeshWriter* w); bool loadObj(const char* filename); void loadMesh(std::unique_ptr mesh); diff --git a/include/tntn/dem2tintiles_workflow.h b/include/tntn/dem2tintiles_workflow.h index cb1dc93..88eb0de 100644 --- a/include/tntn/dem2tintiles_workflow.h +++ b/include/tntn/dem2tintiles_workflow.h @@ -21,7 +21,7 @@ std::vector create_partitions_for_zoom_level(const RasterDouble& dem, bool create_tiles_for_zoom_level(const RasterDouble& dem, const std::vector& partitions, int zoom, - bool include_normals, + bool include_normals, const std::string& output_basedir, const double method_parameter, const std::string& meshing_method, diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 7c64a0e..f517165 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -17,7 +17,7 @@ void Mesh::clear() m_triangles.clear(); m_vertices.clear(); m_faces.clear(); - m_normals.clear(); + m_normals.clear(); } void Mesh::clear_triangles() @@ -37,7 +37,7 @@ Mesh Mesh::clone() const out.m_faces = m_faces; out.m_vertices = m_vertices; out.m_triangles = m_triangles; - out.m_normals = m_normals; + out.m_normals = m_normals; return out; } @@ -723,7 +723,7 @@ bool Mesh::check_tin_properties() const bool Mesh::has_normals() const { - return !m_normals.empty(); + return !m_normals.empty(); } void Mesh::compute_vertex_normals() @@ -754,8 +754,9 @@ void Mesh::compute_vertex_normals() } } - std::transform(m_normals.begin(), m_normals.end(), m_normals.begin(), - [](const auto &n) { return normalize(n); }); + std::transform(m_normals.begin(), m_normals.end(), m_normals.begin(), [](const auto& n) { + return normalize(n); + }); } } //namespace tntn diff --git a/src/cmd.cpp b/src/cmd.cpp index d2f917a..ce112e4 100644 --- a/src/cmd.cpp +++ b/src/cmd.cpp @@ -177,8 +177,8 @@ static int subcommand_dem2tintiles(bool need_help, throw po::error(std::string("unknown method ") + meshing_method); } - bool write_normals = local_varmap["normals"].as(); - + bool write_normals = local_varmap["normals"].as(); + RasterOverviews overviews(std::move(input_raster), min_zoom, max_zoom); RasterOverview overview; @@ -217,7 +217,7 @@ static int subcommand_dem2tintiles(bool need_help, if(!create_tiles_for_zoom_level(*overview.raster, partitions, zoom_level, - write_normals, + write_normals, output_basedir, max_error, meshing_method, diff --git a/src/dem2tintiles_workflow.cpp b/src/dem2tintiles_workflow.cpp index d9a80b5..77ea52a 100644 --- a/src/dem2tintiles_workflow.cpp +++ b/src/dem2tintiles_workflow.cpp @@ -66,7 +66,7 @@ std::vector create_partitions_for_zoom_level(const RasterDouble& dem, bool create_tiles_for_zoom_level(const RasterDouble& dem, const std::vector& partitions, int zoom, - bool include_normals, + bool include_normals, const std::string& output_basedir, const double method_parameter, const std::string& meshing_method, From 1d965aa78f430d521506b308a59757fcdd4d6a95 Mon Sep 17 00:00:00 2001 From: Tymofii Baga <3448+fester@users.noreply.github.com> Date: Mon, 4 Feb 2019 18:37:30 +0100 Subject: [PATCH 6/7] Correctly limit zoom levels for raster overviews. Signed-off-by: Tymofii Baga <3448+fester@users.noreply.github.com> --- src/RasterOverviews.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/RasterOverviews.cpp b/src/RasterOverviews.cpp index 5d07c71..1be8f5f 100644 --- a/src/RasterOverviews.cpp +++ b/src/RasterOverviews.cpp @@ -60,12 +60,18 @@ void RasterOverviews::compute_zoom_levels() m_estimated_min_zoom = guess_min_zoom_level(m_estimated_max_zoom); m_min_zoom = std::max(m_min_zoom, m_estimated_min_zoom); - m_max_zoom = std::min(std::max(0, m_max_zoom), m_estimated_max_zoom); + + if(m_max_zoom < 0 || m_max_zoom > m_estimated_max_zoom) + { + m_max_zoom = m_estimated_max_zoom; + } if(m_max_zoom < m_min_zoom) { std::swap(m_min_zoom, m_max_zoom); } + + TNTN_LOG_INFO("After checking with data, tiles will be generated in a range between {} and {}", m_min_zoom, m_max_zoom); } bool RasterOverviews::next(RasterOverview& overview) From c9a11ecd5de21feab944cdec3bf9413a1d0ffd29 Mon Sep 17 00:00:00 2001 From: Tymofii Baga <3448+fester@users.noreply.github.com> Date: Tue, 5 Feb 2019 13:12:43 +0100 Subject: [PATCH 7/7] Formatting gone wrong, again. Signed-off-by: Tymofii Baga <3448+fester@users.noreply.github.com> --- src/RasterOverviews.cpp | 43 ++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/RasterOverviews.cpp b/src/RasterOverviews.cpp index 1be8f5f..ccc0bbf 100644 --- a/src/RasterOverviews.cpp +++ b/src/RasterOverviews.cpp @@ -22,35 +22,34 @@ RasterOverviews::RasterOverviews(UniqueRasterPointer input_raster, int min_zoom, // Guesses (numerically) maximal zoom level from a raster resolution int RasterOverviews::guess_max_zoom_level(double resolution) { - // pixel_size_z0 is a magic number that is number of meters per pixel on zoom level 0, given tile size is 256 pixels. - // This number is approximate and does not account for latitude, i.e. uses pixel size on equator. - // The formula is: earth circumference * 2 * pi / 256 - // "Real" number can be off up to 30% depending on the latitude. More details here: https://msdn.microsoft.com/en-us/library/aa940990.aspx - const double pixel_size_z0 = 156543.04; + // pixel_size_z0 is a magic number that is number of meters per pixel on zoom level 0, given tile size is 256 pixels. + // This number is approximate and does not account for latitude, i.e. uses pixel size on equator. + // The formula is: earth circumference * 2 * pi / 256 + // "Real" number can be off up to 30% depending on the latitude. More details here: https://msdn.microsoft.com/en-us/library/aa940990.aspx + const double pixel_size_z0 = 156543.04; return static_cast(round(log2(pixel_size_z0 / resolution))); } // Guesses (numerically) minimal zoom level from a raster resolution and it's size int RasterOverviews::guess_min_zoom_level(int max_zoom_level) { - // This constant is an arbitrary number representing some minimal size to which the raster can be downsized when 'zooming out' a map. - // Math is simple: - // 2**max_zoom = raster_size; 2**min_zoom = 128 - // Solve it in regards to min_zoom and there you have it. - const int MINIMAL_RASTER_SIZE = 128; + // This constant is an arbitrary number representing some minimal size to which the raster can be downsized when 'zooming out' a map. + // Math is simple: + // 2**max_zoom = raster_size; 2**min_zoom = 128 + // Solve it in regards to min_zoom and there you have it. + const int MINIMAL_RASTER_SIZE = 128; const double quotient = MINIMAL_RASTER_SIZE * (1 << max_zoom_level); int raster_width = m_base_raster->get_width(); int raster_height = m_base_raster->get_height(); - TNTN_LOG_DEBUG("guess_min_zoom_level: raster_width: {}, raster_height: {}", - raster_width, - raster_height); + TNTN_LOG_DEBUG( + "guess_min_zoom_level: raster_width: {}, raster_height: {}", raster_width, raster_height); int zoom_x = static_cast(floor(log2(quotient / raster_width))); int zoom_y = static_cast(floor(log2(quotient / raster_height))); - // Cap the resulting value so it won't go below 0 and we wouldn't end up with negative zoom levels + // Cap the resulting value so it won't go below 0 and we wouldn't end up with negative zoom levels return std::max(0, std::min(zoom_x, zoom_y)); } @@ -71,7 +70,10 @@ void RasterOverviews::compute_zoom_levels() std::swap(m_min_zoom, m_max_zoom); } - TNTN_LOG_INFO("After checking with data, tiles will be generated in a range between {} and {}", m_min_zoom, m_max_zoom); + TNTN_LOG_INFO( + "After checking with data, tiles will be generated in a range between {} and {}", + m_min_zoom, + m_max_zoom); } bool RasterOverviews::next(RasterOverview& overview) @@ -94,11 +96,12 @@ bool RasterOverviews::next(RasterOverview& overview) overview.resolution = output_raster->get_cell_size(); overview.raster = std::move(output_raster); - TNTN_LOG_DEBUG("Generated next overview at zoom {}, window size {}, min zoom level {}, max zoom level {}", - m_current_zoom + 1, - window_size, - m_min_zoom, - m_max_zoom); + TNTN_LOG_DEBUG( + "Generated next overview at zoom {}, window size {}, min zoom level {}, max zoom level {}", + m_current_zoom + 1, + window_size, + m_min_zoom, + m_max_zoom); return true; }