Allow reading heightmap colors from file, and use separate option for nodes file

This commit is contained in:
Rogier 2015-02-15 08:45:28 +01:00
parent 3812e31fc9
commit 4476de429d
7 changed files with 1443 additions and 1270 deletions

View File

@ -296,7 +296,8 @@ if(WIN32)
install(FILES ${META_FILES} DESTINATION ".")
install(FILES "colors.txt" DESTINATION ".")
install(FILES "colors-heightmap.txt" DESTINATION ".")
install(FILES "heightmap-nodes.txt" DESTINATION ".")
install(FILES "heightmap-colors.txt" DESTINATION ".")
install(FILES "colors-average-alpha.txt" DESTINATION ".")
install(FILES "colors-cumulative-alpha.txt" DESTINATION ".")
install(PROGRAMS "${PROJECT_BINARY_DIR}/minetestmapper.exe" DESTINATION ".")
@ -319,7 +320,8 @@ elseif(CREATE_FLAT_PACKAGE)
install(FILES ${META_FILES} DESTINATION ".")
install(FILES "colors.txt" DESTINATION ".")
install(FILES "colors-heightmap.txt" DESTINATION ".")
install(FILES "heightmap-nodes.txt" DESTINATION ".")
install(FILES "heightmap-colors.txt" DESTINATION ".")
install(FILES "colors-average-alpha.txt" DESTINATION ".")
install(FILES "colors-cumulative-alpha.txt" DESTINATION ".")
install(PROGRAMS "${PROJECT_BINARY_DIR}/minetestmapper" DESTINATION ".")
@ -354,7 +356,8 @@ else(WIN32)
install(FILES ${META_FILES} DESTINATION "share/doc/${PROJECT_NAME}" COMPONENT mapper)
install(FILES colors.txt DESTINATION "share/games/${PROJECT_NAME}" COMPONENT mapper)
install(FILES colors-heightmap.txt DESTINATION "share/games/${PROJECT_NAME}" COMPONENT mapper)
install(FILES heightmap-nodes.txt DESTINATION "share/games/${PROJECT_NAME}" COMPONENT mapper)
install(FILES heightmap-colors.txt DESTINATION "share/games/${PROJECT_NAME}" COMPONENT mapper)
install(FILES colors-average-alpha.txt DESTINATION "share/games/${PROJECT_NAME}" COMPONENT mapper)
install(FILES colors-cumulative-alpha.txt DESTINATION "share/games/${PROJECT_NAME}" COMPONENT mapper)
install(TARGETS minetestmapper RUNTIME DESTINATION bin COMPONENT mapper)

View File

