Move biome calculation to BiomeGen
BiomeGen defines an interface that, given a set of BiomeParams, computes biomes for a given area using the algorithm implemented by that specific BiomeGen. This abstracts away the old system where each mapgen supplied the noises required for biome generation.master
parent
fa6b21a15b
commit
76f4856479
|
@ -181,8 +181,6 @@ EmergeManager::~EmergeManager()
|
||||||
delete oremgr;
|
delete oremgr;
|
||||||
delete decomgr;
|
delete decomgr;
|
||||||
delete schemmgr;
|
delete schemmgr;
|
||||||
|
|
||||||
delete params.sparams;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,10 +76,9 @@ Mapgen::Mapgen()
|
||||||
|
|
||||||
vm = NULL;
|
vm = NULL;
|
||||||
ndef = NULL;
|
ndef = NULL;
|
||||||
heightmap = NULL;
|
biomegen = NULL;
|
||||||
biomemap = NULL;
|
biomemap = NULL;
|
||||||
heatmap = NULL;
|
heightmap = NULL;
|
||||||
humidmap = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,11 +93,10 @@ Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) :
|
||||||
csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE);
|
csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE);
|
||||||
|
|
||||||
vm = NULL;
|
vm = NULL;
|
||||||
ndef = NULL;
|
ndef = emerge->ndef;
|
||||||
heightmap = NULL;
|
biomegen = NULL;
|
||||||
biomemap = NULL;
|
biomemap = NULL;
|
||||||
heatmap = NULL;
|
heightmap = NULL;
|
||||||
humidmap = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -444,6 +442,14 @@ void GenerateNotifier::getEvents(
|
||||||
//// MapgenParams
|
//// MapgenParams
|
||||||
////
|
////
|
||||||
|
|
||||||
|
|
||||||
|
MapgenParams::~MapgenParams()
|
||||||
|
{
|
||||||
|
delete bparams;
|
||||||
|
delete sparams;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MapgenParams::load(const Settings &settings)
|
void MapgenParams::load(const Settings &settings)
|
||||||
{
|
{
|
||||||
std::string seed_str;
|
std::string seed_str;
|
||||||
|
@ -458,10 +464,13 @@ void MapgenParams::load(const Settings &settings)
|
||||||
settings.getS16NoEx("water_level", water_level);
|
settings.getS16NoEx("water_level", water_level);
|
||||||
settings.getS16NoEx("chunksize", chunksize);
|
settings.getS16NoEx("chunksize", chunksize);
|
||||||
settings.getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen);
|
settings.getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen);
|
||||||
settings.getNoiseParams("mg_biome_np_heat", np_biome_heat);
|
|
||||||
settings.getNoiseParams("mg_biome_np_heat_blend", np_biome_heat_blend);
|
delete bparams;
|
||||||
settings.getNoiseParams("mg_biome_np_humidity", np_biome_humidity);
|
bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL);
|
||||||
settings.getNoiseParams("mg_biome_np_humidity_blend", np_biome_humidity_blend);
|
if (bparams) {
|
||||||
|
bparams->readParams(&settings);
|
||||||
|
bparams->seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
delete sparams;
|
delete sparams;
|
||||||
MapgenFactory *mgfactory = EmergeManager::getMapgenFactory(mg_name);
|
MapgenFactory *mgfactory = EmergeManager::getMapgenFactory(mg_name);
|
||||||
|
@ -479,10 +488,9 @@ void MapgenParams::save(Settings &settings) const
|
||||||
settings.setS16("water_level", water_level);
|
settings.setS16("water_level", water_level);
|
||||||
settings.setS16("chunksize", chunksize);
|
settings.setS16("chunksize", chunksize);
|
||||||
settings.setFlagStr("mg_flags", flags, flagdesc_mapgen, U32_MAX);
|
settings.setFlagStr("mg_flags", flags, flagdesc_mapgen, U32_MAX);
|
||||||
settings.setNoiseParams("mg_biome_np_heat", np_biome_heat);
|
|
||||||
settings.setNoiseParams("mg_biome_np_heat_blend", np_biome_heat_blend);
|
if (bparams)
|
||||||
settings.setNoiseParams("mg_biome_np_humidity", np_biome_humidity);
|
bparams->writeParams(&settings);
|
||||||
settings.setNoiseParams("mg_biome_np_humidity_blend", np_biome_humidity_blend);
|
|
||||||
|
|
||||||
if (sparams)
|
if (sparams)
|
||||||
sparams->writeParams(&settings);
|
sparams->writeParams(&settings);
|
||||||
|
|
21
src/mapgen.h
21
src/mapgen.h
|
@ -44,6 +44,8 @@ extern FlagDesc flagdesc_mapgen[];
|
||||||
extern FlagDesc flagdesc_gennotify[];
|
extern FlagDesc flagdesc_gennotify[];
|
||||||
|
|
||||||
class Biome;
|
class Biome;
|
||||||
|
class BiomeGen;
|
||||||
|
struct BiomeParams;
|
||||||
class EmergeManager;
|
class EmergeManager;
|
||||||
class MapBlock;
|
class MapBlock;
|
||||||
class VoxelManipulator;
|
class VoxelManipulator;
|
||||||
|
@ -115,11 +117,7 @@ struct MapgenParams {
|
||||||
s16 water_level;
|
s16 water_level;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
|
||||||
NoiseParams np_biome_heat;
|
BiomeParams *bparams;
|
||||||
NoiseParams np_biome_heat_blend;
|
|
||||||
NoiseParams np_biome_humidity;
|
|
||||||
NoiseParams np_biome_humidity_blend;
|
|
||||||
|
|
||||||
MapgenSpecificParams *sparams;
|
MapgenSpecificParams *sparams;
|
||||||
|
|
||||||
MapgenParams() :
|
MapgenParams() :
|
||||||
|
@ -128,12 +126,12 @@ struct MapgenParams {
|
||||||
seed(0),
|
seed(0),
|
||||||
water_level(1),
|
water_level(1),
|
||||||
flags(MG_CAVES | MG_LIGHT | MG_DECORATIONS),
|
flags(MG_CAVES | MG_LIGHT | MG_DECORATIONS),
|
||||||
np_biome_heat(NoiseParams(50, 50, v3f(750.0, 750.0, 750.0), 5349, 3, 0.5, 2.0)),
|
bparams(NULL),
|
||||||
np_biome_heat_blend(NoiseParams(0, 1.5, v3f(8.0, 8.0, 8.0), 13, 2, 1.0, 2.0)),
|
|
||||||
np_biome_humidity(NoiseParams(50, 50, v3f(750.0, 750.0, 750.0), 842, 3, 0.5, 2.0)),
|
|
||||||
np_biome_humidity_blend(NoiseParams(0, 1.5, v3f(8.0, 8.0, 8.0), 90003, 2, 1.0, 2.0)),
|
|
||||||
sparams(NULL)
|
sparams(NULL)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~MapgenParams();
|
||||||
|
|
||||||
void load(const Settings &settings);
|
void load(const Settings &settings);
|
||||||
void save(Settings &settings) const;
|
void save(Settings &settings) const;
|
||||||
|
@ -153,10 +151,9 @@ public:
|
||||||
u32 blockseed;
|
u32 blockseed;
|
||||||
s16 *heightmap;
|
s16 *heightmap;
|
||||||
u8 *biomemap;
|
u8 *biomemap;
|
||||||
float *heatmap;
|
|
||||||
float *humidmap;
|
|
||||||
v3s16 csize;
|
v3s16 csize;
|
||||||
|
|
||||||
|
BiomeGen *biomegen;
|
||||||
GenerateNotifier gennotify;
|
GenerateNotifier gennotify;
|
||||||
|
|
||||||
Mapgen();
|
Mapgen();
|
||||||
|
|
|
@ -61,10 +61,7 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge
|
||||||
// 1-down overgeneration
|
// 1-down overgeneration
|
||||||
this->zstride_1d = csize.X * (csize.Y + 1);
|
this->zstride_1d = csize.X * (csize.Y + 1);
|
||||||
|
|
||||||
this->biomemap = new u8[csize.X * csize.Z];
|
this->heightmap = new s16[csize.X * csize.Z];
|
||||||
this->heightmap = new s16[csize.X * csize.Z];
|
|
||||||
this->heatmap = NULL;
|
|
||||||
this->humidmap = NULL;
|
|
||||||
|
|
||||||
MapgenFlatParams *sp = (MapgenFlatParams *)params->sparams;
|
MapgenFlatParams *sp = (MapgenFlatParams *)params->sparams;
|
||||||
|
|
||||||
|
@ -86,15 +83,12 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
|
|
||||||
//// Biome noise
|
//// Initialize biome generator
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
biomegen = emerge->biomemgr->createBiomeGen(
|
||||||
noise_humidity = new Noise(¶ms->np_biome_humidity, seed, csize.X, csize.Z);
|
BIOMEGEN_ORIGINAL, params->bparams, csize);
|
||||||
noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z);
|
biomemap = biomegen->biomemap;
|
||||||
noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z);
|
|
||||||
|
|
||||||
//// Resolve nodes to be used
|
//// Resolve nodes to be used
|
||||||
INodeDefManager *ndef = emerge->ndef;
|
|
||||||
|
|
||||||
c_stone = ndef->getId("mapgen_stone");
|
c_stone = ndef->getId("mapgen_stone");
|
||||||
c_water_source = ndef->getId("mapgen_water_source");
|
c_water_source = ndef->getId("mapgen_water_source");
|
||||||
c_lava_source = ndef->getId("mapgen_lava_source");
|
c_lava_source = ndef->getId("mapgen_lava_source");
|
||||||
|
@ -128,13 +122,9 @@ MapgenFlat::~MapgenFlat()
|
||||||
delete noise_cave1;
|
delete noise_cave1;
|
||||||
delete noise_cave2;
|
delete noise_cave2;
|
||||||
|
|
||||||
delete noise_heat;
|
delete biomegen;
|
||||||
delete noise_humidity;
|
|
||||||
delete noise_heat_blend;
|
|
||||||
delete noise_humidity_blend;
|
|
||||||
|
|
||||||
delete[] heightmap;
|
delete[] heightmap;
|
||||||
delete[] biomemap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,12 +242,10 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
|
||||||
// Create heightmap
|
// Create heightmap
|
||||||
updateHeightmap(node_min, node_max);
|
updateHeightmap(node_min, node_max);
|
||||||
|
|
||||||
// Create biomemap at heightmap surface
|
// Init biome generator, place biome-specific nodes, and build biomemap
|
||||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
biomegen->calcBiomeNoise(node_min);
|
||||||
noise_humidity->result, heightmap, biomemap);
|
biomegen->getBiomes(heightmap);
|
||||||
|
MgStoneType stone_type = generateBiomes();
|
||||||
// Actually place the biome-specific nodes
|
|
||||||
MgStoneType stone_type = generateBiomes(noise_heat->result, noise_humidity->result);
|
|
||||||
|
|
||||||
if (flags & MG_CAVES)
|
if (flags & MG_CAVES)
|
||||||
generateCaves(stone_surface_max_y);
|
generateCaves(stone_surface_max_y);
|
||||||
|
@ -343,18 +331,7 @@ void MapgenFlat::calculateNoise()
|
||||||
// only if solid terrain is present in mapchunk
|
// only if solid terrain is present in mapchunk
|
||||||
|
|
||||||
noise_filler_depth->perlinMap2D(x, z);
|
noise_filler_depth->perlinMap2D(x, z);
|
||||||
noise_heat->perlinMap2D(x, z);
|
|
||||||
noise_humidity->perlinMap2D(x, z);
|
|
||||||
noise_heat_blend->perlinMap2D(x, z);
|
|
||||||
noise_humidity_blend->perlinMap2D(x, z);
|
|
||||||
|
|
||||||
for (s32 i = 0; i < csize.X * csize.Z; i++) {
|
|
||||||
noise_heat->result[i] += noise_heat_blend->result[i];
|
|
||||||
noise_humidity->result[i] += noise_humidity_blend->result[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
heatmap = noise_heat->result;
|
|
||||||
humidmap = noise_humidity->result;
|
|
||||||
//printf("calculateNoise: %dus\n", t.stop());
|
//printf("calculateNoise: %dus\n", t.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +383,7 @@ s16 MapgenFlat::generateTerrain()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MgStoneType MapgenFlat::generateBiomes(float *heat_map, float *humidity_map)
|
MgStoneType MapgenFlat::generateBiomes()
|
||||||
{
|
{
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
@ -443,7 +420,8 @@ MgStoneType MapgenFlat::generateBiomes(float *heat_map, float *humidity_map)
|
||||||
// 3. When stone or water is detected but biome has not yet been calculated.
|
// 3. When stone or water is detected but biome has not yet been calculated.
|
||||||
if ((c == c_stone && (air_above || water_above || !biome)) ||
|
if ((c == c_stone && (air_above || water_above || !biome)) ||
|
||||||
(c == c_water_source && (air_above || !biome))) {
|
(c == c_water_source && (air_above || !biome))) {
|
||||||
biome = bmgr->getBiome(heat_map[index], humidity_map[index], y);
|
biome = biomegen->getBiomeAtIndex(index, y);
|
||||||
|
|
||||||
depth_top = biome->depth_top;
|
depth_top = biome->depth_top;
|
||||||
base_filler = MYMAX(depth_top + biome->depth_filler
|
base_filler = MYMAX(depth_top + biome->depth_filler
|
||||||
+ noise_filler_depth->result[index], 0);
|
+ noise_filler_depth->result[index], 0);
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
int getSpawnLevelAtPoint(v2s16 p);
|
int getSpawnLevelAtPoint(v2s16 p);
|
||||||
void calculateNoise();
|
void calculateNoise();
|
||||||
s16 generateTerrain();
|
s16 generateTerrain();
|
||||||
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
|
MgStoneType generateBiomes();
|
||||||
void dustTopNodes();
|
void dustTopNodes();
|
||||||
void generateCaves(s16 max_stone_y);
|
void generateCaves(s16 max_stone_y);
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,10 +59,7 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *
|
||||||
// 1-down overgeneration
|
// 1-down overgeneration
|
||||||
this->zstride_1d = csize.X * (csize.Y + 1);
|
this->zstride_1d = csize.X * (csize.Y + 1);
|
||||||
|
|
||||||
this->biomemap = new u8[csize.X * csize.Z];
|
|
||||||
this->heightmap = new s16[csize.X * csize.Z];
|
this->heightmap = new s16[csize.X * csize.Z];
|
||||||
this->heatmap = NULL;
|
|
||||||
this->humidmap = NULL;
|
|
||||||
|
|
||||||
MapgenFractalParams *sp = (MapgenFractalParams *)params->sparams;
|
MapgenFractalParams *sp = (MapgenFractalParams *)params->sparams;
|
||||||
|
|
||||||
|
@ -87,18 +84,15 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
|
|
||||||
//// Biome noise
|
//// Initialize biome generator
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
biomegen = emerge->biomemgr->createBiomeGen(
|
||||||
noise_humidity = new Noise(¶ms->np_biome_humidity, seed, csize.X, csize.Z);
|
BIOMEGEN_ORIGINAL, params->bparams, csize);
|
||||||
noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z);
|
biomemap = biomegen->biomemap;
|
||||||
noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z);
|
|
||||||
|
|
||||||
this->formula = fractal / 2 + fractal % 2;
|
this->formula = fractal / 2 + fractal % 2;
|
||||||
this->julia = fractal % 2 == 0;
|
this->julia = fractal % 2 == 0;
|
||||||
|
|
||||||
//// Resolve nodes to be used
|
//// Resolve nodes to be used
|
||||||
INodeDefManager *ndef = emerge->ndef;
|
|
||||||
|
|
||||||
c_stone = ndef->getId("mapgen_stone");
|
c_stone = ndef->getId("mapgen_stone");
|
||||||
c_water_source = ndef->getId("mapgen_water_source");
|
c_water_source = ndef->getId("mapgen_water_source");
|
||||||
c_lava_source = ndef->getId("mapgen_lava_source");
|
c_lava_source = ndef->getId("mapgen_lava_source");
|
||||||
|
@ -132,13 +126,9 @@ MapgenFractal::~MapgenFractal()
|
||||||
delete noise_cave1;
|
delete noise_cave1;
|
||||||
delete noise_cave2;
|
delete noise_cave2;
|
||||||
|
|
||||||
delete noise_heat;
|
delete biomegen;
|
||||||
delete noise_humidity;
|
|
||||||
delete noise_heat_blend;
|
|
||||||
delete noise_humidity_blend;
|
|
||||||
|
|
||||||
delete[] heightmap;
|
delete[] heightmap;
|
||||||
delete[] biomemap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,7 +207,7 @@ int MapgenFractal::getSpawnLevelAtPoint(v2s16 p)
|
||||||
s16 search_start = MYMAX(seabed_level, water_level + 1);
|
s16 search_start = MYMAX(seabed_level, water_level + 1);
|
||||||
if (seabed_level > water_level)
|
if (seabed_level > water_level)
|
||||||
solid_below = true;
|
solid_below = true;
|
||||||
|
|
||||||
for (s16 y = search_start; y <= search_start + 128; y++) {
|
for (s16 y = search_start; y <= search_start + 128; y++) {
|
||||||
if (getFractalAtPoint(p.X, y, p.Y)) { // Fractal node
|
if (getFractalAtPoint(p.X, y, p.Y)) { // Fractal node
|
||||||
solid_below = true;
|
solid_below = true;
|
||||||
|
@ -268,12 +258,10 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
|
||||||
// Create heightmap
|
// Create heightmap
|
||||||
updateHeightmap(node_min, node_max);
|
updateHeightmap(node_min, node_max);
|
||||||
|
|
||||||
// Create biomemap at heightmap surface
|
// Init biome generator, place biome-specific nodes, and build biomemap
|
||||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
biomegen->calcBiomeNoise(node_min);
|
||||||
noise_humidity->result, heightmap, biomemap);
|
biomegen->getBiomes(heightmap);
|
||||||
|
MgStoneType stone_type = generateBiomes();
|
||||||
// Actually place the biome-specific nodes
|
|
||||||
MgStoneType stone_type = generateBiomes(noise_heat->result, noise_humidity->result);
|
|
||||||
|
|
||||||
if (flags & MG_CAVES)
|
if (flags & MG_CAVES)
|
||||||
generateCaves(stone_surface_max_y);
|
generateCaves(stone_surface_max_y);
|
||||||
|
@ -358,18 +346,7 @@ void MapgenFractal::calculateNoise()
|
||||||
// only if solid terrain is present in mapchunk
|
// only if solid terrain is present in mapchunk
|
||||||
|
|
||||||
noise_filler_depth->perlinMap2D(x, z);
|
noise_filler_depth->perlinMap2D(x, z);
|
||||||
noise_heat->perlinMap2D(x, z);
|
|
||||||
noise_humidity->perlinMap2D(x, z);
|
|
||||||
noise_heat_blend->perlinMap2D(x, z);
|
|
||||||
noise_humidity_blend->perlinMap2D(x, z);
|
|
||||||
|
|
||||||
for (s32 i = 0; i < csize.X * csize.Z; i++) {
|
|
||||||
noise_heat->result[i] += noise_heat_blend->result[i];
|
|
||||||
noise_humidity->result[i] += noise_humidity_blend->result[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
heatmap = noise_heat->result;
|
|
||||||
humidmap = noise_humidity->result;
|
|
||||||
//printf("calculateNoise: %dus\n", t.stop());
|
//printf("calculateNoise: %dus\n", t.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +507,7 @@ s16 MapgenFractal::generateTerrain()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MgStoneType MapgenFractal::generateBiomes(float *heat_map, float *humidity_map)
|
MgStoneType MapgenFractal::generateBiomes()
|
||||||
{
|
{
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
@ -567,7 +544,8 @@ MgStoneType MapgenFractal::generateBiomes(float *heat_map, float *humidity_map)
|
||||||
// 3. When stone or water is detected but biome has not yet been calculated.
|
// 3. When stone or water is detected but biome has not yet been calculated.
|
||||||
if ((c == c_stone && (air_above || water_above || !biome)) ||
|
if ((c == c_stone && (air_above || water_above || !biome)) ||
|
||||||
(c == c_water_source && (air_above || !biome))) {
|
(c == c_water_source && (air_above || !biome))) {
|
||||||
biome = bmgr->getBiome(heat_map[index], humidity_map[index], y);
|
biome = biomegen->getBiomeAtIndex(index, y);
|
||||||
|
|
||||||
depth_top = biome->depth_top;
|
depth_top = biome->depth_top;
|
||||||
base_filler = MYMAX(depth_top + biome->depth_filler
|
base_filler = MYMAX(depth_top + biome->depth_filler
|
||||||
+ noise_filler_depth->result[index], 0);
|
+ noise_filler_depth->result[index], 0);
|
||||||
|
|
|
@ -88,11 +88,6 @@ public:
|
||||||
Noise *noise_cave1;
|
Noise *noise_cave1;
|
||||||
Noise *noise_cave2;
|
Noise *noise_cave2;
|
||||||
|
|
||||||
Noise *noise_heat;
|
|
||||||
Noise *noise_humidity;
|
|
||||||
Noise *noise_heat_blend;
|
|
||||||
Noise *noise_humidity_blend;
|
|
||||||
|
|
||||||
content_t c_stone;
|
content_t c_stone;
|
||||||
content_t c_water_source;
|
content_t c_water_source;
|
||||||
content_t c_lava_source;
|
content_t c_lava_source;
|
||||||
|
@ -114,7 +109,7 @@ public:
|
||||||
void calculateNoise();
|
void calculateNoise();
|
||||||
bool getFractalAtPoint(s16 x, s16 y, s16 z);
|
bool getFractalAtPoint(s16 x, s16 y, s16 z);
|
||||||
s16 generateTerrain();
|
s16 generateTerrain();
|
||||||
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
|
MgStoneType generateBiomes();
|
||||||
void dustTopNodes();
|
void dustTopNodes();
|
||||||
void generateCaves(s16 max_stone_y);
|
void generateCaves(s16 max_stone_y);
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,10 +57,7 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||||
// 1-down overgeneration
|
// 1-down overgeneration
|
||||||
this->zstride_1d = csize.X * (csize.Y + 1);
|
this->zstride_1d = csize.X * (csize.Y + 1);
|
||||||
|
|
||||||
this->biomemap = new u8[csize.X * csize.Z];
|
|
||||||
this->heightmap = new s16[csize.X * csize.Z];
|
this->heightmap = new s16[csize.X * csize.Z];
|
||||||
this->heatmap = NULL;
|
|
||||||
this->humidmap = NULL;
|
|
||||||
|
|
||||||
MapgenV5Params *sp = (MapgenV5Params *)params->sparams;
|
MapgenV5Params *sp = (MapgenV5Params *)params->sparams;
|
||||||
|
|
||||||
|
@ -79,15 +76,12 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
|
|
||||||
// Biome noise
|
//// Initialize biome generator
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
biomegen = emerge->biomemgr->createBiomeGen(
|
||||||
noise_humidity = new Noise(¶ms->np_biome_humidity, seed, csize.X, csize.Z);
|
BIOMEGEN_ORIGINAL, params->bparams, csize);
|
||||||
noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z);
|
biomemap = biomegen->biomemap;
|
||||||
noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z);
|
|
||||||
|
|
||||||
//// Resolve nodes to be used
|
//// Resolve nodes to be used
|
||||||
INodeDefManager *ndef = emerge->ndef;
|
|
||||||
|
|
||||||
c_stone = ndef->getId("mapgen_stone");
|
c_stone = ndef->getId("mapgen_stone");
|
||||||
c_water_source = ndef->getId("mapgen_water_source");
|
c_water_source = ndef->getId("mapgen_water_source");
|
||||||
c_lava_source = ndef->getId("mapgen_lava_source");
|
c_lava_source = ndef->getId("mapgen_lava_source");
|
||||||
|
@ -123,13 +117,9 @@ MapgenV5::~MapgenV5()
|
||||||
delete noise_cave2;
|
delete noise_cave2;
|
||||||
delete noise_ground;
|
delete noise_ground;
|
||||||
|
|
||||||
delete noise_heat;
|
delete biomegen;
|
||||||
delete noise_humidity;
|
|
||||||
delete noise_heat_blend;
|
|
||||||
delete noise_humidity_blend;
|
|
||||||
|
|
||||||
delete[] heightmap;
|
delete[] heightmap;
|
||||||
delete[] biomemap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,12 +238,10 @@ void MapgenV5::makeChunk(BlockMakeData *data)
|
||||||
// Create heightmap
|
// Create heightmap
|
||||||
updateHeightmap(node_min, node_max);
|
updateHeightmap(node_min, node_max);
|
||||||
|
|
||||||
// Create biomemap at heightmap surface
|
// Init biome generator, place biome-specific nodes, and build biomemap
|
||||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
biomegen->calcBiomeNoise(node_min);
|
||||||
noise_humidity->result, heightmap, biomemap);
|
biomegen->getBiomes(heightmap);
|
||||||
|
MgStoneType stone_type = generateBiomes();
|
||||||
// Actually place the biome-specific nodes
|
|
||||||
MgStoneType stone_type = generateBiomes(noise_heat->result, noise_humidity->result);
|
|
||||||
|
|
||||||
// Generate caves
|
// Generate caves
|
||||||
if ((flags & MG_CAVES) && (stone_surface_max_y >= node_min.Y))
|
if ((flags & MG_CAVES) && (stone_surface_max_y >= node_min.Y))
|
||||||
|
@ -343,18 +331,7 @@ void MapgenV5::calculateNoise()
|
||||||
// only if solid terrain is present in mapchunk
|
// only if solid terrain is present in mapchunk
|
||||||
|
|
||||||
noise_filler_depth->perlinMap2D(x, z);
|
noise_filler_depth->perlinMap2D(x, z);
|
||||||
noise_heat->perlinMap2D(x, z);
|
|
||||||
noise_humidity->perlinMap2D(x, z);
|
|
||||||
noise_heat_blend->perlinMap2D(x, z);
|
|
||||||
noise_humidity_blend->perlinMap2D(x, z);
|
|
||||||
|
|
||||||
for (s32 i = 0; i < csize.X * csize.Z; i++) {
|
|
||||||
noise_heat->result[i] += noise_heat_blend->result[i];
|
|
||||||
noise_humidity->result[i] += noise_humidity_blend->result[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
heatmap = noise_heat->result;
|
|
||||||
humidmap = noise_humidity->result;
|
|
||||||
//printf("calculateNoise: %dus\n", t.stop());
|
//printf("calculateNoise: %dus\n", t.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +393,7 @@ int MapgenV5::generateBaseTerrain()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MgStoneType MapgenV5::generateBiomes(float *heat_map, float *humidity_map)
|
MgStoneType MapgenV5::generateBiomes()
|
||||||
{
|
{
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
@ -452,7 +429,8 @@ MgStoneType MapgenV5::generateBiomes(float *heat_map, float *humidity_map)
|
||||||
// 3. When stone or water is detected but biome has not yet been calculated.
|
// 3. When stone or water is detected but biome has not yet been calculated.
|
||||||
if ((c == c_stone && (air_above || water_above || !biome)) ||
|
if ((c == c_stone && (air_above || water_above || !biome)) ||
|
||||||
(c == c_water_source && (air_above || !biome))) {
|
(c == c_water_source && (air_above || !biome))) {
|
||||||
biome = bmgr->getBiome(heat_map[index], humidity_map[index], y);
|
biome = biomegen->getBiomeAtIndex(index, y);
|
||||||
|
|
||||||
depth_top = biome->depth_top;
|
depth_top = biome->depth_top;
|
||||||
base_filler = MYMAX(depth_top + biome->depth_filler
|
base_filler = MYMAX(depth_top + biome->depth_filler
|
||||||
+ noise_filler_depth->result[index], 0);
|
+ noise_filler_depth->result[index], 0);
|
||||||
|
|
|
@ -70,11 +70,6 @@ public:
|
||||||
Noise *noise_cave2;
|
Noise *noise_cave2;
|
||||||
Noise *noise_ground;
|
Noise *noise_ground;
|
||||||
|
|
||||||
Noise *noise_heat;
|
|
||||||
Noise *noise_humidity;
|
|
||||||
Noise *noise_heat_blend;
|
|
||||||
Noise *noise_humidity_blend;
|
|
||||||
|
|
||||||
content_t c_stone;
|
content_t c_stone;
|
||||||
content_t c_water_source;
|
content_t c_water_source;
|
||||||
content_t c_lava_source;
|
content_t c_lava_source;
|
||||||
|
@ -95,7 +90,7 @@ public:
|
||||||
int getSpawnLevelAtPoint(v2s16 p);
|
int getSpawnLevelAtPoint(v2s16 p);
|
||||||
void calculateNoise();
|
void calculateNoise();
|
||||||
int generateBaseTerrain();
|
int generateBaseTerrain();
|
||||||
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
|
MgStoneType generateBiomes();
|
||||||
void generateCaves(int max_stone_y);
|
void generateCaves(int max_stone_y);
|
||||||
void dustTopNodes();
|
void dustTopNodes();
|
||||||
};
|
};
|
||||||
|
|
|
@ -64,10 +64,7 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||||
// 1-down overgeneration
|
// 1-down overgeneration
|
||||||
this->zstride_1d = csize.X * (csize.Y + 1);
|
this->zstride_1d = csize.X * (csize.Y + 1);
|
||||||
|
|
||||||
this->biomemap = new u8[csize.X * csize.Z];
|
|
||||||
this->heightmap = new s16[csize.X * csize.Z];
|
this->heightmap = new s16[csize.X * csize.Z];
|
||||||
this->heatmap = NULL;
|
|
||||||
this->humidmap = NULL;
|
|
||||||
this->ridge_heightmap = new s16[csize.X * csize.Z];
|
this->ridge_heightmap = new s16[csize.X * csize.Z];
|
||||||
|
|
||||||
MapgenV7Params *sp = (MapgenV7Params *)params->sparams;
|
MapgenV7Params *sp = (MapgenV7Params *)params->sparams;
|
||||||
|
@ -92,15 +89,13 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
|
|
||||||
//// Biome noise
|
// TODO(hmmmm): should we have a way to disable biomemanager biomes?
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
//// Initialize biome generator
|
||||||
noise_humidity = new Noise(¶ms->np_biome_humidity, seed, csize.X, csize.Z);
|
biomegen = emerge->biomemgr->createBiomeGen(
|
||||||
noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z);
|
BIOMEGEN_ORIGINAL, params->bparams, csize);
|
||||||
noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z);
|
biomemap = biomegen->biomemap;
|
||||||
|
|
||||||
//// Resolve nodes to be used
|
//// Resolve nodes to be used
|
||||||
INodeDefManager *ndef = emerge->ndef;
|
|
||||||
|
|
||||||
c_stone = ndef->getId("mapgen_stone");
|
c_stone = ndef->getId("mapgen_stone");
|
||||||
c_water_source = ndef->getId("mapgen_water_source");
|
c_water_source = ndef->getId("mapgen_water_source");
|
||||||
c_lava_source = ndef->getId("mapgen_lava_source");
|
c_lava_source = ndef->getId("mapgen_lava_source");
|
||||||
|
@ -141,14 +136,10 @@ MapgenV7::~MapgenV7()
|
||||||
delete noise_cave1;
|
delete noise_cave1;
|
||||||
delete noise_cave2;
|
delete noise_cave2;
|
||||||
|
|
||||||
delete noise_heat;
|
delete biomegen;
|
||||||
delete noise_humidity;
|
|
||||||
delete noise_heat_blend;
|
|
||||||
delete noise_humidity_blend;
|
|
||||||
|
|
||||||
delete[] ridge_heightmap;
|
delete[] ridge_heightmap;
|
||||||
delete[] heightmap;
|
delete[] heightmap;
|
||||||
delete[] biomemap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,12 +270,10 @@ void MapgenV7::makeChunk(BlockMakeData *data)
|
||||||
// Update heightmap to include mountain terrain
|
// Update heightmap to include mountain terrain
|
||||||
updateHeightmap(node_min, node_max);
|
updateHeightmap(node_min, node_max);
|
||||||
|
|
||||||
// Create biomemap at heightmap surface
|
// Init biome generator, place biome-specific nodes, and build biomemap
|
||||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
biomegen->calcBiomeNoise(node_min);
|
||||||
noise_humidity->result, heightmap, biomemap);
|
biomegen->getBiomes(heightmap);
|
||||||
|
MgStoneType stone_type = generateBiomes();
|
||||||
// Actually place the biome-specific nodes
|
|
||||||
MgStoneType stone_type = generateBiomes(noise_heat->result, noise_humidity->result);
|
|
||||||
|
|
||||||
if (flags & MG_CAVES)
|
if (flags & MG_CAVES)
|
||||||
generateCaves(stone_surface_max_y);
|
generateCaves(stone_surface_max_y);
|
||||||
|
@ -384,35 +373,10 @@ void MapgenV7::calculateNoise()
|
||||||
// Cave noises are calculated in generateCaves()
|
// Cave noises are calculated in generateCaves()
|
||||||
// only if solid terrain is present in mapchunk
|
// only if solid terrain is present in mapchunk
|
||||||
|
|
||||||
noise_filler_depth->perlinMap2D(x, z);
|
|
||||||
noise_heat->perlinMap2D(x, z);
|
|
||||||
noise_humidity->perlinMap2D(x, z);
|
|
||||||
noise_heat_blend->perlinMap2D(x, z);
|
|
||||||
noise_humidity_blend->perlinMap2D(x, z);
|
|
||||||
|
|
||||||
for (s32 i = 0; i < csize.X * csize.Z; i++) {
|
|
||||||
noise_heat->result[i] += noise_heat_blend->result[i];
|
|
||||||
noise_humidity->result[i] += noise_humidity_blend->result[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
heatmap = noise_heat->result;
|
|
||||||
humidmap = noise_humidity->result;
|
|
||||||
//printf("calculateNoise: %dus\n", t.stop());
|
//printf("calculateNoise: %dus\n", t.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Biome *MapgenV7::getBiomeAtPoint(v3s16 p)
|
|
||||||
{
|
|
||||||
float heat = NoisePerlin2D(&noise_heat->np, p.X, p.Z, seed) +
|
|
||||||
NoisePerlin2D(&noise_heat_blend->np, p.X, p.Z, seed);
|
|
||||||
float humidity = NoisePerlin2D(&noise_humidity->np, p.X, p.Z, seed) +
|
|
||||||
NoisePerlin2D(&noise_humidity_blend->np, p.X, p.Z, seed);
|
|
||||||
s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Z);
|
|
||||||
|
|
||||||
return bmgr->getBiome(heat, humidity, groundlevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float MapgenV7::baseTerrainLevelAtPoint(s16 x, s16 z)
|
float MapgenV7::baseTerrainLevelAtPoint(s16 x, s16 z)
|
||||||
{
|
{
|
||||||
float hselect = NoisePerlin2D(&noise_height_select->np, x, z, seed);
|
float hselect = NoisePerlin2D(&noise_height_select->np, x, z, seed);
|
||||||
|
@ -553,7 +517,7 @@ void MapgenV7::generateRidgeTerrain()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MgStoneType MapgenV7::generateBiomes(float *heat_map, float *humidity_map)
|
MgStoneType MapgenV7::generateBiomes()
|
||||||
{
|
{
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
@ -589,7 +553,8 @@ MgStoneType MapgenV7::generateBiomes(float *heat_map, float *humidity_map)
|
||||||
// 3. When stone or water is detected but biome has not yet been calculated.
|
// 3. When stone or water is detected but biome has not yet been calculated.
|
||||||
if ((c == c_stone && (air_above || water_above || !biome)) ||
|
if ((c == c_stone && (air_above || water_above || !biome)) ||
|
||||||
(c == c_water_source && (air_above || !biome))) {
|
(c == c_water_source && (air_above || !biome))) {
|
||||||
biome = bmgr->getBiome(heat_map[index], humidity_map[index], y);
|
biome = biomegen->getBiomeAtIndex(index, y);
|
||||||
|
|
||||||
depth_top = biome->depth_top;
|
depth_top = biome->depth_top;
|
||||||
base_filler = MYMAX(depth_top + biome->depth_filler
|
base_filler = MYMAX(depth_top + biome->depth_filler
|
||||||
+ noise_filler_depth->result[index], 0);
|
+ noise_filler_depth->result[index], 0);
|
||||||
|
|
|
@ -84,11 +84,6 @@ public:
|
||||||
Noise *noise_cave1;
|
Noise *noise_cave1;
|
||||||
Noise *noise_cave2;
|
Noise *noise_cave2;
|
||||||
|
|
||||||
Noise *noise_heat;
|
|
||||||
Noise *noise_humidity;
|
|
||||||
Noise *noise_heat_blend;
|
|
||||||
Noise *noise_humidity_blend;
|
|
||||||
|
|
||||||
content_t c_stone;
|
content_t c_stone;
|
||||||
content_t c_water_source;
|
content_t c_water_source;
|
||||||
content_t c_lava_source;
|
content_t c_lava_source;
|
||||||
|
@ -107,7 +102,6 @@ public:
|
||||||
|
|
||||||
virtual void makeChunk(BlockMakeData *data);
|
virtual void makeChunk(BlockMakeData *data);
|
||||||
int getSpawnLevelAtPoint(v2s16 p);
|
int getSpawnLevelAtPoint(v2s16 p);
|
||||||
Biome *getBiomeAtPoint(v3s16 p);
|
|
||||||
|
|
||||||
float baseTerrainLevelAtPoint(s16 x, s16 z);
|
float baseTerrainLevelAtPoint(s16 x, s16 z);
|
||||||
float baseTerrainLevelFromMap(int index);
|
float baseTerrainLevelFromMap(int index);
|
||||||
|
@ -119,7 +113,7 @@ public:
|
||||||
int generateTerrain();
|
int generateTerrain();
|
||||||
void generateRidgeTerrain();
|
void generateRidgeTerrain();
|
||||||
|
|
||||||
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
|
MgStoneType generateBiomes();
|
||||||
void dustTopNodes();
|
void dustTopNodes();
|
||||||
|
|
||||||
void generateCaves(s16 max_stone_y);
|
void generateCaves(s16 max_stone_y);
|
||||||
|
|
|
@ -68,7 +68,7 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
|
||||||
: Mapgen(mapgenid, params, emerge)
|
: Mapgen(mapgenid, params, emerge)
|
||||||
{
|
{
|
||||||
this->m_emerge = emerge;
|
this->m_emerge = emerge;
|
||||||
this->bmgr = emerge->biomemgr;
|
this->bmgr = emerge->biomemgr;
|
||||||
|
|
||||||
//// amount of elements to skip for the next index
|
//// amount of elements to skip for the next index
|
||||||
//// for noise/height/biome maps (not vmanip)
|
//// for noise/height/biome maps (not vmanip)
|
||||||
|
@ -77,15 +77,13 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
|
||||||
// 1-down overgeneration
|
// 1-down overgeneration
|
||||||
this->zstride_1d = csize.X * (csize.Y + 1);
|
this->zstride_1d = csize.X * (csize.Y + 1);
|
||||||
|
|
||||||
this->biomemap = new u8[csize.X * csize.Z];
|
|
||||||
this->heightmap = new s16[csize.X * csize.Z];
|
this->heightmap = new s16[csize.X * csize.Z];
|
||||||
this->heatmap = NULL;
|
|
||||||
this->humidmap = NULL;
|
|
||||||
|
|
||||||
this->map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT,
|
this->map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT,
|
||||||
g_settings->getU16("map_generation_limit"));
|
g_settings->getU16("map_generation_limit"));
|
||||||
|
|
||||||
MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams;
|
MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams;
|
||||||
|
BiomeParamsOriginal *bp = (BiomeParamsOriginal *)params->bparams;
|
||||||
|
|
||||||
this->spflags = sp->spflags;
|
this->spflags = sp->spflags;
|
||||||
this->altitude_chill = sp->altitude_chill;
|
this->altitude_chill = sp->altitude_chill;
|
||||||
|
@ -113,15 +111,16 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z);
|
noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z);
|
||||||
|
|
||||||
//// Biome noise
|
//// Initialize biome generator
|
||||||
noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z);
|
// NOTE: valleys mapgen can only use BiomeGenOriginal
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
biomegen = emerge->biomemgr->createBiomeGen(
|
||||||
noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z);
|
BIOMEGEN_ORIGINAL, params->bparams, csize);
|
||||||
noise_humidity = new Noise(¶ms->np_biome_humidity, seed, csize.X, csize.Z);
|
biomemap = biomegen->biomemap;
|
||||||
|
m_bgen = (BiomeGenOriginal *)biomegen;
|
||||||
|
|
||||||
this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS);
|
this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS);
|
||||||
this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL);
|
this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL);
|
||||||
this->humidity_adjust = params->np_biome_humidity.offset - 50.f;
|
this->humidity_adjust = bp->np_humidity.offset - 50.f;
|
||||||
|
|
||||||
// a small chance of overflows if the settings are very high
|
// a small chance of overflows if the settings are very high
|
||||||
this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50;
|
this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50;
|
||||||
|
@ -130,8 +129,6 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
|
||||||
tcave_cache = new float[csize.Y + 2];
|
tcave_cache = new float[csize.Y + 2];
|
||||||
|
|
||||||
//// Resolve nodes to be used
|
//// Resolve nodes to be used
|
||||||
INodeDefManager *ndef = emerge->ndef;
|
|
||||||
|
|
||||||
c_cobble = ndef->getId("mapgen_cobble");
|
c_cobble = ndef->getId("mapgen_cobble");
|
||||||
c_desert_stone = ndef->getId("mapgen_desert_stone");
|
c_desert_stone = ndef->getId("mapgen_desert_stone");
|
||||||
c_dirt = ndef->getId("mapgen_dirt");
|
c_dirt = ndef->getId("mapgen_dirt");
|
||||||
|
@ -174,12 +171,8 @@ MapgenValleys::~MapgenValleys()
|
||||||
delete noise_valley_depth;
|
delete noise_valley_depth;
|
||||||
delete noise_valley_profile;
|
delete noise_valley_profile;
|
||||||
|
|
||||||
delete noise_heat;
|
delete biomegen;
|
||||||
delete noise_heat_blend;
|
|
||||||
delete noise_humidity;
|
|
||||||
delete noise_humidity_blend;
|
|
||||||
|
|
||||||
delete[] biomemap;
|
|
||||||
delete[] heightmap;
|
delete[] heightmap;
|
||||||
delete[] tcave_cache;
|
delete[] tcave_cache;
|
||||||
}
|
}
|
||||||
|
@ -293,14 +286,19 @@ void MapgenValleys::makeChunk(BlockMakeData *data)
|
||||||
// Generate noise maps and base terrain height.
|
// Generate noise maps and base terrain height.
|
||||||
calculateNoise();
|
calculateNoise();
|
||||||
|
|
||||||
|
// Generate biome noises. Note this must be executed strictly before
|
||||||
|
// generateTerrain, because generateTerrain depends on intermediate
|
||||||
|
// biome-related noises.
|
||||||
|
biomegen->calcBiomeNoise(node_min);
|
||||||
|
|
||||||
// Generate base terrain with initial heightmaps
|
// Generate base terrain with initial heightmaps
|
||||||
s16 stone_surface_max_y = generateTerrain();
|
s16 stone_surface_max_y = generateTerrain();
|
||||||
|
|
||||||
// Create biomemap at heightmap surface
|
// Build biomemap
|
||||||
bmgr->calcBiomes(csize.X, csize.Z, heatmap, humidmap, heightmap, biomemap);
|
biomegen->getBiomes(heightmap);
|
||||||
|
|
||||||
// Actually place the biome-specific nodes
|
// Place biome-specific nodes
|
||||||
MgStoneType stone_type = generateBiomes(heatmap, humidmap);
|
MgStoneType stone_type = generateBiomes();
|
||||||
|
|
||||||
// Cave creation.
|
// Cave creation.
|
||||||
if (flags & MG_CAVES)
|
if (flags & MG_CAVES)
|
||||||
|
@ -391,10 +389,6 @@ void MapgenValleys::calculateNoise()
|
||||||
//TimeTaker tcn("actualNoise");
|
//TimeTaker tcn("actualNoise");
|
||||||
|
|
||||||
noise_filler_depth->perlinMap2D(x, z);
|
noise_filler_depth->perlinMap2D(x, z);
|
||||||
noise_heat_blend->perlinMap2D(x, z);
|
|
||||||
noise_heat->perlinMap2D(x, z);
|
|
||||||
noise_humidity_blend->perlinMap2D(x, z);
|
|
||||||
noise_humidity->perlinMap2D(x, z);
|
|
||||||
noise_inter_valley_slope->perlinMap2D(x, z);
|
noise_inter_valley_slope->perlinMap2D(x, z);
|
||||||
noise_rivers->perlinMap2D(x, z);
|
noise_rivers->perlinMap2D(x, z);
|
||||||
noise_terrain_height->perlinMap2D(x, z);
|
noise_terrain_height->perlinMap2D(x, z);
|
||||||
|
@ -418,9 +412,8 @@ void MapgenValleys::calculateNoise()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 index = 0; index < csize.X * csize.Z; index++) {
|
for (s32 index = 0; index < csize.X * csize.Z; index++) {
|
||||||
noise_heat->result[index] += noise_heat_blend->result[index] + heat_offset;
|
m_bgen->heatmap[index] += heat_offset;
|
||||||
noise_humidity->result[index] *= humidity_scale;
|
m_bgen->humidmap[index] *= humidity_scale;
|
||||||
noise_humidity->result[index] += noise_humidity_blend->result[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TerrainNoise tn;
|
TerrainNoise tn;
|
||||||
|
@ -450,9 +443,6 @@ void MapgenValleys::calculateNoise()
|
||||||
float mount = terrainLevelFromNoise(&tn);
|
float mount = terrainLevelFromNoise(&tn);
|
||||||
noise_terrain_height->result[index] = mount;
|
noise_terrain_height->result[index] = mount;
|
||||||
}
|
}
|
||||||
|
|
||||||
heatmap = noise_heat->result;
|
|
||||||
humidmap = noise_humidity->result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -596,7 +586,7 @@ int MapgenValleys::generateTerrain()
|
||||||
float river_y = noise_rivers->result[index_2d];
|
float river_y = noise_rivers->result[index_2d];
|
||||||
float surface_y = noise_terrain_height->result[index_2d];
|
float surface_y = noise_terrain_height->result[index_2d];
|
||||||
float slope = noise_inter_valley_slope->result[index_2d];
|
float slope = noise_inter_valley_slope->result[index_2d];
|
||||||
float t_heat = noise_heat->result[index_2d];
|
float t_heat = m_bgen->heatmap[index_2d];
|
||||||
|
|
||||||
heightmap[index_2d] = -MAX_MAP_GENERATION_LIMIT;
|
heightmap[index_2d] = -MAX_MAP_GENERATION_LIMIT;
|
||||||
|
|
||||||
|
@ -610,7 +600,7 @@ int MapgenValleys::generateTerrain()
|
||||||
t_heat -= alt_to_heat * MYMAX(surface_y, river_y) / altitude_chill;
|
t_heat -= alt_to_heat * MYMAX(surface_y, river_y) / altitude_chill;
|
||||||
|
|
||||||
// If humidity is low or heat is high, lower the water table.
|
// If humidity is low or heat is high, lower the water table.
|
||||||
float delta = noise_humidity->result[index_2d] - 50.f;
|
float delta = m_bgen->humidmap[index_2d] - 50.f;
|
||||||
if (delta < 0.f) {
|
if (delta < 0.f) {
|
||||||
float t_evap = (t_heat - 32.f) / evaporation;
|
float t_evap = (t_heat - 32.f) / evaporation;
|
||||||
river_y += delta * MYMAX(t_evap, 0.08f);
|
river_y += delta * MYMAX(t_evap, 0.08f);
|
||||||
|
@ -672,7 +662,7 @@ int MapgenValleys::generateTerrain()
|
||||||
// Use base ground (water table) in a riverbed, to
|
// Use base ground (water table) in a riverbed, to
|
||||||
// avoid an unnatural rise in humidity.
|
// avoid an unnatural rise in humidity.
|
||||||
float t_alt = MYMAX(noise_rivers->result[index_2d], (float)heightmap[index_2d]);
|
float t_alt = MYMAX(noise_rivers->result[index_2d], (float)heightmap[index_2d]);
|
||||||
float humid = noise_humidity->result[index_2d];
|
float humid = m_bgen->humidmap[index_2d];
|
||||||
float water_depth = (t_alt - river_y) / humidity_dropoff;
|
float water_depth = (t_alt - river_y) / humidity_dropoff;
|
||||||
humid *= 1.f + pow(0.5f, MYMAX(water_depth, 1.f));
|
humid *= 1.f + pow(0.5f, MYMAX(water_depth, 1.f));
|
||||||
|
|
||||||
|
@ -683,7 +673,7 @@ int MapgenValleys::generateTerrain()
|
||||||
if (t_alt > 0.f)
|
if (t_alt > 0.f)
|
||||||
humid -= alt_to_humid * t_alt / altitude_chill;
|
humid -= alt_to_humid * t_alt / altitude_chill;
|
||||||
|
|
||||||
noise_humidity->result[index_2d] = humid;
|
m_bgen->humidmap[index_2d] = humid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the heat adjusted by any changed altitudes.
|
// Assign the heat adjusted by any changed altitudes.
|
||||||
|
@ -693,9 +683,9 @@ int MapgenValleys::generateTerrain()
|
||||||
float t_alt = MYMAX(noise_rivers->result[index_2d], (float)heightmap[index_2d]);
|
float t_alt = MYMAX(noise_rivers->result[index_2d], (float)heightmap[index_2d]);
|
||||||
if (humid_rivers && heightmap[index_2d] == (s16)myround(surface_y))
|
if (humid_rivers && heightmap[index_2d] == (s16)myround(surface_y))
|
||||||
// The altitude hasn't changed. Use the first result.
|
// The altitude hasn't changed. Use the first result.
|
||||||
noise_heat->result[index_2d] = t_heat;
|
m_bgen->heatmap[index_2d] = t_heat;
|
||||||
else if (t_alt > 0.f)
|
else if (t_alt > 0.f)
|
||||||
noise_heat->result[index_2d] -= alt_to_heat * t_alt / altitude_chill;
|
m_bgen->heatmap[index_2d] -= alt_to_heat * t_alt / altitude_chill;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,7 +693,7 @@ int MapgenValleys::generateTerrain()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MgStoneType MapgenValleys::generateBiomes(float *heat_map, float *humidity_map)
|
MgStoneType MapgenValleys::generateBiomes()
|
||||||
{
|
{
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
@ -739,9 +729,9 @@ MgStoneType MapgenValleys::generateBiomes(float *heat_map, float *humidity_map)
|
||||||
// 3. When stone or water is detected but biome has not yet been calculated.
|
// 3. When stone or water is detected but biome has not yet been calculated.
|
||||||
if ((c == c_stone && (air_above || water_above || !biome))
|
if ((c == c_stone && (air_above || water_above || !biome))
|
||||||
|| ((c == c_water_source || c == c_river_water_source)
|
|| ((c == c_water_source || c == c_river_water_source)
|
||||||
&& (air_above || !biome))) {
|
&& (air_above || !biome))) {
|
||||||
// Both heat and humidity have already been adjusted for altitude.
|
// Both heat and humidity have already been adjusted for altitude.
|
||||||
biome = bmgr->getBiome(heat_map[index], humidity_map[index], y);
|
biome = biomegen->getBiomeAtIndex(index, y);
|
||||||
|
|
||||||
depth_top = biome->depth_top;
|
depth_top = biome->depth_top;
|
||||||
base_filler = MYMAX(depth_top
|
base_filler = MYMAX(depth_top
|
||||||
|
|
|
@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#define MYCUBE(x) (x) * (x) * (x)
|
#define MYCUBE(x) (x) * (x) * (x)
|
||||||
|
|
||||||
class BiomeManager;
|
class BiomeManager;
|
||||||
|
class BiomeGenOriginal;
|
||||||
|
|
||||||
// Global profiler
|
// Global profiler
|
||||||
//class Profiler;
|
//class Profiler;
|
||||||
|
@ -98,6 +99,7 @@ public:
|
||||||
private:
|
private:
|
||||||
EmergeManager *m_emerge;
|
EmergeManager *m_emerge;
|
||||||
BiomeManager *bmgr;
|
BiomeManager *bmgr;
|
||||||
|
BiomeGenOriginal *m_bgen;
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride;
|
||||||
|
@ -136,11 +138,6 @@ private:
|
||||||
Noise *noise_valley_depth;
|
Noise *noise_valley_depth;
|
||||||
Noise *noise_valley_profile;
|
Noise *noise_valley_profile;
|
||||||
|
|
||||||
Noise *noise_heat;
|
|
||||||
Noise *noise_heat_blend;
|
|
||||||
Noise *noise_humidity;
|
|
||||||
Noise *noise_humidity_blend;
|
|
||||||
|
|
||||||
content_t c_cobble;
|
content_t c_cobble;
|
||||||
content_t c_desert_stone;
|
content_t c_desert_stone;
|
||||||
content_t c_dirt;
|
content_t c_dirt;
|
||||||
|
@ -164,9 +161,7 @@ private:
|
||||||
float terrainLevelFromNoise(TerrainNoise *tn);
|
float terrainLevelFromNoise(TerrainNoise *tn);
|
||||||
float adjustedTerrainLevelFromNoise(TerrainNoise *tn);
|
float adjustedTerrainLevelFromNoise(TerrainNoise *tn);
|
||||||
|
|
||||||
float humidityByTerrain(float humidity_base, float mount, float rivers, float valley);
|
MgStoneType generateBiomes();
|
||||||
|
|
||||||
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
|
|
||||||
void dustTopNodes();
|
void dustTopNodes();
|
||||||
|
|
||||||
void generateCaves(s16 max_stone_y);
|
void generateCaves(s16 max_stone_y);
|
||||||
|
|
185
src/mg_biome.cpp
185
src/mg_biome.cpp
|
@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "util/mathconstants.h"
|
#include "util/mathconstants.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -63,49 +64,11 @@ BiomeManager::BiomeManager(IGameDef *gamedef) :
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BiomeManager::~BiomeManager()
|
BiomeManager::~BiomeManager()
|
||||||
{
|
{
|
||||||
//if (biomecache)
|
|
||||||
// delete[] biomecache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// just a PoC, obviously needs optimization later on (precalculate this)
|
|
||||||
void BiomeManager::calcBiomes(s16 sx, s16 sy, float *heat_map,
|
|
||||||
float *humidity_map, s16 *height_map, u8 *biomeid_map)
|
|
||||||
{
|
|
||||||
for (s32 i = 0; i != sx * sy; i++) {
|
|
||||||
Biome *biome = getBiome(heat_map[i], humidity_map[i], height_map[i]);
|
|
||||||
biomeid_map[i] = biome->index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
|
|
||||||
{
|
|
||||||
Biome *b, *biome_closest = NULL;
|
|
||||||
float dist_min = FLT_MAX;
|
|
||||||
|
|
||||||
for (size_t i = 1; i < m_objects.size(); i++) {
|
|
||||||
b = (Biome *)m_objects[i];
|
|
||||||
if (!b || y > b->y_max || y < b->y_min)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float d_heat = heat - b->heat_point;
|
|
||||||
float d_humidity = humidity - b->humidity_point;
|
|
||||||
float dist = (d_heat * d_heat) +
|
|
||||||
(d_humidity * d_humidity);
|
|
||||||
if (dist < dist_min) {
|
|
||||||
dist_min = dist;
|
|
||||||
biome_closest = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return biome_closest ? biome_closest : (Biome *)m_objects[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void BiomeManager::clear()
|
void BiomeManager::clear()
|
||||||
{
|
{
|
||||||
EmergeManager *emerge = m_gamedef->getEmergeManager();
|
EmergeManager *emerge = m_gamedef->getEmergeManager();
|
||||||
|
@ -118,17 +81,153 @@ void BiomeManager::clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't delete the first biome
|
// Don't delete the first biome
|
||||||
for (size_t i = 1; i < m_objects.size(); i++) {
|
for (size_t i = 1; i < m_objects.size(); i++)
|
||||||
Biome *b = (Biome *)m_objects[i];
|
delete (Biome *)m_objects[i];
|
||||||
delete b;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_objects.resize(1);
|
m_objects.resize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
void BiomeParamsOriginal::readParams(const Settings *settings)
|
||||||
|
{
|
||||||
|
settings->getNoiseParams("mg_biome_np_heat", np_heat);
|
||||||
|
settings->getNoiseParams("mg_biome_np_heat_blend", np_heat_blend);
|
||||||
|
settings->getNoiseParams("mg_biome_np_humidity", np_humidity);
|
||||||
|
settings->getNoiseParams("mg_biome_np_humidity_blend", np_humidity_blend);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BiomeParamsOriginal::writeParams(Settings *settings) const
|
||||||
|
{
|
||||||
|
settings->setNoiseParams("mg_biome_np_heat", np_heat);
|
||||||
|
settings->setNoiseParams("mg_biome_np_heat_blend", np_heat_blend);
|
||||||
|
settings->setNoiseParams("mg_biome_np_humidity", np_humidity);
|
||||||
|
settings->setNoiseParams("mg_biome_np_humidity_blend", np_humidity_blend);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
BiomeGenOriginal::BiomeGenOriginal(BiomeManager *biomemgr,
|
||||||
|
BiomeParamsOriginal *params, v3s16 chunksize)
|
||||||
|
{
|
||||||
|
m_bmgr = biomemgr;
|
||||||
|
m_params = params;
|
||||||
|
m_csize = chunksize;
|
||||||
|
|
||||||
|
noise_heat = new Noise(¶ms->np_heat,
|
||||||
|
params->seed, m_csize.X, m_csize.Z);
|
||||||
|
noise_humidity = new Noise(¶ms->np_humidity,
|
||||||
|
params->seed, m_csize.X, m_csize.Z);
|
||||||
|
noise_heat_blend = new Noise(¶ms->np_heat_blend,
|
||||||
|
params->seed, m_csize.X, m_csize.Z);
|
||||||
|
noise_humidity_blend = new Noise(¶ms->np_humidity_blend,
|
||||||
|
params->seed, m_csize.X, m_csize.Z);
|
||||||
|
|
||||||
|
heatmap = noise_heat->result;
|
||||||
|
humidmap = noise_humidity->result;
|
||||||
|
biomemap = new u8[m_csize.X * m_csize.Z];
|
||||||
|
}
|
||||||
|
|
||||||
|
BiomeGenOriginal::~BiomeGenOriginal()
|
||||||
|
{
|
||||||
|
delete []biomemap;
|
||||||
|
|
||||||
|
delete noise_heat;
|
||||||
|
delete noise_humidity;
|
||||||
|
delete noise_heat_blend;
|
||||||
|
delete noise_humidity_blend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Biome *BiomeGenOriginal::calcBiomeAtPoint(v3s16 pos) const
|
||||||
|
{
|
||||||
|
float heat =
|
||||||
|
NoisePerlin2D(&m_params->np_heat, pos.X, pos.Z, m_params->seed) +
|
||||||
|
NoisePerlin2D(&m_params->np_heat_blend, pos.X, pos.Z, m_params->seed);
|
||||||
|
float humidity =
|
||||||
|
NoisePerlin2D(&m_params->np_humidity, pos.X, pos.Z, m_params->seed) +
|
||||||
|
NoisePerlin2D(&m_params->np_humidity_blend, pos.X, pos.Z, m_params->seed);
|
||||||
|
|
||||||
|
return calcBiomeFromNoise(heat, humidity, pos.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BiomeGenOriginal::calcBiomeNoise(v3s16 pmin)
|
||||||
|
{
|
||||||
|
m_pmin = pmin;
|
||||||
|
|
||||||
|
noise_heat->perlinMap2D(pmin.X, pmin.Z);
|
||||||
|
noise_humidity->perlinMap2D(pmin.X, pmin.Z);
|
||||||
|
noise_heat_blend->perlinMap2D(pmin.X, pmin.Z);
|
||||||
|
noise_humidity_blend->perlinMap2D(pmin.X, pmin.Z);
|
||||||
|
|
||||||
|
for (s32 i = 0; i < m_csize.X * m_csize.Z; i++) {
|
||||||
|
noise_heat->result[i] += noise_heat_blend->result[i];
|
||||||
|
noise_humidity->result[i] += noise_humidity_blend->result[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u8 *BiomeGenOriginal::getBiomes(s16 *heightmap)
|
||||||
|
{
|
||||||
|
for (s32 i = 0; i != m_csize.X * m_csize.Z; i++) {
|
||||||
|
Biome *biome = calcBiomeFromNoise(
|
||||||
|
noise_heat->result[i],
|
||||||
|
noise_humidity->result[i],
|
||||||
|
heightmap[i]);
|
||||||
|
|
||||||
|
biomemap[i] = biome->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
return biomemap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Biome *BiomeGenOriginal::getBiomeAtPoint(v3s16 pos) const
|
||||||
|
{
|
||||||
|
return getBiomeAtIndex(
|
||||||
|
(pos.Z - m_pmin.Z) * m_csize.X + (pos.X - m_pmin.X),
|
||||||
|
pos.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Biome *BiomeGenOriginal::getBiomeAtIndex(size_t index, s16 y) const
|
||||||
|
{
|
||||||
|
return calcBiomeFromNoise(
|
||||||
|
noise_heat->result[index],
|
||||||
|
noise_humidity->result[index],
|
||||||
|
y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Biome *BiomeGenOriginal::calcBiomeFromNoise(float heat, float humidity, s16 y) const
|
||||||
|
{
|
||||||
|
Biome *b, *biome_closest = NULL;
|
||||||
|
float dist_min = FLT_MAX;
|
||||||
|
|
||||||
|
for (size_t i = 1; i < m_bmgr->getNumObjects(); i++) {
|
||||||
|
b = (Biome *)m_bmgr->getRaw(i);
|
||||||
|
if (!b || y > b->y_max || y < b->y_min)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float d_heat = heat - b->heat_point;
|
||||||
|
float d_humidity = humidity - b->humidity_point;
|
||||||
|
float dist = (d_heat * d_heat) +
|
||||||
|
(d_humidity * d_humidity);
|
||||||
|
if (dist < dist_min) {
|
||||||
|
dist_min = dist;
|
||||||
|
biome_closest = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return biome_closest ? biome_closest : (Biome *)m_bmgr->getRaw(BIOME_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Biome::resolveNodeNames()
|
void Biome::resolveNodeNames()
|
||||||
{
|
{
|
||||||
|
|
155
src/mg_biome.h
155
src/mg_biome.h
|
@ -22,6 +22,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "objdef.h"
|
#include "objdef.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
|
#include "noise.h"
|
||||||
|
|
||||||
|
class Settings;
|
||||||
|
class BiomeManager;
|
||||||
|
|
||||||
|
////
|
||||||
|
//// Biome
|
||||||
|
////
|
||||||
|
|
||||||
|
#define BIOME_NONE ((u8)0)
|
||||||
|
|
||||||
enum BiomeType
|
enum BiomeType
|
||||||
{
|
{
|
||||||
|
@ -56,10 +66,122 @@ public:
|
||||||
virtual void resolveNodeNames();
|
virtual void resolveNodeNames();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////
|
||||||
|
//// BiomeGen
|
||||||
|
////
|
||||||
|
|
||||||
|
enum BiomeGenType {
|
||||||
|
BIOMEGEN_ORIGINAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BiomeParams {
|
||||||
|
virtual void readParams(const Settings *settings) = 0;
|
||||||
|
virtual void writeParams(Settings *settings) const = 0;
|
||||||
|
virtual ~BiomeParams() {}
|
||||||
|
|
||||||
|
int seed;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BiomeGen {
|
||||||
|
public:
|
||||||
|
virtual ~BiomeGen() {}
|
||||||
|
virtual BiomeGenType getType() const = 0;
|
||||||
|
|
||||||
|
// Calculates the biome at the exact position provided. This function can
|
||||||
|
// be called at any time, but may be less efficient than the latter methods,
|
||||||
|
// depending on implementation.
|
||||||
|
virtual Biome *calcBiomeAtPoint(v3s16 pos) const = 0;
|
||||||
|
|
||||||
|
// Computes any intermediate results needed for biome generation. Must be
|
||||||
|
// called before using any of: getBiomes, getBiomeAtPoint, or getBiomeAtIndex.
|
||||||
|
// Calling this invalidates the previous results stored in biomemap.
|
||||||
|
virtual void calcBiomeNoise(v3s16 pmin) = 0;
|
||||||
|
|
||||||
|
// Gets all biomes in current chunk using each corresponding element of
|
||||||
|
// heightmap as the y position, then stores the results by biome index in
|
||||||
|
// biomemap (also returned)
|
||||||
|
virtual u8 *getBiomes(s16 *heightmap) = 0;
|
||||||
|
|
||||||
|
// Gets a single biome at the specified position, which must be contained
|
||||||
|
// in the region formed by m_pmin and (m_pmin + m_csize - 1).
|
||||||
|
virtual Biome *getBiomeAtPoint(v3s16 pos) const = 0;
|
||||||
|
|
||||||
|
// Same as above, but uses a raw numeric index correlating to the (x,z) position.
|
||||||
|
virtual Biome *getBiomeAtIndex(size_t index, s16 y) const = 0;
|
||||||
|
|
||||||
|
// Result of calcBiomes bulk computation.
|
||||||
|
u8 *biomemap;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BiomeManager *m_bmgr;
|
||||||
|
v3s16 m_pmin;
|
||||||
|
v3s16 m_csize;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////
|
||||||
|
//// BiomeGen implementations
|
||||||
|
////
|
||||||
|
|
||||||
|
//
|
||||||
|
// Original biome algorithm (Whittaker's classification + surface height)
|
||||||
|
//
|
||||||
|
|
||||||
|
struct BiomeParamsOriginal : public BiomeParams {
|
||||||
|
BiomeParamsOriginal() :
|
||||||
|
np_heat(50, 50, v3f(750.0, 750.0, 750.0), 5349, 3, 0.5, 2.0),
|
||||||
|
np_humidity(50, 50, v3f(750.0, 750.0, 750.0), 842, 3, 0.5, 2.0),
|
||||||
|
np_heat_blend(0, 1.5, v3f(8.0, 8.0, 8.0), 13, 2, 1.0, 2.0),
|
||||||
|
np_humidity_blend(0, 1.5, v3f(8.0, 8.0, 8.0), 90003, 2, 1.0, 2.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void readParams(const Settings *settings);
|
||||||
|
virtual void writeParams(Settings *settings) const;
|
||||||
|
|
||||||
|
NoiseParams np_heat;
|
||||||
|
NoiseParams np_humidity;
|
||||||
|
NoiseParams np_heat_blend;
|
||||||
|
NoiseParams np_humidity_blend;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BiomeGenOriginal : public BiomeGen {
|
||||||
|
public:
|
||||||
|
BiomeGenOriginal(BiomeManager *biomemgr,
|
||||||
|
BiomeParamsOriginal *params, v3s16 chunksize);
|
||||||
|
virtual ~BiomeGenOriginal();
|
||||||
|
|
||||||
|
BiomeGenType getType() const { return BIOMEGEN_ORIGINAL; }
|
||||||
|
|
||||||
|
Biome *calcBiomeAtPoint(v3s16 pos) const;
|
||||||
|
void calcBiomeNoise(v3s16 pmin);
|
||||||
|
|
||||||
|
u8 *getBiomes(s16 *heightmap);
|
||||||
|
Biome *getBiomeAtPoint(v3s16 pos) const;
|
||||||
|
Biome *getBiomeAtIndex(size_t index, s16 y) const;
|
||||||
|
|
||||||
|
Biome *calcBiomeFromNoise(float heat, float humidity, s16 y) const;
|
||||||
|
|
||||||
|
float *heatmap;
|
||||||
|
float *humidmap;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BiomeParamsOriginal *m_params;
|
||||||
|
|
||||||
|
Noise *noise_heat;
|
||||||
|
Noise *noise_humidity;
|
||||||
|
Noise *noise_heat_blend;
|
||||||
|
Noise *noise_humidity_blend;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////
|
||||||
|
//// BiomeManager
|
||||||
|
////
|
||||||
|
|
||||||
class BiomeManager : public ObjDefManager {
|
class BiomeManager : public ObjDefManager {
|
||||||
public:
|
public:
|
||||||
static const char *OBJECT_TITLE;
|
|
||||||
|
|
||||||
BiomeManager(IGameDef *gamedef);
|
BiomeManager(IGameDef *gamedef);
|
||||||
virtual ~BiomeManager();
|
virtual ~BiomeManager();
|
||||||
|
|
||||||
|
@ -73,15 +195,36 @@ public:
|
||||||
return new Biome;
|
return new Biome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BiomeGen *createBiomeGen(BiomeGenType type, BiomeParams *params, v3s16 chunksize)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case BIOMEGEN_ORIGINAL:
|
||||||
|
return new BiomeGenOriginal(this,
|
||||||
|
(BiomeParamsOriginal *)params, chunksize);
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BiomeParams *createBiomeParams(BiomeGenType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case BIOMEGEN_ORIGINAL:
|
||||||
|
return new BiomeParamsOriginal;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
void calcBiomes(s16 sx, s16 sy, float *heat_map, float *humidity_map,
|
// Looks for pos in the biome cache, and if non-existent, looks up by noise
|
||||||
s16 *height_map, u8 *biomeid_map);
|
u8 getBiomeAtPoint(v3s16 pos);
|
||||||
Biome *getBiome(float heat, float humidity, s16 y);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -528,24 +528,26 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case MGOBJ_BIOMEMAP: {
|
case MGOBJ_BIOMEMAP: {
|
||||||
if (!mg->biomemap)
|
if (!mg->biomegen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
for (size_t i = 0; i != maplen; i++) {
|
for (size_t i = 0; i != maplen; i++) {
|
||||||
lua_pushinteger(L, mg->biomemap[i]);
|
lua_pushinteger(L, mg->biomegen->biomemap[i]);
|
||||||
lua_rawseti(L, -2, i + 1);
|
lua_rawseti(L, -2, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case MGOBJ_HEATMAP: {
|
case MGOBJ_HEATMAP: {
|
||||||
if (!mg->heatmap)
|
if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen;
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
for (size_t i = 0; i != maplen; i++) {
|
for (size_t i = 0; i != maplen; i++) {
|
||||||
lua_pushnumber(L, mg->heatmap[i]);
|
lua_pushnumber(L, bg->heatmap[i]);
|
||||||
lua_rawseti(L, -2, i + 1);
|
lua_rawseti(L, -2, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,12 +555,14 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
case MGOBJ_HUMIDMAP: {
|
case MGOBJ_HUMIDMAP: {
|
||||||
if (!mg->humidmap)
|
if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen;
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
for (size_t i = 0; i != maplen; i++) {
|
for (size_t i = 0; i != maplen; i++) {
|
||||||
lua_pushnumber(L, mg->humidmap[i]);
|
lua_pushnumber(L, bg->humidmap[i]);
|
||||||
lua_rawseti(L, -2, i + 1);
|
lua_rawseti(L, -2, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue