Skip to content

Commit

Permalink
Move biome calculation to BiomeGen
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kwolekr committed May 28, 2016
1 parent fa6b21a commit 76f4856
Show file tree
Hide file tree
Showing 16 changed files with 413 additions and 296 deletions.
2 changes: 0 additions & 2 deletions src/emerge.cpp
Expand Up @@ -181,8 +181,6 @@ EmergeManager::~EmergeManager()
delete oremgr;
delete decomgr;
delete schemmgr;

delete params.sparams;
}


Expand Down
38 changes: 23 additions & 15 deletions src/mapgen.cpp
Expand Up @@ -76,10 +76,9 @@ Mapgen::Mapgen()

vm = NULL;
ndef = NULL;
heightmap = NULL;
biomegen = NULL;
biomemap = NULL;
heatmap = NULL;
humidmap = NULL;
heightmap = NULL;
}


Expand All @@ -94,11 +93,10 @@ Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) :
csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE);

vm = NULL;
ndef = NULL;
heightmap = NULL;
ndef = emerge->ndef;
biomegen = NULL;
biomemap = NULL;
heatmap = NULL;
humidmap = NULL;
heightmap = NULL;
}


Expand Down Expand Up @@ -444,6 +442,14 @@ void GenerateNotifier::getEvents(
//// MapgenParams
////


MapgenParams::~MapgenParams()
{
delete bparams;
delete sparams;
}


void MapgenParams::load(const Settings &settings)
{
std::string seed_str;
Expand All @@ -458,10 +464,13 @@ void MapgenParams::load(const Settings &settings)
settings.getS16NoEx("water_level", water_level);
settings.getS16NoEx("chunksize", chunksize);
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);
settings.getNoiseParams("mg_biome_np_humidity", np_biome_humidity);
settings.getNoiseParams("mg_biome_np_humidity_blend", np_biome_humidity_blend);

delete bparams;
bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL);
if (bparams) {
bparams->readParams(&settings);
bparams->seed = seed;
}

delete sparams;
MapgenFactory *mgfactory = EmergeManager::getMapgenFactory(mg_name);
Expand All @@ -479,10 +488,9 @@ void MapgenParams::save(Settings &settings) const
settings.setS16("water_level", water_level);
settings.setS16("chunksize", chunksize);
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);
settings.setNoiseParams("mg_biome_np_humidity", np_biome_humidity);
settings.setNoiseParams("mg_biome_np_humidity_blend", np_biome_humidity_blend);

if (bparams)
bparams->writeParams(&settings);

if (sparams)
sparams->writeParams(&settings);
Expand Down
21 changes: 9 additions & 12 deletions src/mapgen.h
Expand Up @@ -44,6 +44,8 @@ extern FlagDesc flagdesc_mapgen[];
extern FlagDesc flagdesc_gennotify[];

class Biome;
class BiomeGen;
struct BiomeParams;
class EmergeManager;
class MapBlock;
class VoxelManipulator;
Expand Down Expand Up @@ -115,11 +117,7 @@ struct MapgenParams {
s16 water_level;
u32 flags;

NoiseParams np_biome_heat;
NoiseParams np_biome_heat_blend;
NoiseParams np_biome_humidity;
NoiseParams np_biome_humidity_blend;

BiomeParams *bparams;
MapgenSpecificParams *sparams;

MapgenParams() :
Expand All @@ -128,12 +126,12 @@ struct MapgenParams {
seed(0),
water_level(1),
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)),
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)),
bparams(NULL),
sparams(NULL)
{}
{
}

virtual ~MapgenParams();

void load(const Settings &settings);
void save(Settings &settings) const;
Expand All @@ -153,10 +151,9 @@ class Mapgen {
u32 blockseed;
s16 *heightmap;
u8 *biomemap;
float *heatmap;
float *humidmap;
v3s16 csize;

BiomeGen *biomegen;
GenerateNotifier gennotify;

Mapgen();
Expand Down
48 changes: 13 additions & 35 deletions src/mapgen_flat.cpp
Expand Up @@ -61,10 +61,7 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge
// 1-down overgeneration
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->heatmap = NULL;
this->humidmap = NULL;
this->heightmap = new s16[csize.X * csize.Z];

MapgenFlatParams *sp = (MapgenFlatParams *)params->sparams;

Expand All @@ -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_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);

//// Biome noise
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
noise_humidity = new Noise(&params->np_biome_humidity, seed, csize.X, csize.Z);
noise_heat_blend = new Noise(&params->np_biome_heat_blend, seed, csize.X, csize.Z);
noise_humidity_blend = new Noise(&params->np_biome_humidity_blend, seed, csize.X, csize.Z);
//// Initialize biome generator
biomegen = emerge->biomemgr->createBiomeGen(
BIOMEGEN_ORIGINAL, params->bparams, csize);
biomemap = biomegen->biomemap;

//// Resolve nodes to be used
INodeDefManager *ndef = emerge->ndef;

c_stone = ndef->getId("mapgen_stone");
c_water_source = ndef->getId("mapgen_water_source");
c_lava_source = ndef->getId("mapgen_lava_source");
Expand Down Expand Up @@ -128,13 +122,9 @@ MapgenFlat::~MapgenFlat()
delete noise_cave1;
delete noise_cave2;

delete noise_heat;
delete noise_humidity;
delete noise_heat_blend;
delete noise_humidity_blend;
delete biomegen;

