Add shorthand options to draw tiles matching map-blocks and map-chunks

The option --tiles has two new possible values: 'block' and 'chunk'
'block' creates tiles corresponding to map blocks
'chunk' creates tiles corresponding to map chunks
(chunks are the unit of map generation).

An option --chunksize was added to manually override the chunk size.
This commit is contained in:
Rogier 2015-01-03 19:10:50 +01:00
parent 5aa358aafe
commit 22041a8603
5 changed files with 125 additions and 22 deletions

View File

@ -348,13 +348,20 @@ sqlite-cacheworldrow:
This may improve performance when a large percentage of the world is mapped.
tiles <tilesize>[+<border>]
chunksize:
Manually specify the chunk size (for use with --tiles chunk)
tiles <tilesize>[+<border>]|block|chunk
Divide the map in square tiles of the requested size. A border of the
requested width (or width 1, of not specfied) is drawn between the tiles.
In order to preserve all map pixels (and to prevent overwriting them with
borders), extra pixel rows and columns for the borders are inserted into
the map.
The special values 'block' and 'chunk' draw tiles that correspond to map
blocks (16x16 nodes) or to chunks (the unit of map generation; 5x5 blocks
for a world with default settings).
In order to allow partial world maps to be combined into larger maps, edge
borders of the map are always drawn on the same side (left or top). Other
edges are always border-less.
@ -365,6 +372,8 @@ tiles <tilesize>[+<border>]
`--tiles 1000+2`
`--tiles block`
NOTE: As a consequence of preserving all map pixels:
* tiled maps (in particular slanted straight lines) may look slightly

View File

