From cb8341aeab8879c78d1f45a1cf4c924345fdd3a4 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 28 Mar 2020 00:14:47 +0100 Subject: [PATCH] Implement --exhaustive y mode as another database access optimization This one works best when you have a wide area with low height (e.g. 10000x200x10000) --- README.rst | 5 +++-- TileGenerator.cpp | 28 +++++++++++++++++++++++++--- include/TileGenerator.h | 2 +- minetestmapper.6 | 5 +++++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index c6b6e4d..b522a3f 100644 --- a/README.rst +++ b/README.rst @@ -108,5 +108,6 @@ scales: Draw scales on specified image edges (letters *t b l r* meaning top, bottom, left and right), e.g. ``--scales tbr`` exhaustive: - Select if database should be traversed exhaustively or using range queries, available: *never*, *y*, *full*, *auto* - Defaults to *auto*. You shouldn't need to change this, but doing so can improve rendering times on large maps. + | Select if database should be traversed exhaustively or using range queries, available: *never*, *y*, *full*, *auto* + | Defaults to *auto*. You shouldn't need to change this, but doing so can improve rendering times on large maps. + | For these optimizations to work it is important that you set ``min-y`` and ``max-y`` when you don't care about the world below e.g. -60 and above 1000 nodes. diff --git a/TileGenerator.cpp b/TileGenerator.cpp index 6117451..c264e00 100644 --- a/TileGenerator.cpp +++ b/TileGenerator.cpp @@ -353,7 +353,7 @@ void TileGenerator::openDb(const std::string &input) m_exhaustiveSearch = EXH_NEVER; else if (blocks < 200000) m_exhaustiveSearch = EXH_FULL; - else if (y_range < 600) + else if (y_range < 42) m_exhaustiveSearch = EXH_Y; else m_exhaustiveSearch = EXH_NEVER; @@ -364,8 +364,6 @@ void TileGenerator::openDb(const std::string &input) " in worse performance." << std::endl; } } - if (m_exhaustiveSearch == EXH_Y) - m_exhaustiveSearch = EXH_NEVER; // (TODO remove when implemented) assert(m_exhaustiveSearch != EXH_AUTO); } @@ -511,6 +509,30 @@ void TileGenerator::renderMap() } postRenderRow(zPos); } + } else if (m_exhaustiveSearch == EXH_Y) { +#ifndef NDEBUG + std::cerr << "Exhaustively searching height of " + << (yMax - (m_yMin / 16)) << " blocks" << std::endl; +#endif + std::vector positions; + positions.reserve(yMax - (m_yMin / 16)); + for (auto it = m_positions.rbegin(); it != m_positions.rend(); ++it) { + int16_t zPos = it->first; + for (auto it2 = it->second.rbegin(); it2 != it->second.rend(); ++it2) { + int16_t xPos = *it2; + + positions.clear(); + for (int16_t yPos = m_yMin / 16; yPos < yMax; yPos++) + positions.emplace_back(xPos, yPos, zPos); + + BlockList blockStack; + m_db->getBlocksByPos(blockStack, positions); + blockStack.sort(); + + renderSingle(xPos, zPos, blockStack); + } + postRenderRow(zPos); + } } else if (m_exhaustiveSearch == EXH_FULL) { #ifndef NDEBUG std::cerr << "Exhaustively searching " diff --git a/include/TileGenerator.h b/include/TileGenerator.h index 65bc5b2..4149b50 100644 --- a/include/TileGenerator.h +++ b/include/TileGenerator.h @@ -25,7 +25,7 @@ enum { enum { EXH_NEVER, // Always use range queries - EXH_Y, // Exhaustively search Y space, range queries for X/Z (future TODO) + EXH_Y, // Exhaustively search Y space, range queries for X/Z EXH_FULL, // Exhaustively search entire requested geometry EXH_AUTO, // Automatically pick one of the previous modes }; diff --git a/minetestmapper.6 b/minetestmapper.6 index bb456cb..ceff8f0 100644 --- a/minetestmapper.6 +++ b/minetestmapper.6 @@ -97,6 +97,11 @@ Draw scales on specified image edges (letters \fIt b l r\fP meaning top, bottom, Select if database should be traversed exhaustively or using range queries, available: \fInever\fP, \fIy\fP, \fIfull\fP, \fIauto\fP Defaults to \fIauto\fP. You shouldn't need to change this, but doing so can improve rendering times on large maps. +For these optimizations to work it is important that you set +.B min-y +and +.B max-y +when you don't care about the world below e.g. -60 and above 1000 nodes. .SH MORE INFORMATION Website: https://github.com/minetest/minetestmapper