1
0
mirror of https://github.com/moparisthebest/minetest synced 2024-12-23 08:08:47 -05:00

Add flags and lacunarity as new noise parameters

Add 'absolute value' option to noise map functions
Extend persistence modulation to 3D noise
Extend 'eased' option to noise2d_perlin* functions
Some noise.cpp formatting fixups
This commit is contained in:
kwolekr 2014-12-07 21:57:12 -05:00
parent 638f3a8454
commit 2fd3d52020
16 changed files with 306 additions and 214 deletions

View File

@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapgen_v7.h"
#include "cavegen.h"
NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6);
NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0);
///////////////////////////////////////////////////////////////////////////////

View File

@ -31,9 +31,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
//#define DGEN_USE_TORCHES
NoiseParams nparams_dungeon_rarity(0.0, 1.0, v3f(500.0, 500.0, 500.0), 0, 2, 0.8);
NoiseParams nparams_dungeon_wetness(0.0, 1.0, v3f(40.0, 40.0, 40.0), 32474, 4, 1.1);
NoiseParams nparams_dungeon_density(0.0, 1.0, v3f(2.5, 2.5, 2.5), 0, 2, 1.4);
NoiseParams nparams_dungeon_rarity(0.0, 1.0, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0);
NoiseParams nparams_dungeon_wetness(0.0, 1.0, v3f(40.0, 40.0, 40.0), 32474, 4, 1.1, 2.0);
NoiseParams nparams_dungeon_density(0.0, 1.0, v3f(2.5, 2.5, 2.5), 0, 2, 1.4, 2.0);
///////////////////////////////////////////////////////////////////////////////

View File

