Allow reading heightmap colors from file, and use separate option for nodes file
This commit is contained in:
parent
3812e31fc9
commit
4476de429d
@ -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)
|
||||
|
@ -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,54 +495,10 @@ void TileGenerator::parseColorsStream(std::istream &in, const std::string &filen
|
||||
}
|
||||
}
|
||||
#endif
|
||||
parseColorsFile(includeFile, depth + 1);
|
||||
}
|
||||
else 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;
|
||||
}
|
||||
m_colors.erase(name);
|
||||
parseDataFile(includeFile, depth + 1, type, parseLine);
|
||||
}
|
||||
else {
|
||||
int r, g, b, a, t;
|
||||
iline >> r;
|
||||
iline >> g;
|
||||
iline >> b;
|
||||
if (iline.fail()) {
|
||||
std::cerr << filename << ":" << linenr << ": bad line in colors file (" << line << ")" << std::endl;
|
||||
continue;
|
||||
}
|
||||
a = 0xff;
|
||||
iline >> a;
|
||||
t = 0;
|
||||
iline >> t;
|
||||
color = ColorEntry(r,g,b,a,t);
|
||||
if ((m_drawAlpha && a == 0xff) || (!m_drawAlpha && a != 0xff)) {
|
||||
// If drawing alpha, and the colors file contains both
|
||||
// an opaque entry and a non-opaque entry for a name, prefer
|
||||
// the non-opaque entry
|
||||
// If not drawing alpha, and the colors file contains both
|
||||
// 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()) {
|
||||
if (m_drawAlpha && (a == 0xff && it->second.a != 0xff)) {
|
||||
// drawing alpha: don't use opaque color to override
|
||||
// non-opaque color
|
||||
continue;
|
||||
}
|
||||
if (!m_drawAlpha && (a != 0xff && it->second.a == 0xff)) {
|
||||
// not drawing alpha: don't use non-opaque color to
|
||||
// override opaque color
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_colors[name] = color;
|
||||
(this->*parseLine)(line, name, iline, linenr, filename);
|
||||
}
|
||||
}
|
||||
if (!in.eof()) {
|
||||
@ -542,6 +506,128 @@ void TileGenerator::parseColorsStream(std::istream &in, const std::string &filen
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
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;
|
||||
return;
|
||||
}
|
||||
a = 0xff;
|
||||
iline >> a;
|
||||
t = 0;
|
||||
iline >> t;
|
||||
color = ColorEntry(r,g,b,a,t);
|
||||
if ((m_drawAlpha && a == 0xff) || (!m_drawAlpha && a != 0xff)) {
|
||||
// If drawing alpha, and the colors file contains both
|
||||
// an opaque entry and a non-opaque entry for a name, prefer
|
||||
// the non-opaque entry
|
||||
// If not drawing alpha, and the colors file contains both
|
||||
// an opaque entry and a non-opaque entry for a name, prefer
|
||||
// the opaque entry
|
||||
// Otherwise, any later entry overrides any previous entry
|
||||
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
|
||||
return;
|
||||
}
|
||||
if (!m_drawAlpha && (a != 0xff && it->second.a == 0xff)) {
|
||||
// not drawing alpha: don't use non-opaque color to
|
||||
// override opaque color
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_nodeColors[name] = color;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
std::string TileGenerator::getWorldDatabaseBackend(const std::string &input)
|
||||
{
|
||||
string backend;
|
||||
@ -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 {
|
||||
@ -1306,7 +1393,7 @@ void TileGenerator::renderMap()
|
||||
cout << "Statistics"
|
||||
<< ": blocks read: " << m_db->getBlocksReadCount()
|
||||
<< " (" << m_db->getBlocksCachedCount() << " cached + "
|
||||
<< m_db->getBlocksUnCachedCount() << " uncached)"
|
||||
<< m_db->getBlocksUnCachedCount() << " uncached)"
|
||||
<< "; blocks rendered: " << blocks_rendered
|
||||
<< "; area rendered: " << area_rendered
|
||||
<< "/" << (m_xMax-m_xMin+1) * (m_zMax-m_zMin+1)
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
@ -143,21 +147,21 @@ private:
|
||||
void createImage();
|
||||
void computeMapParameters(const std::string &input);
|
||||
void computeTileParameters(
|
||||
// Input parameters
|
||||
int minPos,
|
||||
int maxPos,
|
||||
int mapStartNodeOffset,
|
||||
int mapEndNodeOffset,
|
||||
int tileOrigin,
|
||||
int tileSize,
|
||||
// Input / Output parameters
|
||||
int &pictSize,
|
||||
// Output parameters
|
||||
int &tileBorderCount,
|
||||
int &tileMapOffset,
|
||||
int &tileMapExcess,
|
||||
// Behavior selection
|
||||
bool ascending);
|
||||
// Input parameters
|
||||
int minPos,
|
||||
int maxPos,
|
||||
int mapStartNodeOffset,
|
||||
int mapEndNodeOffset,
|
||||
int tileOrigin,
|
||||
int tileSize,
|
||||
// Input / Output parameters
|
||||
int &pictSize,
|
||||
// Output parameters
|
||||
int &tileBorderCount,
|
||||
int &tileMapOffset,
|
||||
int &tileMapExcess,
|
||||
// Behavior selection
|
||||
bool ascending);
|
||||
void renderMap();
|
||||
std::list<int> getZValueList() const;
|
||||
void pushPixelRows(int zPosLimit);
|
||||
@ -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;
|
||||
|
1130
colors-heightmap.txt
1130
colors-heightmap.txt
File diff suppressed because it is too large
Load Diff
25
heightmap-colors.txt
Normal file
25
heightmap-colors.txt
Normal 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
1130
heightmap-nodes.txt
Normal file
File diff suppressed because it is too large
Load Diff
98
mapper.cpp
98
mapper.cpp
@ -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);
|
||||
break;
|
||||
case OPT_HEIGHTMAPGREY:
|
||||
generator.setHeightMap(true, true);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user