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
master
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
@ -90,45 +102,33 @@ float biLinearInterpolation(
{
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);
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 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,
@ -138,7 +138,6 @@ float triLinearInterpolation(
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) +
@ -149,6 +148,9 @@ float triLinearInterpolation(
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(
@ -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
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;
}
@ -288,8 +292,7 @@ float noise3d_perlin(float x, float y, float z, int seed,
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;
@ -304,8 +307,7 @@ float noise3d_perlin_abs(float x, float y, float z, int seed,
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;
@ -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,12 +84,23 @@ 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_;
@ -86,7 +108,8 @@ struct NoiseParams {
seed = seed_;
octaves = octaves_;
persist = persist_;
eased = eased_;
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;
@ -998,9 +998,13 @@ bool read_noiseparams_nc(lua_State *L, int index, NoiseParams *np)
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);
np->eased = getboolfield_default(L, index, "eased", false);
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,36 +243,41 @@ 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)
{
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

@ -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" \