mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-04 17:23:33 +01:00
Make region iteration more efficient for sparse worlds
Do not iterate over each region coordinate in the bounding box. Closes #12
This commit is contained in:
parent
c06af49068
commit
9ac3b00b6e
2 changed files with 35 additions and 33 deletions
11
src/Info.hpp
11
src/Info.hpp
|
@ -29,6 +29,7 @@
|
|||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
|
@ -40,6 +41,8 @@ namespace MinedMap {
|
|||
|
||||
class Info {
|
||||
public:
|
||||
typedef std::function<void (int, int)> RegionVisitor;
|
||||
|
||||
struct Level {
|
||||
std::map<int, std::set<int>> regions;
|
||||
std::tuple<int, int, int, int> bounds;
|
||||
|
@ -82,8 +85,12 @@ public:
|
|||
});
|
||||
}
|
||||
|
||||
size_t getMipmapLevel() const {
|
||||
return levels.size()-1;
|
||||
void visitRegions(size_t level, const RegionVisitor &visitor) const {
|
||||
for (const auto &item : levels[level].regions) {
|
||||
int z = item.first;
|
||||
for (int x : item.second)
|
||||
visitor(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
void setSpawn(const std::pair<int32_t, int32_t> &v) {
|
||||
|
|
|
@ -292,13 +292,9 @@ static void makeBiome(const std::string ®iondir, const std::string &outputdir
|
|||
}
|
||||
|
||||
static void makeBiomes(const std::string ®iondir, const std::string &outputdir, const Info *info) {
|
||||
int minX, maxX, minZ, maxZ;
|
||||
std::tie(minX, maxX, minZ, maxZ) = info->getBounds(0);
|
||||
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++)
|
||||
makeBiome(regiondir, outputdir, x, z);
|
||||
}
|
||||
info->visitRegions(0, [&] (int x, int z) {
|
||||
makeBiome(regiondir, outputdir, x, z);
|
||||
});
|
||||
}
|
||||
|
||||
static void makeMap(const std::string ®iondir, const std::string &outputdir, int x, int z) {
|
||||
|
@ -356,13 +352,9 @@ static void makeMap(const std::string ®iondir, const std::string &outputdir,
|
|||
}
|
||||
|
||||
static void makeMaps(const std::string ®iondir, const std::string &outputdir, const Info *info) {
|
||||
int minX, maxX, minZ, maxZ;
|
||||
std::tie(minX, maxX, minZ, maxZ) = info->getBounds(0);
|
||||
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++)
|
||||
makeMap(regiondir, outputdir, x, z);
|
||||
}
|
||||
info->visitRegions(0, [&] (int x, int z) {
|
||||
makeMap(regiondir, outputdir, x, z);
|
||||
});
|
||||
}
|
||||
|
||||
static bool makeMipmap(const std::string &dir, size_t level, int x, int z, PNG::Format imageFormat) {
|
||||
|
@ -432,29 +424,32 @@ static bool makeMipmap(const std::string &dir, size_t level, int x, int z, PNG::
|
|||
return true;
|
||||
}
|
||||
|
||||
static int floored_half(int a) {
|
||||
return (a - (a < 0)) / 2;
|
||||
}
|
||||
|
||||
static void makeMipmaps(const std::string &dir, Info *info) {
|
||||
int minX, maxX, minZ, maxZ;
|
||||
std::tie(minX, maxX, minZ, maxZ) = info->getBounds(0);
|
||||
for (size_t level = 0; ; level++) {
|
||||
int minX, maxX, minZ, maxZ;
|
||||
std::tie(minX, maxX, minZ, maxZ) = info->getBounds(level);
|
||||
|
||||
if (minX >= -1 && maxX <= 0 && minZ >= -1 && maxZ <= 0)
|
||||
break;
|
||||
|
||||
while (minX < -1 || maxX > 0 || minZ < -1 || maxZ > 0) {
|
||||
info->addMipmapLevel();
|
||||
size_t level = info->getMipmapLevel();
|
||||
makeDir(dir + "/map/" + format(level));
|
||||
makeDir(dir + "/light/" + format(level));
|
||||
makeDir(dir + "/map/" + format(level + 1));
|
||||
makeDir(dir + "/light/" + format(level + 1));
|
||||
|
||||
minX = (minX-1)/2;
|
||||
maxX = maxX/2;
|
||||
minZ = (minZ-1)/2;
|
||||
maxZ = maxZ/2;
|
||||
info->visitRegions(level, [&] (int x, int z) {
|
||||
info->addRegion(floored_half(x), floored_half(z), level + 1);
|
||||
});
|
||||
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
if (makeMipmap(dir + "/map", level, x, z, PNG::RGB_ALPHA))
|
||||
info->addRegion(x, z, level);
|
||||
info->visitRegions(level + 1, [&] (int x, int z) {
|
||||
if (makeMipmap(dir + "/map", level + 1, x, z, PNG::RGB_ALPHA))
|
||||
info->addRegion(x, z, level + 1);
|
||||
|
||||
makeMipmap(dir + "/light", level, x, z, PNG::GRAY_ALPHA);
|
||||
}
|
||||
}
|
||||
makeMipmap(dir + "/light", level + 1, x, z, PNG::GRAY_ALPHA);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue