mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 08:03:45 +01:00
New math mapgen with fractal based worlds
This commit is contained in:
parent
f960c3be31
commit
75b8c13b00
@ -325,7 +325,7 @@
|
||||
# Mapgen stuff
|
||||
#
|
||||
|
||||
# Name of map generator to be used. Currently v6, indev and singlenode are supported.
|
||||
# Name of map generator to be used. Currently supported: v6, indev, singlenode, math
|
||||
#mg_name = v6
|
||||
# Water level of map.
|
||||
#water_level = 1
|
||||
@ -368,6 +368,9 @@
|
||||
# Float islands starts from height, 0 to disable
|
||||
#mgindev_float_islands = 500
|
||||
|
||||
# Math mapgen generator: sphere, mandelbox, mengersponge dont forget to lower water_level = -30000
|
||||
#mgmath_generator = mandelbox
|
||||
|
||||
# Enable/disable IPv6
|
||||
#enable_ipv6 = true
|
||||
# Enable/disable running an IPv6 server. An IPv6 server may be restricted
|
||||
|
@ -233,6 +233,7 @@ set(common_SRCS
|
||||
mapgen_v7.cpp
|
||||
mapgen_indev.cpp
|
||||
mapgen_singlenode.cpp
|
||||
mapgen_math.cpp
|
||||
treegen.cpp
|
||||
dungeongen.cpp
|
||||
cavegen.cpp
|
||||
|
@ -251,7 +251,9 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("mgindev_np_float_islands3", "0, 1, (256, 256, 256), 6412, 2, 0.5, 1, 0.5");
|
||||
settings->setDefault("mgindev_np_biome", "0, 1, (250, 250, 250), 9130, 3, 0.50, 1, 10");
|
||||
settings->setDefault("mgindev_float_islands", "500");
|
||||
|
||||
|
||||
settings->setDefault("mgmath_generator", "mandelbox");
|
||||
|
||||
// IPv6
|
||||
settings->setDefault("enable_ipv6", "true");
|
||||
settings->setDefault("ipv6_server", "false");
|
||||
|
@ -42,6 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "mapgen_v7.h"
|
||||
#include "mapgen_indev.h"
|
||||
#include "mapgen_singlenode.h"
|
||||
#include "mapgen_math.h"
|
||||
|
||||
|
||||
/////////////////////////////// Emerge Manager ////////////////////////////////
|
||||
@ -52,6 +53,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef) {
|
||||
registerMapgen("v7", new MapgenFactoryV7());
|
||||
registerMapgen("indev", new MapgenFactoryIndev());
|
||||
registerMapgen("singlenode", new MapgenFactorySinglenode());
|
||||
registerMapgen("math", new MapgenFactoryMath());
|
||||
|
||||
this->ndef = gamedef->getNodeDefManager();
|
||||
this->biomedef = new BiomeDefManager();
|
||||
|
366
src/mapgen_math.cpp
Normal file
366
src/mapgen_math.cpp
Normal file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
Minetest
|
||||
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include "mapgen_math.h"
|
||||
#include "voxel.h"
|
||||
#include "mapblock.h"
|
||||
#include "mapnode.h"
|
||||
#include "map.h"
|
||||
#include "nodedef.h"
|
||||
#include "voxelalgorithms.h"
|
||||
#include "profiler.h"
|
||||
#include "settings.h" // For g_settings
|
||||
#include "main.h" // For g_profiler
|
||||
#include "emerge.h"
|
||||
#include "biome.h"
|
||||
|
||||
// can use ported lib from http://mandelbulber.googlecode.com/svn/trunk/src
|
||||
//#include "mandelbulber/fractal.h"
|
||||
//#include "mandelbulber/fractal.cpp"
|
||||
|
||||
double mandelbox(double x, double y, double z, double d, int nn = 10) {
|
||||
int s = 7;
|
||||
x *= s;
|
||||
y *= s;
|
||||
z *= s;
|
||||
d *= s;
|
||||
|
||||
double posX = x;
|
||||
double posY = y;
|
||||
double posZ = z;
|
||||
|
||||
double dr = 1.0;
|
||||
double r = 0.0;
|
||||
|
||||
double scale = 2;
|
||||
|
||||
double minRadius2 = 0.25;
|
||||
double fixedRadius2 = 1;
|
||||
|
||||
for (int n = 0; n < nn; n++) {
|
||||
// Reflect
|
||||
if (x > 1.0)
|
||||
x = 2.0 - x;
|
||||
else if (x < -1.0)
|
||||
x = -2.0 - x;
|
||||
if (y > 1.0)
|
||||
y = 2.0 - y;
|
||||
else if (y < -1.0)
|
||||
y = -2.0 - y;
|
||||
if (z > 1.0)
|
||||
z = 2.0 - z;
|
||||
else if (z < -1.0)
|
||||
z = -2.0 - z;
|
||||
|
||||
// Sphere Inversion
|
||||
double r2 = x * x + y * y + z * z;
|
||||
|
||||
if (r2 < minRadius2) {
|
||||
x = x * fixedRadius2 / minRadius2;
|
||||
y = y * fixedRadius2 / minRadius2;
|
||||
z = z * fixedRadius2 / minRadius2;
|
||||
dr = dr * fixedRadius2 / minRadius2;
|
||||
} else if (r2 < fixedRadius2) {
|
||||
x = x * fixedRadius2 / r2;
|
||||
y = y * fixedRadius2 / r2;
|
||||
z = z * fixedRadius2 / r2;
|
||||
fixedRadius2 *= fixedRadius2 / r2;
|
||||
}
|
||||
|
||||
x = x * scale + posX;
|
||||
y = y * scale + posY;
|
||||
z = z * scale + posZ;
|
||||
dr *= scale;
|
||||
}
|
||||
r = sqrt(x * x + y * y + z * z);
|
||||
return ((r / fabs(dr)) < d);
|
||||
|
||||
}
|
||||
|
||||
double mengersponge(double x, double y, double z, double d, int MI = 10) {
|
||||
|
||||
double r = x * x + y * y + z * z;
|
||||
double scale = 3;
|
||||
int i = 0;
|
||||
|
||||
|
||||
for (i = 0; i < MI && r < 9; i++) {
|
||||
|
||||
|
||||
x = fabs(x);
|
||||
y = fabs(y);
|
||||
z = fabs(z);
|
||||
|
||||
|
||||
if (x - y < 0) {
|
||||
double x1 = y;
|
||||
y = x;
|
||||
x = x1;
|
||||
}
|
||||
if (x - z < 0) {
|
||||
double x1 = z;
|
||||
z = x;
|
||||
x = x1;
|
||||
}
|
||||
if (y - z < 0) {
|
||||
double y1 = z;
|
||||
z = y;
|
||||
y = y1;
|
||||
}
|
||||
|
||||
|
||||
x = scale * x - 1 * (scale - 1);
|
||||
y = scale * y - 1 * (scale - 1);
|
||||
z = scale * z;
|
||||
|
||||
|
||||
if (z > 0.5 * 1 * (scale - 1))
|
||||
z -= 1 * (scale - 1);
|
||||
|
||||
|
||||
r = x * x + y * y + z * z;
|
||||
}
|
||||
return ((sqrt(r)) * pow(scale, (-i)) < d);
|
||||
}
|
||||
|
||||
double sphere(double x, double y, double z, double d, int ITR = 1) {
|
||||
return v3f(x, y, z).getLength() < d;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////// Mapgen Singlenode parameter read/write
|
||||
|
||||
bool MapgenMathParams::readParams(Settings *settings) {
|
||||
//params = settings->getJson("mg_math");
|
||||
// can be counfigured from here.
|
||||
std::string value = "{}";
|
||||
Json::Reader reader;
|
||||
if (!reader.parse( value, params ) ) {
|
||||
errorstream << "Failed to parse json conf var ='" << value << "' : " << reader.getFormattedErrorMessages();
|
||||
}
|
||||
|
||||
if (params["generator"].empty()) params["generator"] = settings->get("mgmath_generator");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MapgenMathParams::writeParams(Settings *settings) {
|
||||
//settings->setJson("mg_math", params);
|
||||
settings->set("mgmath_generator", params["generator"].asString());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MapgenMath::MapgenMath(int mapgenid, MapgenMathParams *params_, EmergeManager *emerge) : MapgenV7(mapgenid, params_, emerge) {
|
||||
mg_params = params_;
|
||||
|
||||
Json::Value & params = mg_params->params;
|
||||
invert = params["invert"].empty() ? 1 : params["invert"].asBool(); //params["invert"].empty()?1:params["invert"].asBool();
|
||||
size = params["size"].empty() ? 0 : params["size"].asDouble(); // = max_r
|
||||
scale = params["scale"].empty() ? 0 : params["scale"].asDouble(); //(double)1 / size;
|
||||
if(!params["center"].empty()) center = v3f(params["center"]["x"].asFloat(), params["center"]["y"].asFloat(), params["center"]["z"].asFloat()); //v3f(5, -size - 5, 5);
|
||||
iterations = params["iterations"].empty() ? 0 : params["iterations"].asInt(); //10;
|
||||
distance = params["distance"].empty() ? 0 : params["distance"].asDouble(); // = 1/size;
|
||||
|
||||
func = &sphere;
|
||||
|
||||
if (params["generator"].empty()) params["generator"] = "mandelbox";
|
||||
if (params["generator"].asString() == "mengersponge") {
|
||||
if (!size) size = (MAP_GENERATION_LIMIT - 1000) / 2;
|
||||
if (!iterations) iterations = 10;
|
||||
if (!distance) distance = 0.0003;
|
||||
//if (!scale) scale = (double)0.1 / size;
|
||||
//if (!distance) distance = 0.01; //10/size;//sqrt3 * bd4;
|
||||
//if (!scale) scale = 0.01; //10/size;//sqrt3 * bd4;
|
||||
//center=v3f(-size/3,-size/3+(-2*-invert),2);
|
||||
center = v3f(-size, -size, -size);
|
||||
func = &mengersponge;
|
||||
} else if (params["generator"].asString() == "mandelbox") {
|
||||
/*
|
||||
size = MAP_GENERATION_LIMIT - 1000;
|
||||
//size = 1000;
|
||||
distance = 0.01; //100/size; //0.01;
|
||||
iterations = 10;
|
||||
center = v3f(1, 1, 1); // *size/6;
|
||||
*/
|
||||
|
||||
//mandelbox
|
||||
if (!size) size = 1000;
|
||||
if (!distance) distance = 0.01;
|
||||
if(params["invert"].empty()) invert = 0;
|
||||
//center=v3f(2,-size/4,2);
|
||||
//size = 10000;
|
||||
//center=v3f(size/2,-size*0.9,size/2);
|
||||
if(params["center"].empty())center = v3f(size * 0.3, -size * 0.6, size * 0.5);
|
||||
func = &mandelbox;
|
||||
} else if (params["generator"].asString() == "sphere") {
|
||||
if(params["invert"].empty()) invert = 0;
|
||||
if (!size) size = 100;
|
||||
if (!distance) distance = size;
|
||||
func = &sphere;
|
||||
if (!scale) scale = 1;
|
||||
//sphere
|
||||
//size = 1000;scale = 1;center = v3f(2,-size-2,2);
|
||||
}
|
||||
|
||||
if (!iterations) iterations = 10;
|
||||
if (!size) size = 1000;
|
||||
if (!scale) scale = (double)1 / size;
|
||||
if (!distance) distance = scale;
|
||||
if (params["center"].empty() && !center.getLength()) center = v3f(3, -size + (-5 - (-invert * 10)), 3);
|
||||
//size ||= params["size"].empty()?1000:params["size"].asDouble(); // = max_r
|
||||
|
||||
}
|
||||
|
||||
|
||||
MapgenMath::~MapgenMath() {
|
||||
}
|
||||
|
||||
//////////////////////// Map generator
|
||||
|
||||
void MapgenMath::generateTerrain() {
|
||||
|
||||
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source, LIGHT_SUN);
|
||||
MapNode n_stone(c_stone, LIGHT_SUN);
|
||||
u32 index = 0;
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
|
||||
#if 1
|
||||
|
||||
/* debug
|
||||
v3f vec0 = (v3f(node_min.X, node_min.Y, node_min.Z) - center) * scale ;
|
||||
errorstream << " X=" << node_min.X << " Y=" << node_min.Y << " Z=" << node_min.Z
|
||||
//<< " N="<< mengersponge(vec0.X, vec0.Y, vec0.Z, distance, iterations)
|
||||
<< " N=" << (*func)(vec0.X, vec0.Y, vec0.Z, distance, iterations)
|
||||
<< " Sc=" << scale << " gen=" << params["generator"].asString() << " J=" << Json::FastWriter().write(params) << std::endl;
|
||||
*/
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++) {
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = bmgr->biomes[biomemap[index]];
|
||||
u32 i = vm->m_area.index(x, node_min.Y, z);
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
v3f vec = (v3f(x, y, z) - center) * scale ;
|
||||
double d = (*func)(vec.X, vec.Y, vec.Z, distance, iterations);
|
||||
if ((!invert && d > 0) || (invert && d == 0) ) {
|
||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE)
|
||||
vm->m_data[i] = (y > water_level + biome->filler_height) ?
|
||||
MapNode(biome->c_filler) : n_stone;
|
||||
} else if (y <= water_level) {
|
||||
vm->m_data[i] = n_water_source;
|
||||
} else {
|
||||
vm->m_data[i] = n_air;
|
||||
}
|
||||
vm->m_area.add_y(em, i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
// mandelbulber, unfinished but works
|
||||
sFractal par;
|
||||
par.doubles.N = 10;
|
||||
|
||||
par.doubles.power = 9.0;
|
||||
par.doubles.foldingSphericalFixed = 1.0;
|
||||
par.doubles.foldingSphericalMin = 0.5;
|
||||
//no par.formula = smoothMandelbox; par.doubles.N = 40; invert = 0;//no
|
||||
par.mandelbox.doubles.sharpness = 3.0;
|
||||
par.mandelbox.doubles.scale = 1;
|
||||
par.mandelbox.doubles.sharpness = 2;
|
||||
par.mandelbox.doubles.foldingLimit = 1.0;
|
||||
par.mandelbox.doubles.foldingValue = 2;
|
||||
|
||||
//ok par.formula = mandelboxVaryScale4D; par.doubles.N = 50; scale = 5; invert = 1; //ok
|
||||
par.mandelbox.doubles.vary4D.scaleVary = 0.1;
|
||||
par.mandelbox.doubles.vary4D.fold = 1;
|
||||
par.mandelbox.doubles.vary4D.rPower = 1;
|
||||
par.mandelbox.doubles.vary4D.minR = 0.5;
|
||||
par.mandelbox.doubles.vary4D.wadd = 0;
|
||||
par.doubles.constantFactor = 1.0;
|
||||
|
||||
par.formula = menger_sponge; par.doubles.N = 15; invert = 0; size = 30000; center = v3f(-size / 2, -size + (-2 * -invert), 2); scale = (double)1 / size; //ok
|
||||
|
||||
//double tresh = 1.5;
|
||||
//par.formula = mandelbulb2; par.doubles.N = 10; scale = (double)1/size; invert=1; center = v3f(5,-size-5,0); //ok
|
||||
//par.formula = hypercomplex; par.doubles.N = 20; scale = 0.0001; invert=1; center = v3f(0,-10001,0); //(double)50 / max_r;
|
||||
|
||||
//no par.formula = trig_DE; par.doubles.N = 5; scale = (double)10; invert=1;
|
||||
|
||||
//no par.formula = trig_optim; scale = (double)10; par.doubles.N = 4;
|
||||
|
||||
//par.formula = mandelbulb2; scale = (double)1/10000; par.doubles.N = 10; invert = 1; center = v3f(1,-4201,1); //ok
|
||||
// no par.formula = tglad;
|
||||
|
||||
//par.formula = xenodreambuie; par.juliaMode = 1; par.doubles.julia.x = -1; par.doubles.power = 2.0; center=v3f(-size/2,-size/2-5,5); //ok
|
||||
|
||||
par.mandelbox.doubles.vary4D.scaleVary = 0.1;
|
||||
par.mandelbox.doubles.vary4D.fold = 1;
|
||||
par.mandelbox.doubles.vary4D.minR = 0.5;
|
||||
par.mandelbox.doubles.vary4D.rPower = 1;
|
||||
par.mandelbox.doubles.vary4D.wadd = 0;
|
||||
//no par.formula = mandelboxVaryScale4D;
|
||||
par.doubles.cadd = -1.3;
|
||||
//par.formula = aexion; // ok but center
|
||||
//par.formula = benesi; par.doubles.N = 10; center = v3f(0,0,0); invert = 0; //ok
|
||||
|
||||
// par.formula = bristorbrot; //ok
|
||||
|
||||
v3f vec0(node_min.X, node_min.Y, node_min.Z);
|
||||
vec0 = (vec0 - center) * scale ;
|
||||
errorstream << " X=" << node_min.X << " Y=" << node_min.Y << " Z=" << node_min.Z
|
||||
<< " N=" << Compute<normal>(CVector3(vec0.X, vec0.Y, vec0.Z), par)
|
||||
//<<" F="<< Compute<fake_AO>(CVector3(node_min.X,node_min.Y,node_min.Z), par)
|
||||
//<<" L="<<node_min.getLength()<< " -="<<node_min.getLength() - Compute<normal>(CVector3(node_min.X,node_min.Y,node_min.Z), par)
|
||||
<< " Sc=" << scale
|
||||
<< std::endl;
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
u32 i = vm->m_area.index(node_min.X, y, z);
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++) {
|
||||
v3f vec(x, y, z);
|
||||
vec = (vec - center) * scale ;
|
||||
//double d = Compute<fake_AO>(CVector3(x,y,z), par);
|
||||
double d = Compute<normal>(CVector3(vec.X, vec.Y, vec.Z), par);
|
||||
//if (d>0)
|
||||
// errorstream << " d=" << d <<" v="<< vec.getLength()<< " -="<< vec.getLength() - d <<" yad="
|
||||
//<< Compute<normal>(CVector3(x,y,z), par)
|
||||
//<< std::endl;
|
||||
if ((!invert && d > 0) || (invert && d == 0)/*&& vec.getLength() - d > tresh*/ ) {
|
||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE)
|
||||
vm->m_data[i] = n_stone;
|
||||
} else {
|
||||
vm->m_data[i] = n_air;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int MapgenMath::getGroundLevelAtPoint(v2s16 p) {
|
||||
return 0;
|
||||
}
|
70
src/mapgen_math.h
Normal file
70
src/mapgen_math.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
Minetest
|
||||
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MAPGEN_MATH_HEADER
|
||||
#define MAPGEN_MATH_HEADER
|
||||
|
||||
#include "mapgen.h"
|
||||
#include "mapgen_v7.h"
|
||||
#include "json/json.h"
|
||||
|
||||
struct MapgenMathParams : public MapgenV7Params {
|
||||
|
||||
MapgenMathParams() {
|
||||
}
|
||||
|
||||
Json::Value params;
|
||||
|
||||
bool readParams(Settings *settings);
|
||||
void writeParams(Settings *settings);
|
||||
};
|
||||
|
||||
class MapgenMath : public MapgenV7 {
|
||||
public:
|
||||
MapgenMathParams * mg_params;
|
||||
|
||||
MapgenMath(int mapgenid, MapgenMathParams *mg_params, EmergeManager *emerge);
|
||||
~MapgenMath();
|
||||
|
||||
|
||||
//void makeChunk(BlockMakeData *data);
|
||||
void generateTerrain();
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
|
||||
bool invert;
|
||||
double size;
|
||||
double scale;
|
||||
v3f center;
|
||||
int iterations;
|
||||
double distance;
|
||||
double (*func)(double, double, double, double, int);
|
||||
|
||||
};
|
||||
|
||||
struct MapgenFactoryMath : public MapgenFactory {
|
||||
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
||||
return new MapgenMath(mgid, (MapgenMathParams *)params, emerge);
|
||||
};
|
||||
|
||||
MapgenParams *createMapgenParams() {
|
||||
return new MapgenMathParams();
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
@ -94,7 +94,7 @@ public:
|
||||
MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge);
|
||||
~MapgenV7();
|
||||
|
||||
void makeChunk(BlockMakeData *data);
|
||||
virtual void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
Biome *getBiomeAtPoint(v3s16 p);
|
||||
|
||||
@ -103,7 +103,7 @@ public:
|
||||
void calculateNoise();
|
||||
int calcHeightMap();
|
||||
|
||||
void generateTerrain();
|
||||
virtual void generateTerrain();
|
||||
void carveRidges();
|
||||
//void carveRivers(); //experimental
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user