Skip to content

Commit

Permalink
Biomes: Add vertical biome blend (#6853)
Browse files Browse the repository at this point in the history
Add 'vertical blend' parameter to biome registration that defines how
many nodes above the biome's 'y max' limit the blend will extend.
  • Loading branch information
paramat authored and nerzhul committed Jan 4, 2018
1 parent ff2ceed commit 549cfd9
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 19 deletions.
18 changes: 9 additions & 9 deletions doc/lua_api.txt
Expand Up @@ -4989,18 +4989,18 @@ Definition tables
y_min = 1,
y_max = 31000,
-- ^ Lower and upper limits for biome.
vertical_blend = 8,
-- ^ Vertical distance in nodes above 'y_max' over which the biome will
-- ^ blend with the biome above.
-- ^ Set to 0 for no vertical blend. Defaults to 0.
heat_point = 0,
humidity_point = 50,
-- ^ Characteristic average temperature and humidity for the biome.
-- ^ These values create 'biome points' on a voronoi diagram that has heat
-- ^ and humidity as axes. The resulting voronoi cells determine which
-- ^ heat/humidity points belong to which biome, and therefore determine
-- ^ the area and location of each biome in the world.
-- ^ The biome points need to be carefully and evenly spaced on the voronoi
-- ^ diagram to result in roughly equal size biomes.
-- ^ Characteristic temperature and humidity for the biome.
-- ^ These values create 'biome points' on a voronoi diagram with heat and
-- ^ humidity as axes. The resulting voronoi cells determine the
-- ^ distribution of the biomes.
-- ^ Heat and humidity have average values of 50, vary mostly between
-- ^ 0 and 100 but also often exceed these values.
-- ^ Heat is not in degrees Celsius, both values are abstract.
-- ^ 0 and 100 but can exceed these values.
}

### Decoration definition (`register_decoration`)
Expand Down
37 changes: 27 additions & 10 deletions src/mapgen/mg_biome.cpp
Expand Up @@ -50,6 +50,7 @@ BiomeManager::BiomeManager(Server *server) :
b->y_max = MAX_MAP_GENERATION_LIMIT;
b->heat_point = 0.0;
b->humidity_point = 0.0;
b->vertical_blend = 0;

b->m_nodenames.emplace_back("mapgen_stone");
b->m_nodenames.emplace_back("mapgen_stone");
Expand Down Expand Up @@ -201,25 +202,41 @@ Biome *BiomeGenOriginal::getBiomeAtIndex(size_t index, s16 y) const

Biome *BiomeGenOriginal::calcBiomeFromNoise(float heat, float humidity, s16 y) const
{
Biome *b, *biome_closest = NULL;
Biome *biome_closest = nullptr;
Biome *biome_closest_blend = nullptr;
float dist_min = FLT_MAX;
float dist_min_blend = 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)
Biome *b = (Biome *)m_bmgr->getRaw(i);
if (!b || y > b->y_max + b->vertical_blend || y < b->y_min)
continue;

float d_heat = heat - b->heat_point;
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;
float dist = (d_heat * d_heat) + (d_humidity * d_humidity);

if (y <= b->y_max) { // Within y limits of biome b
if (dist < dist_min) {
dist_min = dist;
biome_closest = b;
}
} else if (dist < dist_min_blend) { // Blend area above biome b
dist_min_blend = dist;
biome_closest_blend = b;
}
}

return biome_closest ? biome_closest : (Biome *)m_bmgr->getRaw(BIOME_NONE);
// Carefully tune pseudorandom seed variation to avoid single node dither
// and create larger scale blending patterns.
mysrand(y + (heat - humidity) * 2);

if (biome_closest_blend &&
myrand_range(0, biome_closest_blend->vertical_blend) >=
y - biome_closest_blend->y_max)
return biome_closest_blend;

return (biome_closest) ? biome_closest : (Biome *)m_bmgr->getRaw(BIOME_NONE);
}


Expand Down
1 change: 1 addition & 0 deletions src/mapgen/mg_biome.h
Expand Up @@ -67,6 +67,7 @@ class Biome : public ObjDef, public NodeResolver {
s16 y_max;
float heat_point;
float humidity_point;
s16 vertical_blend;

virtual void resolveNodeNames();
};
Expand Down
1 change: 1 addition & 0 deletions src/script/lua_api/l_mapgen.cpp
Expand Up @@ -392,6 +392,7 @@ Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef)
b->y_max = getintfield_default(L, index, "y_max", 31000);
b->heat_point = getfloatfield_default(L, index, "heat_point", 0.f);
b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.f);
b->vertical_blend = getintfield_default(L, index, "vertical_blend", 0);
b->flags = 0; //reserved

std::vector<std::string> &nn = b->m_nodenames;
Expand Down

0 comments on commit 549cfd9

Please sign in to comment.