@ -133,7 +133,6 @@ TileGenerator::TileGenerator():
verboseStatistics(false),
progressIndicator(false),
m_heightMap(false),
m_heightMapGrey(false),
m_heightMapYScale(1),
m_seaLevel(0),
m_bgColor(255, 255, 255),
@ -180,39 +179,19 @@ TileGenerator::TileGenerator():
m_tileMapXOffset(0),
m_tileMapYOffset(0)
{
// Load default grey colors.
m_heightMapColors.push_back(HeightMapColor(INT_MIN, Color(0,0,0), -129, Color(0,0,0)));
m_heightMapColors.push_back(HeightMapColor(-128, Color(0,0,0), 127, Color(255,255,255)));
m_heightMapColors.push_back(HeightMapColor(128, Color(255,255,255), INT_MAX, Color(255,255,255)));
}
TileGenerator::~TileGenerator()
{
}
void TileGenerator::setHeightMap(bool enable, bool grey)
void TileGenerator::setHeightMap(bool enable)
{
m_heightMap = enable;
m_heightMapGrey = grey;
m_heightMapColors.clear();
if (m_heightMapGrey) {
m_heightMapColors.push_back(HeightMapColor(INT_MIN, Color(0,0,0), -1, Color(0,0,0)));
m_heightMapColors.push_back(HeightMapColor(0, Color(0,0,0), 255, Color(255,255,255)));
m_heightMapColors.push_back(HeightMapColor(256, Color(255,255,255), INT_MAX, Color(255,255,255)));
}
else {
m_heightMapColors.push_back(HeightMapColor(INT_MIN, Color(4,4,4), -60, Color(4,4,4)));
m_heightMapColors.push_back(HeightMapColor(-60, Color(4,4,4), -45, Color(16,16,16)));
m_heightMapColors.push_back(HeightMapColor(-45, Color(16,16,16), -30, Color(16,32,64)));
m_heightMapColors.push_back(HeightMapColor(-30, Color(16,32,64), 0, Color(32,64,255)));
m_heightMapColors.push_back(HeightMapColor(1, Color(32,128,32), 10, Color(64,192,64))); // Green
m_heightMapColors.push_back(HeightMapColor(10, Color(64,192,64), 20, Color(192,192,64))); // Green -> Yellow
m_heightMapColors.push_back(HeightMapColor(20, Color(192,192,64), 40, Color(128,128,64))); // Yellow
m_heightMapColors.push_back(HeightMapColor(40, Color(128,128,64), 50, Color(128,64,64))); // Yellow -> Red
m_heightMapColors.push_back(HeightMapColor(50, Color(128,64,64), 70, Color(64,32,32))); // Red
m_heightMapColors.push_back(HeightMapColor(70, Color(64,32,32), 80, Color(48,48,48))); // Red -> Grey
m_heightMapColors.push_back(HeightMapColor(80, Color(48,48,48), 140, Color(96,96,96))); // Grey
// Above 100, white suggests snowy :-)
m_heightMapColors.push_back(HeightMapColor(141, Color(160,160,160), 250, Color(250,250,250))); // Grey -> White
m_heightMapColors.push_back(HeightMapColor(250, Color(250,250,250), INT_MAX, Color(250,250,250)));
}
}
void TileGenerator::setHeightMapYScale(float scale)
@ -267,6 +246,14 @@ void TileGenerator::setPlayerColor(const Color &playerColor)
m_playerColor = playerColor;
}
void TileGenerator::setHeightMapColor(const Color &color0, const Color &color1)
{
m_heightMapColors.clear();
m_heightMapColors.push_back(HeightMapColor(INT_MIN, color0, -129, color0));
m_heightMapColors.push_back(HeightMapColor(-128, color0, 127, color1));
m_heightMapColors.push_back(HeightMapColor(128, color1, INT_MAX, color1));
}
void TileGenerator::setTileBorderColor(const Color &tileBorderColor)
{
m_tileBorderColor = tileBorderColor;
@ -389,21 +376,41 @@ void TileGenerator::setMaxY(int y)
m_reqYMaxNode = y - 16 * m_reqYMax;
}
void TileGenerator::parseColorsFile(const std::string &fileName, int depth)
void TileGenerator::parseNodeColorsFile(const std::string &fileName)
{
m_nodeColors.clear();
parseDataFile(fileName, 0, "map colors", &TileGenerator::parseNodeColorsLine);
}
void TileGenerator::parseHeightMapNodesFile(const std::string &fileName)
{
m_nodeColors.clear();
parseDataFile(fileName, 0, "heightmap nodes", &TileGenerator::parseHeightMapNodesLine);
}
void TileGenerator::parseHeightMapColorsFile(const std::string &fileName)
{
m_heightMapColors.clear();
parseDataFile(fileName, 0, "heightmap colors", &TileGenerator::parseHeightMapColorsLine);
}
void TileGenerator::parseDataFile(const std::string &fileName, int depth, const char *type,
void (TileGenerator::*parseLine)(const std::string &line, std::string name,
istringstream &iline, int linenr, const std::string &filename))
{
if (depth > 100)
throw std::runtime_error(std::string("Excessive inclusion depth of colors files - suspected recursion (i.e. cycle); current file: '") + fileName + "'");
throw std::runtime_error(std::string("Excessive inclusion depth of ") + type + " files - suspected recursion (i.e. cycle); current file: '" + fileName + "'");
if (depth == 0 && verboseReadColors >= 2)
cout << "Checking for colors file: " << fileName << std::endl;
cout << "Checking for " << type << " file: " << fileName << std::endl;
ifstream in;
in.open(fileName.c_str(), ifstream::in);
if (!in.is_open()) {
throw std::runtime_error(std::string("Failed to open colors file '") + fileName + "'");
throw std::runtime_error(std::string("Failed to open ") + type + " file '" + fileName + "'");
return;
}
if (verboseReadColors >= 1)
cout << "Reading colors file: " << fileName << std::endl;
parseColorsStream(in, fileName.c_str(), depth);
cout << "Reading " << type << " file: " << fileName << std::endl;
parseDataStream(in, fileName, depth, type, parseLine);
in.close();
}
@ -449,7 +456,9 @@ void TileGenerator::generate(const std::string &input, const std::string &output
printUnknown();
}
void TileGenerator::parseColorsStream(std::istream &in, const std::string &filename, int depth)
void TileGenerator::parseDataStream(std::istream &in, const std::string &filename, int depth, const char *type,
void (TileGenerator::*parseLine)(const std::string &line, std::string name,
istringstream &iline, int linenr, const std::string &filename))
{
string line;
int linenr = 0;
@ -462,7 +471,6 @@ void TileGenerator::parseColorsStream(std::istream &in, const std::string &filen
iline.str(line);
iline >> std::skipws;
string name;
ColorEntry color;
iline >> name >> std::ws;
if (name.length() == 0)
continue;
@ -487,25 +495,37 @@ void TileGenerator::parseColorsStream(std::istream &in, const std::string &filen
}
}
#endif
parseColorsFile(includeFile, depth + 1);
parseDataFile(includeFile, depth + 1, type, parseLine);
}
else if (iline.good() && iline.peek() == '-') {
else {
(this->*parseLine)(line, name, iline, linenr, filename);
}
}
if (!in.eof()) {
std::cerr << filename << ": error reading colors file after line " << linenr << std::endl;
}
}
void TileGenerator::parseNodeColorsLine(const std::string &line, std::string name, istringstream &iline, int linenr, const std::string &filename)
{
if (iline.good() && iline.peek() == '-') {
char c;
iline >> c >> std::ws;
if (iline.bad() || !iline.eof()) {
std::cerr << filename << ":" << linenr << ": bad line in colors file (" << line << ")" << std::endl;
continue;
return;
}
m_colors.erase(name);
m_nodeColors.erase(name);
}
else {
int r, g, b, a, t;
ColorEntry color;
iline >> r;
iline >> g;
iline >> b;
if (iline.fail()) {
std::cerr << filename << ":" << linenr << ": bad line in colors file (" << line << ")" << std::endl;
continue;
return;
}
a = 0xff;
iline >> a;
@ -520,25 +540,91 @@ void TileGenerator::parseColorsStream(std::istream &in, const std::string &filen
// an opaque entry and a non-opaque entry for a name, prefer
// the opaque entry
// Otherwise, any later entry overrides any previous entry
ColorMap::iterator it = m_colors.find(name);
if (it != m_colors.end()) {
NodeColorMap::iterator it = m_nodeColors.find(name);
if (it != m_nodeColors.end()) {
if (m_drawAlpha && (a == 0xff && it->second.a != 0xff)) {
// drawing alpha: don't use opaque color to override
// non-opaque color
continue;
return;
}
if (!m_drawAlpha && (a != 0xff && it->second.a == 0xff)) {
// not drawing alpha: don't use non-opaque color to
// override opaque color
continue;
return;
}
}
}
m_colors[name] = color;
m_nodeColors[name] = color;
}
}
if (!in.eof()) {
std::cerr << filename << ": error reading colors file after line " << linenr << std::endl;
void TileGenerator::parseHeightMapColorsLine(const std::string &line, std::string name, istringstream &iline, int linenr, const std::string &filename)
{
(void) name;
int height[2];
Color color[2];
iline.str(line); // Reset
for (int i = 0; i < 2; i++) {
iline >> std::ws;
char c = iline.peek();
iline >> height[i];
if (iline.fail()) {
std::string value;
iline.clear();
iline >> std::ws;
iline >> value >> std::ws;
if (iline.good()) {
if (value == "-oo" || (c == '-' && value=="oo"))
height[i] = INT_MIN;
else if (value == "oo" || value == "+oo")
height[i] = INT_MAX;
else {
iline.clear(ios::failbit); // Set to failed
break;
}
}
}
}
for (int i = 0; i < 2; i++) {
int r, g, b;
iline >> r;
iline >> g;
iline >> b;
color[i] = Color(r,g,b);
}
if (height[0] > height[1]) {
{
int tmp = height[0];
height[0] = height[1];
height[1] = tmp;
}
{
Color tmp = color[0];
color[0] = color[1];
color[1] = tmp;
}
}
iline >> std::ws;
if (iline.fail() || !iline.eof()) {
std::cerr << filename << ":" << linenr << ": bad line in heightmap colors file (" << line << ")" << std::endl;
return;
}
m_heightMapColors.push_back(HeightMapColor(height[0], color[0], height[1], color[1]));
}
void TileGenerator::parseHeightMapNodesLine(const std::string &line, std::string name, istringstream &iline, int linenr, const std::string &filename)
{
if (name == "-") {
iline >> std::ws >> name >> std::ws;
m_nodeColors.erase(name);
}
else {
m_nodeColors[name] = ColorEntry(0,0,0,255,1); // Dummy entry - but must not be transparent
}
// Don't care if not at eof (== really eol). We might be reading a colors.txt file...
if (iline.bad()) {
std::cerr << filename << ":" << linenr << ": bad line in heightmap nodes file (" << line << ")" << std::endl;
return;
}
}
@ -1201,15 +1287,16 @@ void TileGenerator::processMapBlock(const DB::Block &block)
size_t end = name.find_first_of('\0');
if (end != std::string::npos)
name.erase(end);
ColorMap::const_iterator color = m_colors.find(name);
if (name == "air" && !(m_drawAir && color != m_colors.end())) {
// In case of a height map, it stores just dummy colors...
NodeColorMap::const_iterator color = m_nodeColors.find(name);
if (name == "air" && !(m_drawAir && color != m_nodeColors.end())) {
m_nodeIDColor[nodeId] = NodeColorNotDrawn;
}
else if (name == "ignore") {
m_nodeIDColor[nodeId] = NodeColorNotDrawn;
}
else {
if (color != m_colors.end()) {
if (color != m_nodeColors.end()) {
m_nodeIDColor[nodeId] = &color->second;
}
else {
@ -1357,7 +1444,7 @@ inline void TileGenerator::renderMapBlock(const ustring &mapBlock, const BlockPo
float g = 0;
float b = 0;
int n = 0;
for (std::list<HeightMapColor>::iterator i = m_heightMapColors.begin(); i != m_heightMapColors.end(); i++) {
for (HeightMapColorList::iterator i = m_heightMapColors.begin(); i != m_heightMapColors.end(); i++) {
HeightMapColor &colorSpec = *i;
if (adjustedHeight >= colorSpec.height[0] && adjustedHeight <= colorSpec.height[1]) {
float weight = (float) (colorSpec.height[1] - adjustedHeight + 1) / (colorSpec.height[1] - colorSpec.height[0] + 1);

View File

@ -23,7 +23,8 @@
#include <list>
#include <stdint.h>
#include <string>
#include <string>
#include <iostream>
#include <sstream>
#include "types.h"
#include "PixelAttributes.h"
#include "BlockPos.h"
@ -51,10 +52,10 @@ class TileGenerator
{
private:
#if __cplusplus >= 201103L
typedef std::unordered_map<std::string, ColorEntry> ColorMap;
typedef std::unordered_map<std::string, ColorEntry> NodeColorMap;
typedef std::unordered_map<int, std::string> NodeID2NameMap;
#else
typedef std::map<std::string, ColorEntry> ColorMap;
typedef std::map<std::string, ColorEntry> NodeColorMap;
typedef std::map<int, std::string> NodeID2NameMap;
#endif
public:
@ -64,6 +65,7 @@ public:
int height[2];
Color color[2];
};
typedef std::list<HeightMapColor> HeightMapColorList;
struct DrawObject {
void setCenter(const NodeCoord &c) { haveCenter = true; center = c; }
void setCorner1(const NodeCoord &c) { haveCenter = false; corner1 = c; }
@ -101,7 +103,7 @@ public:
TileGenerator();
~TileGenerator();
void setHeightMap(bool enable, bool grey);
void setHeightMap(bool enable);
void setHeightMapYScale(float scale);
void setSeaLevel(int level);
void setBgColor(const Color &bgColor);
@ -109,6 +111,7 @@ public:
void setScaleColor(const Color &scaleColor);
void setOriginColor(const Color &originColor);
void setPlayerColor(const Color &playerColor);
void setHeightMapColor(const Color &color0, const Color &color1);
Color parseColor(const Color &color);
void setDrawOrigin(bool drawOrigin);
void setDrawPlayers(bool drawPlayers);
@ -129,13 +132,14 @@ public:
void setTileOrigin(int x, int y);
void setTileCenter(int x, int y);
void enableProgressIndicator(void);
void parseColorsFile(const std::string &fileName, int depth = 0);
void parseNodeColorsFile(const std::string &fileName);
void parseHeightMapNodesFile(const std::string &fileName);
void parseHeightMapColorsFile(const std::string &fileName);
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);
@ -180,6 +184,19 @@ private:
int borderLeft() const { return ((m_drawScale & DRAWSCALE_LEFT) ? SCALESIZE_VERT : 0); }
int borderRight() const { return ((m_drawScale & DRAWSCALE_RIGHT) ? SCALESIZE_VERT : 0); }
void parseDataFile(const std::string &fileName, int depth, const char *type,
void (TileGenerator::*parseLine)(const std::string &line, std::string name,
std::istringstream &iline, int linenr, const std::string &filename));
void parseDataStream(std::istream &in, const std::string &filename, int depth, const char *type,
void (TileGenerator::*parseLine)(const std::string &line, std::string name,
std::istringstream &iline, int linenr, const std::string &filename));
void parseNodeColorsLine(const std::string &line, std::string name, std::istringstream &iline,
int linenr, const std::string &filename);
void parseHeightMapNodesLine(const std::string &line, std::string name, std::istringstream &iline,
int linenr, const std::string &filename);
void parseHeightMapColorsLine(const std::string &line, std::string name, std::istringstream &iline,
int linenr, const std::string &filename);
public:
int verboseCoordinates;
int verboseReadColors;
@ -188,10 +205,8 @@ public:
private:
bool m_heightMap;
bool m_heightMapGrey;
float m_heightMapYScale;
int m_seaLevel;
std::list<HeightMapColor> m_heightMapColors;
Color m_bgColor;
Color m_blockDefaultColor;
Color m_scaleColor;
@ -250,7 +265,8 @@ private:
NodeID2NameMap m_nameMap;
static const ColorEntry *NodeColorNotDrawn;
const ColorEntry *m_nodeIDColor[MAPBLOCK_MAXCOLORS];
ColorMap m_colors;
NodeColorMap m_nodeColors;
HeightMapColorList m_heightMapColors;
uint16_t m_readedPixels[16];
std::set<std::string> m_unknownNodes;
std::vector<DrawObject> m_drawObjects;

File diff suppressed because it is too large Load Diff

25
heightmap-colors.txt Normal file
View File

@ -0,0 +1,25 @@
# The colors in this file were primarily chosen so that they make a standard
# minetest world look good.
# Secondarily, they were chosen to span as large a height-range as possible.
-oo -150 4 4 4 4 4 4 # Almost black
-150 -90 4 4 4 48 16 48 # Dark purple -> almost black
-90 -60 48 16 48 16 32 64 # Dark blue -> dark purple
-60 0 16 32 64 32 64 255 # Light blue -> dark blue
# The green, yellow and red-ish colors could be spread over a much
# greater height range, but using these parameters, a map of a regular
# world contains some yellow, and even red-ish as well
# See below
1 10 32 128 32 64 192 64 # Green -> Yellow-ish
10 20 64 192 64 192 192 64 # Yellow-ish -> Yellow
20 40 192 192 64 128 128 64 # Yellow -> dark yellow
40 50 128 128 64 128 64 64 # Dark yellow -> red-ish
50 70 128 64 64 64 32 32 # Red-ish -> dark red-ish
70 80 64 32 32 48 48 48 # Dark red-ish -> dark grey
80 140 48 48 48 96 96 96 # Dark grey -> less dark gray
# Above 140, white suggests snowy :-)
141 250 160 160 160 250 250 250 # Light gray -> almost white
250 oo 250 250 250 250 250 250 # Almost white

1130
heightmap-nodes.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -32,15 +32,17 @@ using namespace std;
#define OPT_VERBOSE_SEARCH_COLORS 0x86
#define OPT_CHUNKSIZE 0x87
#define OPT_HEIGHTMAP 0x88
#define OPT_HEIGHTMAPGREY 0x89
#define OPT_HEIGHTMAPYSCALE 0x8a
#define OPT_HEIGHT_LEVEL0 0x8b
#define OPT_HEIGHTMAPYSCALE 0x89
#define OPT_HEIGHT_LEVEL0 0x8a
#define OPT_HEIGHTMAPNODESFILE 0x8b
#define OPT_HEIGHTMAPCOLORSFILE 0x8c
// Will be replaced with the actual name and location of the executable (if found)
string executableName = "minetestmapper";
string installPrefix = INSTALL_PREFIX;
string colorsDefaultName = "colors.txt";
string nodeColorsDefaultFile = "colors.txt";
string heightMapNodesDefaultFile = "heightmap-nodes.txt";
string heightMapColorsDefaultFile = "heightmap-colors.txt";
class FuzzyBool {
private:
@ -71,9 +73,11 @@ void usage()
" -i/--input <world_path>\n"
" -o/--output <output_image.png>\n"
" --colors <file>\n"
" --heightmap[-grey]\n"
" --heightmap-scale <scale>\n"
" --heightmap-nodes <file>\n"
" --heightmap-colors[=<file>]\n"
" --height-level-0 <level>\n"
" --heightmap[=<color>]\n"
" --heightmap-yscale <scale>\n"
" --bgcolor <color>\n"
" --blockcolor <color>\n"
" --scalecolor <color>\n"
@ -139,9 +143,11 @@ void usage()
std::cout << executableName << ' ' << options_text;
}
void parseColorsFile(TileGenerator &generator, const string &input, string colorsFile) {
if (!colorsFile.empty()) {
generator.parseColorsFile(colorsFile);
void parseDataFile(TileGenerator &generator, const string &input, string dataFile, string defaultFile,
void (TileGenerator::*parseFile)(const std::string &fileName))
{
if (!dataFile.empty()) {
(generator.*parseFile)(dataFile);
return;
}
@ -170,17 +176,17 @@ void parseColorsFile(TileGenerator &generator, const string &input, string color
}
colorPaths.push_back("");
std::vector<std::string> colorFileNames;
colorFileNames.push_back(colorsDefaultName);
std::vector<std::string> fileNames;
fileNames.push_back(defaultFile);
for (std::vector<std::string>::iterator path = colorPaths.begin(); path != colorPaths.end(); path++) {
for (std::vector<std::string>::iterator name = colorFileNames.begin(); name != colorFileNames.end(); name++) {
for (std::vector<std::string>::iterator name = fileNames.begin(); name != fileNames.end(); name++) {
if (path->empty())
colorsFile = *name;
dataFile = *name;
else
colorsFile = *path + PATH_SEPARATOR + *name;
dataFile = *path + PATH_SEPARATOR + *name;
try {
generator.parseColorsFile(colorsFile);
(generator.*parseFile)(dataFile);
if (path->empty()) {
// I hope this is not obnoxious to windows users ?
cerr << "Warning: Using " << *name << " in current directory as a last resort." << std::endl
@ -199,7 +205,9 @@ void parseColorsFile(TileGenerator &generator, const string &input, string color
}
}
throw std::runtime_error("Failed to find or failed to open a colors.txt file.");
ostringstream oss;
oss << "Failed to find or failed to open a " << defaultFile << " file.";
throw std::runtime_error(oss.str().c_str());
}
// is: stream to read from
@ -530,10 +538,10 @@ int main(int argc, char *argv[])
{"input", required_argument, 0, 'i'},
{"output", required_argument, 0, 'o'},
{"colors", required_argument, 0, 'C'},
{"heightmap", no_argument, 0, OPT_HEIGHTMAP},
{"heightmap-grey", no_argument, 0, OPT_HEIGHTMAPGREY},
{"heightmap-gray", no_argument, 0, OPT_HEIGHTMAPGREY},
{"heightmap-scale", required_argument, 0, OPT_HEIGHTMAPYSCALE},
{"heightmap-nodes", required_argument, 0, OPT_HEIGHTMAPNODESFILE},
{"heightmap-colors", required_argument, 0, OPT_HEIGHTMAPCOLORSFILE},
{"heightmap", optional_argument, 0, OPT_HEIGHTMAP},
{"heightmap-yscale", required_argument, 0, OPT_HEIGHTMAPYSCALE},
{"height-level-0", required_argument, 0, OPT_HEIGHT_LEVEL0},
{"bgcolor", required_argument, 0, 'b'},
{"blockcolor", required_argument, 0, OPT_BLOCKCOLOR},
@ -580,7 +588,11 @@ int main(int argc, char *argv[])
string input;
string output;
string colorsFile;
bool heightMap = false;
bool loadHeightMapColorsFile = false;
string nodeColorsFile;
string heightMapColorsFile;
string heightMapNodesFile;
bool foundGeometrySpec = false;
bool setFixedOrShrinkGeometry = false;
@ -614,16 +626,39 @@ int main(int argc, char *argv[])
output = optarg;
break;
case 'C':
colorsFile = optarg;
nodeColorsFile = optarg;
break;
case OPT_HEIGHTMAPNODESFILE:
heightMapNodesFile = optarg;
break;
case OPT_HEIGHTMAPCOLORSFILE:
heightMapColorsFile = optarg;
break;
case 'b':
generator.setBgColor(Color(optarg, 0));
break;
case OPT_HEIGHTMAP:
generator.setHeightMap(true, false);
generator.setHeightMap(true);
heightMap = true;
if (optarg && *optarg) {
loadHeightMapColorsFile = false;
std::string color = optarg;
int l = color.length();
for (int i = 0; i < l; i++)
color[i] = tolower(color[i]);
if (color == "grey" || color == "gray")
generator.setHeightMapColor(Color(0, 0, 0), Color(255, 255, 255));
else if (color == "black")
generator.setHeightMapColor(Color(0, 0, 0), Color(0, 0, 0));
else if (color == "white")
generator.setHeightMapColor(Color(255, 255, 255), Color(255, 255, 255));
else
generator.setHeightMapColor(Color(0, 0, 0), Color(color, 0));
break;
case OPT_HEIGHTMAPGREY:
generator.setHeightMap(true, true);
}
else {
loadHeightMapColorsFile = true;
}
break;
case OPT_HEIGHTMAPYSCALE:
if (isdigit(optarg[0]) || ((optarg[0]=='-' || optarg[0]=='+') && isdigit(optarg[1]))) {
@ -1053,7 +1088,14 @@ int main(int argc, char *argv[])
}
try {
parseColorsFile(generator, input, colorsFile);
if (heightMap) {
parseDataFile(generator, input, heightMapNodesFile, heightMapNodesDefaultFile, &TileGenerator::parseHeightMapNodesFile);
if (loadHeightMapColorsFile)
parseDataFile(generator, input, heightMapColorsFile, heightMapColorsDefaultFile, &TileGenerator::parseHeightMapColorsFile);
}
else {
parseDataFile(generator, input, nodeColorsFile, nodeColorsDefaultFile, &TileGenerator::parseNodeColorsFile);
}
generator.generate(input, output);
} catch(std::runtime_error e) {
std::cout<<"Exception: "<<e.what()<<std::endl;