@ -143,6 +143,7 @@ TileGenerator::TileGenerator():
m_shrinkGeometry(true),
m_blockGeometry(false),
m_sqliteCacheWorldRow(false),
m_chunkSize(0),
m_image(0),
m_xMin(INT_MAX/16-1),
m_xMax(INT_MIN/16+1),
@ -367,6 +368,11 @@ void TileGenerator::setBackend(std::string backend)
m_backend = backend;
}
void TileGenerator::setChunkSize(int size)
{
m_chunkSize = size;
}
void TileGenerator::generate(const std::string &input, const std::string &output)
{
string input_path = input;
@ -376,7 +382,7 @@ void TileGenerator::generate(const std::string &input, const std::string &output
openDb(input_path);
loadBlocks();
computeMapParameters();
computeMapParameters(input);
createImage();
renderMap();
if (m_drawScale) {
@ -524,6 +530,49 @@ std::string TileGenerator::getWorldDatabaseBackend(const std::string &input)
return backend;
}
int TileGenerator::getMapChunkSize(const std::string &input)
{
int chunkSize = -1;
std::string worldFile = input + PATH_SEPARATOR + "map_meta.txt";
ifstream in;
in.open(worldFile.c_str(), ifstream::in);
if (!in.is_open()) {
cerr << "Could not obtain world chunk size: failed to open map_meta.txt - using default size ("
<< CHUNK_SIZE_DEFAULT << ")" << std::endl;
return CHUNK_SIZE_DEFAULT;
}
std::string line;
int linenr = 0;
for (std::getline(in,line); in.good(); std::getline(in,line)) {
linenr++;
istringstream iline;
iline.str(line);
iline >> std::skipws;
string variable;
char eq;
iline >> variable;
if (variable != "chunksize")
continue;
iline >> std::ws >> eq;
iline >> chunkSize;
if (in.fail() || eq != '=') {
cerr << "Could not obtain world chunk size: error parsing configuration line - using default size ("
<< CHUNK_SIZE_DEFAULT << ")" << std::endl;
return CHUNK_SIZE_DEFAULT;
}
if (chunkSize <= 0) {
cerr << "Invalid chunk size found in map_meta.txt (" << chunkSize << ") - using default size ("
<< CHUNK_SIZE_DEFAULT << ")" << std::endl;
return CHUNK_SIZE_DEFAULT;
}
}
in.close();
if (chunkSize < 0) return CHUNK_SIZE_DEFAULT;
else return chunkSize;
}
void TileGenerator::openDb(const std::string &input)
{
string backend = m_backend;
@ -876,8 +925,15 @@ void TileGenerator::computeTileParameters(
tileBorderCount = tileBorderLimit - tileBorderStart;
}
void TileGenerator::computeMapParameters()
void TileGenerator::computeMapParameters(const std::string &input)
{
if (!m_chunkSize && (m_tileWidth == TILESIZE_CHUNK || m_tileHeight == TILESIZE_CHUNK))
m_chunkSize = getMapChunkSize(input);
if (m_tileWidth == TILESIZE_CHUNK)
m_tileWidth = m_chunkSize * BLOCK_SIZE;
if (m_tileHeight == TILESIZE_CHUNK)
m_tileHeight = m_chunkSize * BLOCK_SIZE;
m_storedWidth = (m_xMax - m_xMin + 1) * 16;
m_storedHeight = (m_zMax - m_zMin + 1) * 16;
int mapWidth = m_storedWidth - m_mapXStartNodeOffset + m_mapXEndNodeOffset;
@ -893,6 +949,9 @@ void TileGenerator::computeMapParameters()
case TILECORNER_AT_WORLDCENTER:
m_tileXOrigin = 0;
break;
case TILECENTER_AT_CHUNKCENTER:
m_tileXOrigin = ((m_chunkSize%2) ? BLOCK_SIZE / 2 : 0) - m_tileWidth / 2;
break;
case TILECENTER_AT_MAPCENTER:
m_tileXOrigin = m_xMin * 16 + m_mapXStartNodeOffset + mapWidth / 2 - m_tileWidth / 2;
break;
@ -913,6 +972,9 @@ void TileGenerator::computeMapParameters()
case TILECORNER_AT_WORLDCENTER:
m_tileZOrigin = 0;
break;
case TILECENTER_AT_CHUNKCENTER:
m_tileZOrigin = ((m_chunkSize%2) ? BLOCK_SIZE / 2 : 0) - m_tileHeight / 2;
break;
case TILECENTER_AT_MAPCENTER:
m_tileZOrigin = (m_zMax + 1) * 16 - 1 - m_mapYStartNodeOffset - mapHeight / 2 - m_tileHeight / 2;
break;

View File

@ -29,8 +29,10 @@
#include "Color.h"
#include "db.h"
#define TILESIZE_CHUNK (INT_MIN)
#define TILECENTER_AT_WORLDCENTER (INT_MAX)
#define TILECORNER_AT_WORLDCENTER (INT_MAX - 1)
#define TILECENTER_AT_CHUNKCENTER (INT_MAX - 2)
#define TILECENTER_AT_MAPCENTER (INT_MIN)
#define TILECORNER_AT_MAPCENTER (INT_MIN + 1)
@ -109,15 +111,17 @@ public:
void enableProgressIndicator(void);
void parseColorsFile(const std::string &fileName, int depth = 0);
void setBackend(std::string backend);
void setChunkSize(int size);
void generate(const std::string &input, const std::string &output);
private:
void parseColorsStream(std::istream &in, const std::string &filename, int depth);
std::string getWorldDatabaseBackend(const std::string &input);
int getMapChunkSize(const std::string &input);
void openDb(const std::string &input);
void loadBlocks();
void createImage();
void computeMapParameters();
void computeMapParameters(const std::string &input);
void computeTileParameters(
// Input parameters
int minPos,
@ -176,6 +180,7 @@ private:
bool m_shrinkGeometry;
bool m_blockGeometry;
bool m_sqliteCacheWorldRow;
int m_chunkSize;
DB *m_db;
gdImagePtr m_image;

View File

@ -16,6 +16,7 @@
#define BLOCK_SIZE 16
#define MAPBLOCK_MIN (-2048)
#define MAPBLOCK_MAX 2047
#define CHUNK_SIZE_DEFAULT 5
// Max number of node name -> color mappings stored in a mapblock
#define MAPBLOCK_MAXCOLORS 65536

View File

@ -29,6 +29,7 @@ using namespace std;
#define OPT_BLOCKCOLOR 0x84
#define OPT_DRAWAIR 0x85
#define OPT_VERBOSE_SEARCH_COLORS 0x86
#define OPT_CHUNKSIZE 0x87
// Will be replaced with the actual name and location of the executable (if found)
string executableName = "minetestmapper";
@ -96,9 +97,10 @@ void usage()
#if USE_SQLITE3
" --sqlite-cacheworldrow\n"
#endif
" --tiles <tilesize>[+<border>]\n"
" --tiles <tilesize>[+<border>]|block|chunk\n"
" --tileorigin <x>,<y>|world|map\n"
" --tilecenter <x>,<y>|world|map\n"
" --chunksize <size>\n"
" --verbose[=n]\n"
" --verbose-search-colors[=n]\n"
" --progress\n"
@ -556,6 +558,7 @@ int main(int argc, char *argv[])
{"tileorigin", required_argument, 0, 'T'},
{"tilecenter", required_argument, 0, 'T'},
{"tilebordercolor", required_argument, 0, 'B'},
{"chunksize", required_argument, 0, OPT_CHUNKSIZE},
{"verbose", optional_argument, 0, 'v'},
{"verbose-search-colors", optional_argument, 0, OPT_VERBOSE_SEARCH_COLORS},
{"progress", no_argument, 0, OPT_PROGRESS_INDICATOR},
@ -696,9 +699,31 @@ int main(int argc, char *argv[])
generator.setMaxY(maxy);
}
break;
case OPT_CHUNKSIZE : {
istringstream iss;
iss.str(optarg);
int size;
iss >> size;
if (iss.fail() || size < 0) {
std::cerr << "Invalid chunk size (" << optarg << ")" << std::endl;
usage();
exit(1);
}
generator.setChunkSize(size);
}
break;
case 't': {
istringstream tilesize;
tilesize.str(optarg);
if (tilesize.str() == "block") {
generator.setTileSize(BLOCK_SIZE, BLOCK_SIZE);
generator.setTileOrigin(TILECORNER_AT_WORLDCENTER, TILECORNER_AT_WORLDCENTER);
}
else if (tilesize.str() == "chunk") {
generator.setTileSize(TILESIZE_CHUNK, TILESIZE_CHUNK);
generator.setTileOrigin(TILECENTER_AT_CHUNKCENTER, TILECENTER_AT_CHUNKCENTER);
}
else {
int size, border;
char c;
tilesize >> size;
@ -718,6 +743,7 @@ int main(int argc, char *argv[])
generator.setTileBorderSize(border);
}
}
}
break;
case 'T': {
bool origin = long_options[option_index].name[4] == 'o';