delete[] heightmap;
delete[] biomemap;
}


Expand Down Expand Up @@ -252,12 +242,10 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
// Create heightmap
updateHeightmap(node_min, node_max);

// Create biomemap at heightmap surface
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
noise_humidity->result, heightmap, biomemap);

// Actually place the biome-specific nodes
MgStoneType stone_type = generateBiomes(noise_heat->result, noise_humidity->result);
// Init biome generator, place biome-specific nodes, and build biomemap
biomegen->calcBiomeNoise(node_min);
biomegen->getBiomes(heightmap);
MgStoneType stone_type = generateBiomes();

if (flags & MG_CAVES)
generateCaves(stone_surface_max_y);
Expand Down Expand Up @@ -343,18 +331,7 @@ void MapgenFlat::calculateNoise()
// 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());
}

Expand Down Expand Up @@ -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();
u32 index = 0;
Expand Down Expand Up @@ -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.
if ((c == c_stone && (air_above || water_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;
base_filler = MYMAX(depth_top + biome->depth_filler
+ noise_filler_depth->result[index], 0);
Expand Down
2 changes: 1 addition & 1 deletion src/mapgen_flat.h
Expand Up @@ -104,7 +104,7 @@ class MapgenFlat : public Mapgen {
int getSpawnLevelAtPoint(v2s16 p);
void calculateNoise();
s16 generateTerrain();
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
MgStoneType generateBiomes();
void dustTopNodes();
void generateCaves(s16 max_stone_y);
};
Expand Down
48 changes: 13 additions & 35 deletions src/mapgen_fractal.cpp
Expand Up @@ -59,10 +59,7 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *
// 1-down overgeneration
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->heatmap = NULL;
this->humidmap = NULL;

MapgenFractalParams *sp = (MapgenFractalParams *)params->sparams;

Expand All @@ -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_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);

//// Biome noise
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
noise_humidity = new Noise(&params->np_biome_humidity, seed, csize.X, csize.Z);
noise_heat_blend = new Noise(&params->np_biome_heat_blend, seed, csize.X, csize.Z);
noise_humidity_blend = new Noise(&params->np_biome_humidity_blend, seed, csize.X, csize.Z);
//// Initialize biome generator
biomegen = emerge->biomemgr->createBiomeGen(
BIOMEGEN_ORIGINAL, params->bparams, csize);
biomemap = biomegen->biomemap;

this->formula = fractal / 2 + fractal % 2;
this->julia = fractal % 2 == 0;

//// Resolve nodes to be used
INodeDefManager *ndef = emerge->ndef;

c_stone = ndef->getId("mapgen_stone");
c_water_source = ndef->getId("mapgen_water_source");
c_lava_source = ndef->getId("mapgen_lava_source");
Expand Down Expand Up @@ -132,13 +126,9 @@ MapgenFractal::~MapgenFractal()
delete noise_cave1;
delete noise_cave2;

delete noise_heat;
delete noise_humidity;
delete noise_heat_blend;
delete noise_humidity_blend;
delete biomegen;

delete[] heightmap;
delete[] biomemap;
}


Expand Down Expand Up @@ -217,7 +207,7 @@ int MapgenFractal::getSpawnLevelAtPoint(v2s16 p)
s16 search_start = MYMAX(seabed_level, water_level + 1);
if (seabed_level > water_level)
solid_below = true;

for (s16 y = search_start; y <= search_start + 128; y++) {
if (getFractalAtPoint(p.X, y, p.Y)) { // Fractal node
solid_below = true;
Expand Down Expand Up @@ -268,12 +258,10 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
// Create heightmap
updateHeightmap(node_min, node_max);

// Create biomemap at heightmap surface
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
noise_humidity->result, heightmap, biomemap);

// Actually place the biome-specific nodes
MgStoneType stone_type = generateBiomes(noise_heat->result, noise_humidity->result);
// Init biome generator, place biome-specific nodes, and build biomemap
biomegen->calcBiomeNoise(node_min);
biomegen->getBiomes(heightmap);
MgStoneType stone_type = generateBiomes();

if (flags & MG_CAVES)
generateCaves(stone_surface_max_y);
Expand Down Expand Up @@ -358,18 +346,7 @@ void MapgenFractal::calculateNoise()
// 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());
}

Expand Down Expand Up @@ -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();
u32 index = 0;
Expand Down Expand Up @@ -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.
if ((c == c_stone && (air_above || water_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;
base_filler = MYMAX(depth_top + biome->depth_filler
+ noise_filler_depth->result[index], 0);
Expand Down
7 changes: 1 addition & 6 deletions src/mapgen_fractal.h
Expand Up @@ -88,11 +88,6 @@ class MapgenFractal : public Mapgen {
Noise *noise_cave1;
Noise *noise_cave2;

Noise *noise_heat;
Noise *noise_humidity;
Noise *noise_heat_blend;
Noise *noise_humidity_blend;

content_t c_stone;
content_t c_water_source;
content_t c_lava_source;
Expand All @@ -114,7 +109,7 @@ class MapgenFractal : public Mapgen {
void calculateNoise();
bool getFractalAtPoint(s16 x, s16 y, s16 z);
s16 generateTerrain();
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
MgStoneType generateBiomes();
void dustTopNodes();
void generateCaves(s16 max_stone_y);
};
Expand Down

0 comments on commit 76f4856

Please sign in to comment.