@ -130,14 +130,14 @@ MapgenV5::~MapgenV5() {
MapgenV5Params::MapgenV5Params() {
spflags = MGV5_BLOBS;
np_filler_depth = NoiseParams(0, 1, v3f(150, 150, 150), 261, 4, 0.7);
np_factor = NoiseParams(0, 1, v3f(250, 250, 250), 920381, 3, 0.45);
np_height = NoiseParams(0, 10, v3f(250, 250, 250), 84174, 4, 0.5);
np_cave1 = NoiseParams(0, 6, v3f(50, 50, 50), 52534, 4, 0.5);
np_cave2 = NoiseParams(0, 6, v3f(50, 50, 50), 10325, 4, 0.5);
np_ground = NoiseParams(0, 40, v3f(80, 80, 80), 983240, 4, 0.55);
np_crumble = NoiseParams(0, 1, v3f(20, 20, 20), 34413, 3, 1.3);
np_wetness = NoiseParams(0, 1, v3f(40, 40, 40), 32474, 4, 1.1);
np_filler_depth = NoiseParams(0, 1, v3f(150, 150, 150), 261, 4, 0.7, 2.0);
np_factor = NoiseParams(0, 1, v3f(250, 250, 250), 920381, 3, 0.45, 2.0);
np_height = NoiseParams(0, 10, v3f(250, 250, 250), 84174, 4, 0.5, 2.0);
np_cave1 = NoiseParams(0, 6, v3f(50, 50, 50), 52534, 4, 0.5, 2.0, NOISE_FLAG_EASED);
np_cave2 = NoiseParams(0, 6, v3f(50, 50, 50), 10325, 4, 0.5, 2.0, NOISE_FLAG_EASED);
np_ground = NoiseParams(0, 40, v3f(80, 80, 80), 983240, 4, 0.55, 2.0, NOISE_FLAG_EASED);
np_crumble = NoiseParams(0, 1, v3f(20, 20, 20), 34413, 3, 1.3, 2.0, NOISE_FLAG_EASED);
np_wetness = NoiseParams(0, 1, v3f(40, 40, 40), 32474, 4, 1.1, 2.0);
}
@ -301,16 +301,16 @@ void MapgenV5::calculateNoise() {
noise_height->perlinMap2D(x, z);
noise_height->transformNoiseMap();
noise_cave1->perlinMap3D(x, y, z, true);
noise_cave1->perlinMap3D(x, y, z);
noise_cave1->transformNoiseMap();
noise_cave2->perlinMap3D(x, y, z, true);
noise_cave2->perlinMap3D(x, y, z);
noise_cave2->transformNoiseMap();
noise_ground->perlinMap3D(x, y, z, true);
noise_ground->perlinMap3D(x, y, z);
noise_ground->transformNoiseMap();
if (spflags & MGV5_BLOBS) {
noise_crumble->perlinMap3D(x, y, z, true);
noise_wetness->perlinMap3D(x, y, z, false);
noise_crumble->perlinMap3D(x, y, z);
noise_wetness->perlinMap3D(x, y, z);
}
noise_heat->perlinMap2D(x, z);

View File

@ -122,17 +122,17 @@ MapgenV6Params::MapgenV6Params() {
freq_desert = 0.45;
freq_beach = 0.15;
np_terrain_base = NoiseParams(-4, 20.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6);
np_terrain_higher = NoiseParams(20, 16.0, v3f(500.0, 500.0, 500.0), 85039, 5, 0.6);
np_steepness = NoiseParams(0.85,0.5, v3f(125.0, 125.0, 125.0), -932, 5, 0.7);
np_height_select = NoiseParams(0.5, 1.0, v3f(250.0, 250.0, 250.0), 4213, 5, 0.69);
np_mud = NoiseParams(4, 2.0, v3f(200.0, 200.0, 200.0), 91013, 3, 0.55);
np_beach = NoiseParams(0, 1.0, v3f(250.0, 250.0, 250.0), 59420, 3, 0.50);
np_biome = NoiseParams(0, 1.0, v3f(250.0, 250.0, 250.0), 9130, 3, 0.50);
np_cave = NoiseParams(6, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50);
np_humidity = NoiseParams(0.5, 0.5, v3f(500.0, 500.0, 500.0), 72384, 4, 0.66);
np_trees = NoiseParams(0, 1.0, v3f(125.0, 125.0, 125.0), 2, 4, 0.66);
np_apple_trees = NoiseParams(0, 1.0, v3f(100.0, 100.0, 100.0), 342902, 3, 0.45);
np_terrain_base = NoiseParams(-4, 20.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6, 2.0);
np_terrain_higher = NoiseParams(20, 16.0, v3f(500.0, 500.0, 500.0), 85039, 5, 0.6, 2.0);
np_steepness = NoiseParams(0.85,0.5, v3f(125.0, 125.0, 125.0), -932, 5, 0.7, 2.0);
np_height_select = NoiseParams(0.5, 1.0, v3f(250.0, 250.0, 250.0), 4213, 5, 0.69, 2.0);
np_mud = NoiseParams(4, 2.0, v3f(200.0, 200.0, 200.0), 91013, 3, 0.55, 2.0);
np_beach = NoiseParams(0, 1.0, v3f(250.0, 250.0, 250.0), 59420, 3, 0.50, 2.0);
np_biome = NoiseParams(0, 1.0, v3f(250.0, 250.0, 250.0), 9130, 3, 0.50, 2.0);
np_cave = NoiseParams(6, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50, 2.0);
np_humidity = NoiseParams(0.5, 0.5, v3f(500.0, 500.0, 500.0), 72384, 4, 0.66, 2.0);
np_trees = NoiseParams(0, 1.0, v3f(125.0, 125.0, 125.0), 2, 4, 0.66, 2.0);
np_apple_trees = NoiseParams(0, 1.0, v3f(100.0, 100.0, 100.0), 342902, 3, 0.45, 2.0);
}

View File

@ -122,15 +122,15 @@ MapgenV7::~MapgenV7() {
MapgenV7Params::MapgenV7Params() {
spflags = MGV7_MOUNTAINS | MGV7_RIDGES;
np_terrain_base = NoiseParams(4, 70, v3f(300, 300, 300), 82341, 6, 0.7);
np_terrain_alt = NoiseParams(4, 25, v3f(600, 600, 600), 5934, 5, 0.6);
np_terrain_persist = NoiseParams(0.6, 0.1, v3f(500, 500, 500), 539, 3, 0.6);
np_height_select = NoiseParams(-0.5, 1, v3f(250, 250, 250), 4213, 5, 0.69);
np_filler_depth = NoiseParams(0, 1.2, v3f(150, 150, 150), 261, 4, 0.7);
np_mount_height = NoiseParams(100, 30, v3f(500, 500, 500), 72449, 4, 0.6);
np_ridge_uwater = NoiseParams(0, 1, v3f(500, 500, 500), 85039, 4, 0.6);
np_mountain = NoiseParams(0, 1, v3f(250, 350, 250), 5333, 5, 0.68);
np_ridge = NoiseParams(0, 1, v3f(100, 100, 100), 6467, 4, 0.75);
np_terrain_base = NoiseParams(4, 70, v3f(300, 300, 300), 82341, 6, 0.7, 2.0);
np_terrain_alt = NoiseParams(4, 25, v3f(600, 600, 600), 5934, 5, 0.6, 2.0);
np_terrain_persist = NoiseParams(0.6, 0.1, v3f(500, 500, 500), 539, 3, 0.6, 2.0);
np_height_select = NoiseParams(-0.5, 1, v3f(250, 250, 250), 4213, 5, 0.69, 2.0);
np_filler_depth = NoiseParams(0, 1.2, v3f(150, 150, 150), 261, 4, 0.7, 2.0);
np_mount_height = NoiseParams(100, 30, v3f(500, 500, 500), 72449, 4, 0.6, 2.0);
np_ridge_uwater = NoiseParams(0, 1, v3f(500, 500, 500), 85039, 4, 0.6, 2.0);
np_mountain = NoiseParams(0, 1, v3f(250, 350, 250), 5333, 5, 0.68, 2.0);
np_ridge = NoiseParams(0, 1, v3f(100, 100, 100), 6467, 4, 0.75, 2.0);
}
@ -278,10 +278,10 @@ void MapgenV7::calculateNoise() {
for (int i = 0; i != csize.X * csize.Z; i++)
persistmap[i] = rangelim(persistmap[i], 0.4, 0.9);
noise_terrain_base->perlinMap2DModulated(x, z, persistmap);
noise_terrain_base->perlinMap2D(x, z, persistmap);
noise_terrain_base->transformNoiseMap();
noise_terrain_alt->perlinMap2DModulated(x, z, persistmap);
noise_terrain_alt->perlinMap2D(x, z, persistmap);
noise_terrain_alt->transformNoiseMap();
noise_filler_depth->perlinMap2D(x, z);
@ -728,7 +728,7 @@ void MapgenV7::addTopNodes() {
#endif
NoiseParams nparams_v7_def_cave(6, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50);
NoiseParams nparams_v7_def_cave(6, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50, 2.0);
void MapgenV7::generateCaves(int max_stone_y) {
PseudoRandom ps(blockseed + 21343);

View File

@ -29,8 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
const char *BiomeManager::ELEMENT_TITLE = "biome";
NoiseParams nparams_biome_def_heat(50, 50, v3f(500.0, 500.0, 500.0), 5349, 3, 0.70);
NoiseParams nparams_biome_def_humidity(50, 50, v3f(500.0, 500.0, 500.0), 842, 3, 0.55);
NoiseParams nparams_biome_def_heat(50, 50, v3f(500.0, 500.0, 500.0), 5349, 3, 0.70, 2.0);
NoiseParams nparams_biome_def_humidity(50, 50, v3f(500.0, 500.0, 500.0), 842, 3, 0.55, 2.0);
///////////////////////////////////////////////////////////////////////////////

View File

@ -29,6 +29,7 @@
#include <string.h> // memset
#include "debug.h"
#include "util/numeric.h"
#include "util/string.h"
#include "exceptions.h"
#define NOISE_MAGIC_X 1619
@ -36,6 +37,10 @@
#define NOISE_MAGIC_Z 52591
#define NOISE_MAGIC_SEED 1013
typedef float (*Interp2dFxn)(
float v00, float v10, float v01, float v11,
float x, float y);
typedef float (*Interp3dFxn)(
float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111,
@ -46,11 +51,18 @@ float cos_lookup[16] = {
1.0, -0.9238, -0.7071, -0.3826, 0, 0.3826, 0.7071, 0.9238
};
FlagDesc flagdesc_noiseparams[] = {
{"defaults", NOISE_FLAG_DEFAULTS},
{"eased", NOISE_FLAG_EASED},
{"absvalue", NOISE_FLAG_ABSVALUE},
{"pointbuffer", NOISE_FLAG_POINTBUFFER},
{"simplex", NOISE_FLAG_SIMPLEX},
{NULL, 0}
};
///////////////////////////////////////////////////////////////////////////////
//noise poly: p(n) = 60493n^3 + 19990303n + 137612589
float noise2d(int x, int y, int seed)
{
int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y
@ -79,95 +91,85 @@ float dotProduct(float vx, float vy, float wx, float wy)
inline float linearInterpolation(float v0, float v1, float t)
{
return v0 + (v1 - v0) * t;
return v0 + (v1 - v0) * t;
}
float biLinearInterpolation(
float v00, float v10,
float v01, float v11,
float x, float y)
float v00, float v10,
float v01, float v11,
float x, float y)
{
float tx = easeCurve(x);
float ty = easeCurve(y);
float u = linearInterpolation(v00, v10, tx);
float v = linearInterpolation(v01, v11, tx);
return linearInterpolation(u, v, ty);
float tx = easeCurve(x);
float ty = easeCurve(y);
return (
v00 * (1 - tx) * (1 - ty) +
v10 * tx * (1 - ty) +
v01 * (1 - tx) * ty +
v11 * tx * ty
);
//float u = linearInterpolation(v00, v10, x);
//float v = linearInterpolation(v01, v11, x);
//return linearInterpolation(u, v, y);
}
float biLinearInterpolationNoEase(
float x0y0, float x1y0,
float x0y1, float x1y1,
float x, float y)
float v00, float v10,
float v01, float v11,
float x, float y)
{
float u = linearInterpolation(x0y0, x1y0, x);
float v = linearInterpolation(x0y1, x1y1, x);
return linearInterpolation(u, v, y);
float tx = x;
float ty = y;
return (
v00 * (1 - tx) * (1 - ty) +
v10 * tx * (1 - ty) +
v01 * (1 - tx) * ty +
v11 * tx * ty
);
}
/*
float triLinearInterpolation(
float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111,
float x, float y, float z)
{
float u = biLinearInterpolation(v000, v100, v010, v110, x, y);
float v = biLinearInterpolation(v001, v101, v011, v111, x, y);
return linearInterpolation(u, v, z);
}
float triLinearInterpolationNoEase(
float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111,
float x, float y, float z)
{
float u = biLinearInterpolationNoEase(v000, v100, v010, v110, x, y);
float v = biLinearInterpolationNoEase(v001, v101, v011, v111, x, y);
return linearInterpolation(u, v, z);
}
*/
float triLinearInterpolation(
float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111,
float x, float y, float z)
float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111,
float x, float y, float z)
{
float tx = easeCurve(x);
float ty = easeCurve(y);
float tz = easeCurve(z);
return (
v000 * (1 - tx) * (1 - ty) * (1 - tz) +
v100 * tx * (1 - ty) * (1 - tz) +
v010 * (1 - tx) * ty * (1 - tz) +
v110 * tx * ty * (1 - tz) +
v001 * (1 - tx) * (1 - ty) * tz +
v101 * tx * (1 - ty) * tz +
v011 * (1 - tx) * ty * tz +
v111 * tx * ty * tz
v100 * tx * (1 - ty) * (1 - tz) +
v010 * (1 - tx) * ty * (1 - tz) +
v110 * tx * ty * (1 - tz) +
v001 * (1 - tx) * (1 - ty) * tz +
v101 * tx * (1 - ty) * tz +
v011 * (1 - tx) * ty * tz +
v111 * tx * ty * tz
);
//float u = biLinearInterpolation(v000, v100, v010, v110, x, y);
//float v = biLinearInterpolation(v001, v101, v011, v111, x, y);
//return linearInterpolation(u, v, z);
}
float triLinearInterpolationNoEase(
float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111,
float x, float y, float z)
float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111,
float x, float y, float z)
{
float tx = x;
float ty = y;
float tz = z;
return (
v000 * (1 - tx) * (1 - ty) * (1 - tz) +
v100 * tx * (1 - ty) * (1 - tz) +
v010 * (1 - tx) * ty * (1 - tz) +
v110 * tx * ty * (1 - tz) +
v001 * (1 - tx) * (1 - ty) * tz +
v101 * tx * (1 - ty) * tz +
v011 * (1 - tx) * ty * tz +
v111 * tx * ty * tz
v100 * tx * (1 - ty) * (1 - tz) +
v010 * (1 - tx) * ty * (1 - tz) +
v110 * tx * ty * (1 - tz) +
v001 * (1 - tx) * (1 - ty) * tz +
v101 * tx * (1 - ty) * tz +
v011 * (1 - tx) * ty * tz +
v111 * tx * ty * tz
);
}
@ -198,7 +200,7 @@ float noise2d_gradient(float x, float y, int seed)
#endif
float noise2d_gradient(float x, float y, int seed)
float noise2d_gradient(float x, float y, int seed, bool eased)
{
// Calculate the integer coordinates
int x0 = myfloor(x);
@ -212,7 +214,10 @@ float noise2d_gradient(float x, float y, int seed)
float v01 = noise2d(x0, y0+1, seed);
float v11 = noise2d(x0+1, y0+1, seed);
// Interpolate
return biLinearInterpolation(v00, v10, v01, v11, xl, yl);
if (eased)
return biLinearInterpolation(v00, v10, v01, v11, xl, yl);
else
return biLinearInterpolationNoEase(v00, v10, v01, v11, xl, yl);
}
@ -251,14 +256,14 @@ float noise3d_gradient(float x, float y, float z, int seed, bool eased)
float noise2d_perlin(float x, float y, int seed,
int octaves, float persistence)
int octaves, float persistence, bool eased)
{
float a = 0;
float f = 1.0;
float g = 1.0;
for (int i = 0; i < octaves; i++)
{
a += g * noise2d_gradient(x * f, y * f, seed + i);
a += g * noise2d_gradient(x * f, y * f, seed + i, eased);
f *= 2.0;
g *= persistence;
}
@ -267,14 +272,13 @@ float noise2d_perlin(float x, float y, int seed,
float noise2d_perlin_abs(float x, float y, int seed,
int octaves, float persistence)
int octaves, float persistence, bool eased)
{
float a = 0;
float f = 1.0;
float g = 1.0;
for (int i = 0; i < octaves; i++)
{
a += g * fabs(noise2d_gradient(x * f, y * f, seed + i));
for (int i = 0; i < octaves; i++) {
a += g * fabs(noise2d_gradient(x * f, y * f, seed + i, eased));
f *= 2.0;
g *= persistence;
}
@ -283,13 +287,12 @@ float noise2d_perlin_abs(float x, float y, int seed,
float noise3d_perlin(float x, float y, float z, int seed,
int octaves, float persistence, bool eased)
int octaves, float persistence, bool eased)
{
float a = 0;
float f = 1.0;
float g = 1.0;
for (int i = 0; i < octaves; i++)
{
for (int i = 0; i < octaves; i++) {
a += g * noise3d_gradient(x * f, y * f, z * f, seed + i, eased);
f *= 2.0;
g *= persistence;
@ -299,13 +302,12 @@ float noise3d_perlin(float x, float y, float z, int seed,
float noise3d_perlin_abs(float x, float y, float z, int seed,
int octaves, float persistence, bool eased)
int octaves, float persistence, bool eased)
{
float a = 0;
float f = 1.0;
float g = 1.0;
for (int i = 0; i < octaves; i++)
{
for (int i = 0; i < octaves; i++) {
a += g * fabs(noise3d_gradient(x * f, y * f, z * f, seed + i, eased));
f *= 2.0;
g *= persistence;
@ -317,7 +319,7 @@ float noise3d_perlin_abs(float x, float y, float z, int seed,
float contour(float v)
{
v = fabs(v);
if(v >= 1.0)
if (v >= 1.0)
return 0.0;
return (1.0 - v);
}
@ -335,6 +337,12 @@ Noise::Noise(NoiseParams *np, int seed, int sx, int sy, int sz)
this->sz = sz;
this->noisebuf = NULL;
if (np->flags & NOISE_FLAG_DEFAULTS) {
// By default, only 2d noise is eased.
if (sz == 1)
np->flags |= NOISE_FLAG_EASED;
}
resizeNoiseBuf(sz > 1);
try {
@ -437,6 +445,9 @@ void Noise::gradientMap2D(
int index, i, j, x0, y0, noisex, noisey;
int nlx, nly;
Interp2dFxn interpolate = (np->flags & NOISE_FLAG_EASED) ?
biLinearInterpolation : biLinearInterpolationNoEase;
x0 = floor(x);
y0 = floor(y);
u = x - (float)x0;
@ -463,7 +474,7 @@ void Noise::gradientMap2D(
u = orig_u;
noisex = 0;
for (i = 0; i != sx; i++) {
buf[index++] = biLinearInterpolation(v00, v10, v01, v11, u, v);
buf[index++] = interpolate(v00, v10, v01, v11, u, v);
u += step_x;
if (u >= 1.0) {
u -= 1.0;
@ -489,7 +500,7 @@ void Noise::gradientMap2D(
void Noise::gradientMap3D(
float x, float y, float z,
float step_x, float step_y, float step_z,
int seed, bool eased)
int seed)
{
float v000, v010, v100, v110;
float v001, v011, v101, v111;
@ -497,7 +508,7 @@ void Noise::gradientMap3D(
int index, i, j, k, x0, y0, z0, noisex, noisey, noisez;
int nlx, nly, nlz;
Interp3dFxn interpolate = eased ?
Interp3dFxn interpolate = (np->flags & NOISE_FLAG_EASED) ?
triLinearInterpolation : triLinearInterpolationNoEase;
x0 = floor(x);
@ -576,7 +587,7 @@ void Noise::gradientMap3D(
#undef idx
float *Noise::perlinMap2D(float x, float y)
float *Noise::perlinMap2D(float x, float y, float *persistence_map)
{
float f = 1.0, g = 1.0;
size_t bufsize = sx * sy;
@ -586,55 +597,30 @@ float *Noise::perlinMap2D(float x, float y)
memset(result, 0, sizeof(float) * bufsize);
for (int oct = 0; oct < np->octaves; oct++) {
float *gmap = NULL;
if (persistence_map) {
gmap = new float[bufsize];
for (size_t i = 0; i != bufsize; i++)
gmap[i] = 1.0;
}
for (size_t oct = 0; oct < np->octaves; oct++) {
gradientMap2D(x * f, y * f,
f / np->spread.X, f / np->spread.Y,
seed + np->seed + oct);
for (size_t i = 0; i != bufsize; i++)
result[i] += g * buf[i];
updateResults(g, gmap, persistence_map, bufsize);
f *= 2.0;
f *= np->lacunarity;
g *= np->persist;
}
delete[] gmap;
return result;
}
float *Noise::perlinMap2DModulated(float x, float y, float *persist_map)
{
float f = 1.0;
size_t bufsize = sx * sy;
x /= np->spread.X;
y /= np->spread.Y;
memset(result, 0, sizeof(float) * bufsize);
float *g = new float[bufsize];
for (size_t i = 0; i != bufsize; i++)
g[i] = 1.0;
for (int oct = 0; oct < np->octaves; oct++) {
gradientMap2D(x * f, y * f,
f / np->spread.X, f / np->spread.Y,
seed + np->seed + oct);
for (size_t i = 0; i != bufsize; i++) {
result[i] += g[i] * buf[i];
g[i] *= persist_map[i];
}
f *= 2.0;
}
delete[] g;
return result;
}
float *Noise::perlinMap3D(float x, float y, float z, bool eased)
float *Noise::perlinMap3D(float x, float y, float z, float *persistence_map)
{
float f = 1.0, g = 1.0;
size_t bufsize = sx * sy * sz;
@ -645,22 +631,58 @@ float *Noise::perlinMap3D(float x, float y, float z, bool eased)
memset(result, 0, sizeof(float) * bufsize);
for (int oct = 0; oct < np->octaves; oct++) {
float *gmap = NULL;
if (persistence_map) {
gmap = new float[bufsize];
for (size_t i = 0; i != bufsize; i++)
gmap[i] = 1.0;
}
for (size_t oct = 0; oct < np->octaves; oct++) {
gradientMap3D(x * f, y * f, z * f,
f / np->spread.X, f / np->spread.Y, f / np->spread.Z,
seed + np->seed + oct, eased);
seed + np->seed + oct);
for (size_t i = 0; i != bufsize; i++)
result[i] += g * buf[i];
updateResults(g, gmap, persistence_map, bufsize);
f *= 2.0;
f *= np->lacunarity;
g *= np->persist;
}
delete[] gmap;
return result;
}
void Noise::updateResults(float g, float *gmap,
float *persistence_map, size_t bufsize)
{
// This looks very ugly, but it is 50-70% faster than having
// conditional statements inside the loop
if (np->flags & NOISE_FLAG_ABSVALUE) {
if (persistence_map) {
for (size_t i = 0; i != bufsize; i++) {
result[i] += gmap[i] * fabs(buf[i]);
gmap[i] *= persistence_map[i];
}
} else {
for (size_t i = 0; i != bufsize; i++)
result[i] += g * fabs(buf[i]);
}
} else {
if (persistence_map) {
for (size_t i = 0; i != bufsize; i++) {
result[i] += gmap[i] * buf[i];
gmap[i] *= persistence_map[i];
}
} else {
for (size_t i = 0; i != bufsize; i++)
result[i] += g * buf[i];
}
}
}
void Noise::transformNoiseMap()
{
size_t i = 0;

View File

@ -28,6 +28,9 @@
#include "debug.h"
#include "irr_v3d.h"
#include "util/string.h"
extern FlagDesc flagdesc_noiseparams[];
class PseudoRandom
{
@ -66,6 +69,14 @@ private:
int m_next;
};
#define NOISE_FLAG_DEFAULTS 0x01
#define NOISE_FLAG_EASED 0x02
#define NOISE_FLAG_ABSVALUE 0x04
//// TODO(hmmmm): implement these!
#define NOISE_FLAG_POINTBUFFER 0x08
#define NOISE_FLAG_SIMPLEX 0x10
struct NoiseParams {
float offset;
float scale;
@ -73,20 +84,32 @@ struct NoiseParams {
s32 seed;
u16 octaves;
float persist;
bool eased;
float lacunarity;
u32 flags;
NoiseParams() {}
NoiseParams() {
offset = 0.0f;
scale = 1.0f;
spread = v3f(250, 250, 250);
seed = 12345;
octaves = 3;
persist = 0.6f;
lacunarity = 2.0f;
flags = NOISE_FLAG_DEFAULTS;
}
NoiseParams(float offset_, float scale_, v3f spread_,
int seed_, int octaves_, float persist_, bool eased_=false)
NoiseParams(float offset_, float scale_, v3f spread_, s32 seed_,
u16 octaves_, float persist_, float lacunarity_,
u32 flags_=NOISE_FLAG_DEFAULTS)
{
offset = offset_;
scale = scale_;
spread = spread_;
seed = seed_;
octaves = octaves_;
persist = persist_;
eased = eased_;
offset = offset_;
scale = scale_;
spread = spread_;
seed = seed_;
octaves = octaves_;
persist = persist_;
lacunarity = lacunarity_;
flags = flags_;
}
};
@ -123,10 +146,12 @@ public:
void gradientMap3D(
float x, float y, float z,
float step_x, float step_y, float step_z,
int seed, bool eased=false);
float *perlinMap2D(float x, float y);
float *perlinMap2DModulated(float x, float y, float *persist_map);
float *perlinMap3D(float x, float y, float z, bool eased=false);
int seed);
float *perlinMap2D(float x, float y, float *persistence_map=NULL);
float *perlinMap3D(float x, float y, float z, float *persistence_map=NULL);
void updateResults(float g, float *gmap, float *persistence_map, size_t bufsize);
void transformNoiseMap();
};
@ -134,14 +159,14 @@ public:
float noise2d(int x, int y, int seed);
float noise3d(int x, int y, int z, int seed);
float noise2d_gradient(float x, float y, int seed);
float noise2d_gradient(float x, float y, int seed, bool eased=true);
float noise3d_gradient(float x, float y, float z, int seed, bool eased=false);
float noise2d_perlin(float x, float y, int seed,
int octaves, float persistence);
int octaves, float persistence, bool eased=true);
float noise2d_perlin_abs(float x, float y, int seed,
int octaves, float persistence);
int octaves, float persistence, bool eased=true);
float noise3d_perlin(float x, float y, float z, int seed,
int octaves, float persistence, bool eased=false);

View File

@ -975,11 +975,11 @@ void luaentity_get(lua_State *L, u16 id)
}
/******************************************************************************/
NoiseParams *read_noiseparams(lua_State *L, int index)
NoiseParams *get_noiseparams(lua_State *L, int index)
{
NoiseParams *np = new NoiseParams;
if (!read_noiseparams_nc(L, index, np)) {
if (!read_noiseparams(L, index, np)) {
delete np;
np = NULL;
}
@ -987,7 +987,7 @@ NoiseParams *read_noiseparams(lua_State *L, int index)
return np;
}
bool read_noiseparams_nc(lua_State *L, int index, NoiseParams *np)
bool read_noiseparams(lua_State *L, int index, NoiseParams *np)
{
if (index < 0)
index = lua_gettop(L) + 1 + index;
@ -995,12 +995,16 @@ bool read_noiseparams_nc(lua_State *L, int index, NoiseParams *np)
if (!lua_istable(L, index))
return false;
np->offset = getfloatfield_default(L, index, "offset", 0.0);
np->scale = getfloatfield_default(L, index, "scale", 0.0);
np->persist = getfloatfield_default(L, index, "persist", 0.0);
np->seed = getintfield_default(L, index, "seed", 0);
np->octaves = getintfield_default(L, index, "octaves", 0);
np->eased = getboolfield_default(L, index, "eased", false);
np->offset = getfloatfield_default(L, index, "offset", 0.0);
np->scale = getfloatfield_default(L, index, "scale", 0.0);
np->persist = getfloatfield_default(L, index, "persist", 0.0);
np->lacunarity = getfloatfield_default(L, index, "lacunarity", 2.0);
np->seed = getintfield_default(L, index, "seed", 0);
np->octaves = getintfield_default(L, index, "octaves", 0);
u32 flags = 0, flagmask = 0;
np->flags = getflagsfield(L, index, "flags", flagdesc_noiseparams,
&flags, &flagmask) ? flags : NOISE_FLAG_DEFAULTS;
lua_getfield(L, index, "spread");
np->spread = read_v3f(L, -1);

View File

@ -147,9 +147,9 @@ bool string_to_enum (const EnumString *spec,
int &result,
const std::string &str);
NoiseParams* read_noiseparams (lua_State *L, int index);
NoiseParams* get_noiseparams (lua_State *L, int index);
bool read_noiseparams_nc (lua_State *L, int index,
bool read_noiseparams (lua_State *L, int index,
NoiseParams *np);
bool get_schematic (lua_State *L, int index,
Schematic *schem,

View File

@ -608,13 +608,13 @@ int ModApiEnvMod::l_get_perlin_map(lua_State *L)
{
GET_ENV_PTR;
NoiseParams *np = read_noiseparams(L, 1);
if (!np)
NoiseParams np;
if (!read_noiseparams(L, 1, &np))
return 0;
v3s16 size = read_v3s16(L, 2);
int seed = (int)(env->getServerMap().getSeed());
LuaPerlinNoiseMap *n = new LuaPerlinNoiseMap(np, seed, size);
LuaPerlinNoiseMap *n = new LuaPerlinNoiseMap(&np, seed, size);
*(void **)(lua_newuserdata(L, sizeof(void *))) = n;
luaL_getmetatable(L, "PerlinNoiseMap");
lua_setmetatable(L, -2);

View File

@ -274,7 +274,10 @@ int ModApiMapgen::l_set_noiseparam_defaults(lua_State *L)
lua_pushnil(L);
while (lua_next(L, 1)) {
if (read_noiseparams_nc(L, -1, &np)) {
if (read_noiseparams(L, -1, &np)) {
/// TODO(hmmmm): Update this for newer noiseparam formats
/// Right now this is safe because serializeStructToString() won't
/// touch memory outside of what the format string specifies
if (!serializeStructToString(&val, NOISEPARAMS_FMT_STR, &np))
continue;
if (!lua_isstring(L, -2))
@ -406,7 +409,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
//// Get NoiseParams to define how decoration is placed
lua_getfield(L, index, "noise_params");
deco->np = read_noiseparams(L, -1);
deco->np = get_noiseparams(L, -1);
lua_pop(L, 1);
//// Get biomes associated with this decoration (if any)
@ -556,7 +559,7 @@ int ModApiMapgen::l_register_ore(lua_State *L)
getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);
lua_getfield(L, index, "noise_params");
ore->np = read_noiseparams(L, -1);
ore->np = get_noiseparams(L, -1);
lua_pop(L, 1);
u32 id = oremgr->add(ore);

View File

@ -31,6 +31,7 @@ int LuaPerlinNoise::gc_object(lua_State *L)
return 0;
}
int LuaPerlinNoise::l_get2d(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
@ -40,6 +41,8 @@ int LuaPerlinNoise::l_get2d(lua_State *L)
lua_pushnumber(L, val);
return 1;
}
int LuaPerlinNoise::l_get3d(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
@ -60,10 +63,12 @@ LuaPerlinNoise::LuaPerlinNoise(int a_seed, int a_octaves, float a_persistence,
{
}
LuaPerlinNoise::~LuaPerlinNoise()
{
}
// LuaPerlinNoise(seed, octaves, persistence, scale)
// Creates an LuaPerlinNoise and leaves it on top of stack
int LuaPerlinNoise::create_object(lua_State *L)
@ -80,15 +85,18 @@ int LuaPerlinNoise::create_object(lua_State *L)
return 1;
}
LuaPerlinNoise* LuaPerlinNoise::checkobject(lua_State *L, int narg)
{
NO_MAP_LOCK_REQUIRED;
luaL_checktype(L, narg, LUA_TUSERDATA);
void *ud = luaL_checkudata(L, narg, className);
if(!ud) luaL_typerror(L, narg, className);
if (!ud)
luaL_typerror(L, narg, className);
return *(LuaPerlinNoise**)ud; // unbox pointer
}
void LuaPerlinNoise::Register(lua_State *L)
{
lua_newtable(L);
@ -117,6 +125,7 @@ void LuaPerlinNoise::Register(lua_State *L)
lua_register(L, className, create_object);
}
const char LuaPerlinNoise::className[] = "PerlinNoise";
const luaL_reg LuaPerlinNoise::methods[] = {
luamethod(LuaPerlinNoise, get2d),
@ -124,11 +133,11 @@ const luaL_reg LuaPerlinNoise::methods[] = {
{0,0}
};
/*
PerlinNoiseMap
*/
int LuaPerlinNoiseMap::gc_object(lua_State *L)
{
LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
@ -136,6 +145,7 @@ int LuaPerlinNoiseMap::gc_object(lua_State *L)
return 0;
}
int LuaPerlinNoiseMap::l_get2dMap(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
@ -160,6 +170,7 @@ int LuaPerlinNoiseMap::l_get2dMap(lua_State *L)
return 1;
}
int LuaPerlinNoiseMap::l_get2dMap_flat(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
@ -181,6 +192,7 @@ int LuaPerlinNoiseMap::l_get2dMap_flat(lua_State *L)
return 1;
}
int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
@ -190,7 +202,7 @@ int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
v3f p = read_v3f(L, 2);
Noise *n = o->noise;
n->perlinMap3D(p.X, p.Y, p.Z, n->np->eased);
n->perlinMap3D(p.X, p.Y, p.Z);
lua_newtable(L);
for (int z = 0; z != n->sz; z++) {
@ -208,6 +220,7 @@ int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
return 1;
}
int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
@ -216,7 +229,7 @@ int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
v3f p = read_v3f(L, 2);
Noise *n = o->noise;
n->perlinMap3D(p.X, p.Y, p.Z, n->np->eased);
n->perlinMap3D(p.X, p.Y, p.Z);
int maplen = n->sx * n->sy * n->sz;
@ -230,37 +243,42 @@ int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
return 1;
}
LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *np, int seed, v3s16 size) {
LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *np, int seed, v3s16 size)
{
memcpy(&m_noise_params, np, sizeof(m_noise_params));
try {
noise = new Noise(np, seed, size.X, size.Y, size.Z);
noise = new Noise(&m_noise_params, seed, size.X, size.Y, size.Z);
} catch (InvalidNoiseParamsException &e) {
throw LuaError(e.what());
}
}
LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
{
delete noise->np;
delete noise;
}
// LuaPerlinNoiseMap(np, size)
// Creates an LuaPerlinNoiseMap and leaves it on top of stack
int LuaPerlinNoiseMap::create_object(lua_State *L)
{
NoiseParams *np = read_noiseparams(L, 1);
if (!np)
NoiseParams np;
if (!read_noiseparams(L, 1, &np))
return 0;
v3s16 size = read_v3s16(L, 2);
LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(np, 0, size);
LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(&np, 0, size);
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, className);
lua_setmetatable(L, -2);
return 1;
}
LuaPerlinNoiseMap* LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
{
luaL_checktype(L, narg, LUA_TUSERDATA);
@ -271,6 +289,7 @@ LuaPerlinNoiseMap* LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
return *(LuaPerlinNoiseMap **)ud; // unbox pointer
}
void LuaPerlinNoiseMap::Register(lua_State *L)
{
lua_newtable(L);
@ -299,6 +318,7 @@ void LuaPerlinNoiseMap::Register(lua_State *L)
lua_register(L, className, create_object);
}
const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap";
const luaL_reg LuaPerlinNoiseMap::methods[] = {
luamethod(LuaPerlinNoiseMap, get2dMap),
@ -320,6 +340,7 @@ int LuaPseudoRandom::gc_object(lua_State *L)
return 0;
}
// next(self, min=0, max=32767) -> get next value
int LuaPseudoRandom::l_next(lua_State *L)
{
@ -354,19 +375,23 @@ LuaPseudoRandom::LuaPseudoRandom(int seed):
{
}
LuaPseudoRandom::~LuaPseudoRandom()
{
}
const PseudoRandom& LuaPseudoRandom::getItem() const
{
return m_pseudo;
}
PseudoRandom& LuaPseudoRandom::getItem()
{
return m_pseudo;
}
// LuaPseudoRandom(seed)
// Creates an LuaPseudoRandom and leaves it on top of stack
int LuaPseudoRandom::create_object(lua_State *L)
@ -379,14 +404,17 @@ int LuaPseudoRandom::create_object(lua_State *L)
return 1;
}
LuaPseudoRandom* LuaPseudoRandom::checkobject(lua_State *L, int narg)
{
luaL_checktype(L, narg, LUA_TUSERDATA);
void *ud = luaL_checkudata(L, narg, className);
if(!ud) luaL_typerror(L, narg, className);
if (!ud)
luaL_typerror(L, narg, className);
return *(LuaPseudoRandom**)ud; // unbox pointer
}
void LuaPseudoRandom::Register(lua_State *L)
{
lua_newtable(L);
@ -415,6 +443,7 @@ void LuaPseudoRandom::Register(lua_State *L)
lua_register(L, className, create_object);
}
const char LuaPseudoRandom::className[] = "PseudoRandom";
const luaL_reg LuaPseudoRandom::methods[] = {
luamethod(LuaPseudoRandom, next),

View File

@ -54,7 +54,7 @@ public:
// Creates an LuaPerlinNoise and leaves it on top of stack
static int create_object(lua_State *L);
static LuaPerlinNoise* checkobject(lua_State *L, int narg);
static LuaPerlinNoise *checkobject(lua_State *L, int narg);
static void Register(lua_State *L);
};
@ -63,7 +63,7 @@ public:
LuaPerlinNoiseMap
*/
class LuaPerlinNoiseMap : public ModApiBase {
private:
NoiseParams m_noise_params;
Noise *noise;
static const char className[];
static const luaL_reg methods[];

View File

@ -591,6 +591,11 @@ bool Settings::getNoiseParamsFromGroup(const std::string &name,
group->getS32NoEx("seed", np.seed);
group->getU16NoEx("octaves", np.octaves);
group->getFloatNoEx("persistence", np.persist);
group->getFloatNoEx("lacunarity", np.lacunarity);
np.flags = 0;
if (!group->getFlagStrNoEx("flags", np.flags, flagdesc_noiseparams))
np.flags = NOISE_FLAG_DEFAULTS;
return true;
}
@ -896,6 +901,8 @@ void Settings::setNoiseParams(const std::string &name, const NoiseParams &np)
group->setS32("seed", np.seed);
group->setU16("octaves", np.octaves);
group->setFloat("persistence", np.persist);
group->setFloat("lacunarity", np.lacunarity);
group->setFlagStr("flags", np.flags, flagdesc_noiseparams, np.flags);
Settings *old_group;
{

View File

@ -467,6 +467,8 @@ struct TestPath: public TestBase
" with leading whitespace!\n" \
"\"\"\"\n" \
"np_terrain = {\n" \
" flags = defaults\n" \
" lacunarity = 2\n" \
" octaves = 6\n" \
" offset = 3.5\n" \
" persistence = 0.7\n" \