forked from Mirrorlandia_minetest/minetest
Decoration API: Add lightweight ability to have complete coverage (#7456)
When the noise value or fill_ratio >= 10.0 complete coverage is enabled. This disables random placement to avoid redundant multiple placements at one position. Instead, 1 decoration per surface node is placed by looping across each division. '10' was chosen as this is the fill_ratio that previously created very near complete coverage. The complete coverage feature therefore integrates smoothly when noise is used for variable decoration density. 'fill_ratio = 10' should be used by modders who want a decoration placed on every surface node. Compared to before such a decoration placement will be 10 times faster.
This commit is contained in:
parent
1d1cf000c0
commit
de621d5d4b
@ -5769,6 +5769,8 @@ Definition tables
|
|||||||
fill_ratio = 0.02,
|
fill_ratio = 0.02,
|
||||||
-- ^ The value determines 'decorations per surface node'.
|
-- ^ The value determines 'decorations per surface node'.
|
||||||
-- ^ Used only if noise_params is not specified.
|
-- ^ Used only if noise_params is not specified.
|
||||||
|
-- ^ If >= 10.0 complete coverage is enabled and decoration placement uses
|
||||||
|
-- ^ a different and much faster method.
|
||||||
noise_params = {
|
noise_params = {
|
||||||
offset = 0,
|
offset = 0,
|
||||||
scale = 0.45,
|
scale = 0.45,
|
||||||
@ -5783,6 +5785,8 @@ Definition tables
|
|||||||
-- ^ distribution.
|
-- ^ distribution.
|
||||||
-- ^ A noise value is calculated for each square division and determines
|
-- ^ A noise value is calculated for each square division and determines
|
||||||
-- ^ 'decorations per surface node' within each division.
|
-- ^ 'decorations per surface node' within each division.
|
||||||
|
-- ^ If the noise value >= 10.0 complete coverage is enabled and decoration
|
||||||
|
-- ^ placement uses a different and much faster method.
|
||||||
biomes = {"Oceanside", "Hills", "Plains"},
|
biomes = {"Oceanside", "Hills", "Plains"},
|
||||||
-- ^ List of biomes in which this decoration occurs. Occurs in all biomes
|
-- ^ List of biomes in which this decoration occurs. Occurs in all biomes
|
||||||
-- ^ if this is omitted, and ignored if the Mapgen being used does not
|
-- ^ if this is omitted, and ignored if the Mapgen being used does not
|
||||||
|
@ -155,23 +155,43 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
|||||||
nmin.Z + sidelen + sidelen * z0 - 1
|
nmin.Z + sidelen + sidelen * z0 - 1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
bool cover = false;
|
||||||
// Amount of decorations
|
// Amount of decorations
|
||||||
float nval = (flags & DECO_USE_NOISE) ?
|
float nval = (flags & DECO_USE_NOISE) ?
|
||||||
NoisePerlin2D(&np, p2d_center.X, p2d_center.Y, mapseed) :
|
NoisePerlin2D(&np, p2d_center.X, p2d_center.Y, mapseed) :
|
||||||
fill_ratio;
|
fill_ratio;
|
||||||
u32 deco_count = 0;
|
u32 deco_count = 0;
|
||||||
float deco_count_f = (float)area * nval;
|
|
||||||
if (deco_count_f >= 1.f) {
|
if (nval >= 10.0f) {
|
||||||
deco_count = deco_count_f;
|
// Complete coverage. Disable random placement to avoid
|
||||||
} else if (deco_count_f > 0.f) {
|
// redundant multiple placements at one position.
|
||||||
// For low density decorations calculate a chance for 1 decoration
|
cover = true;
|
||||||
if (ps.range(1000) <= deco_count_f * 1000.f)
|
deco_count = area;
|
||||||
deco_count = 1;
|
} else {
|
||||||
|
float deco_count_f = (float)area * nval;
|
||||||
|
if (deco_count_f >= 1.0f) {
|
||||||
|
deco_count = deco_count_f;
|
||||||
|
} else if (deco_count_f > 0.0f) {
|
||||||
|
// For very low density calculate a chance for 1 decoration
|
||||||
|
if (ps.range(1000) <= deco_count_f * 1000.0f)
|
||||||
|
deco_count = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s16 x = p2d_min.X - 1;
|
||||||
|
s16 z = p2d_min.Y;
|
||||||
|
|
||||||
for (u32 i = 0; i < deco_count; i++) {
|
for (u32 i = 0; i < deco_count; i++) {
|
||||||
s16 x = ps.range(p2d_min.X, p2d_max.X);
|
if (!cover) {
|
||||||
s16 z = ps.range(p2d_min.Y, p2d_max.Y);
|
x = ps.range(p2d_min.X, p2d_max.X);
|
||||||
|
z = ps.range(p2d_min.Y, p2d_max.Y);
|
||||||
|
} else {
|
||||||
|
x++;
|
||||||
|
if (x == p2d_max.X + 1) {
|
||||||
|
z++;
|
||||||
|
x = p2d_min.X;
|
||||||
|
}
|
||||||
|
}
|
||||||
int mapindex = carea_size * (z - nmin.Z) + (x - nmin.X);
|
int mapindex = carea_size * (z - nmin.Z) + (x - nmin.X);
|
||||||
|
|
||||||
if ((flags & DECO_ALL_FLOORS) ||
|
if ((flags & DECO_ALL_FLOORS) ||
|
||||||
|
Loading…
Reference in New Issue
Block a user