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

@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapgen_v7.h" #include "mapgen_v7.h"
#include "cavegen.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);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

@ -31,9 +31,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
//#define DGEN_USE_TORCHES //#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_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); 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); NoiseParams nparams_dungeon_density(0.0, 1.0, v3f(2.5, 2.5, 2.5), 0, 2, 1.4, 2.0);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

@ -130,14 +130,14 @@ MapgenV5::~MapgenV5() {
MapgenV5Params::MapgenV5Params() { MapgenV5Params::MapgenV5Params() {
spflags = MGV5_BLOBS; spflags = MGV5_BLOBS;
np_filler_depth = NoiseParams(0, 1, v3f(150, 150, 150), 261, 4, 0.7); 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); 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); 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); 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); 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); 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); 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); 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->perlinMap2D(x, z);
noise_height->transformNoiseMap(); noise_height->transformNoiseMap();
noise_cave1->perlinMap3D(x, y, z, true); noise_cave1->perlinMap3D(x, y, z);
noise_cave1->transformNoiseMap(); noise_cave1->transformNoiseMap();
noise_cave2->perlinMap3D(x, y, z, true); noise_cave2->perlinMap3D(x, y, z);
noise_cave2->transformNoiseMap(); noise_cave2->transformNoiseMap();
noise_ground->perlinMap3D(x, y, z, true); noise_ground->perlinMap3D(x, y, z);
noise_ground->transformNoiseMap(); noise_ground->transformNoiseMap();
if (spflags & MGV5_BLOBS) { if (spflags & MGV5_BLOBS) {
noise_crumble->perlinMap3D(x, y, z, true); noise_crumble->perlinMap3D(x, y, z);
noise_wetness->perlinMap3D(x, y, z, false); noise_wetness->perlinMap3D(x, y, z);
} }
noise_heat->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z);

@ -122,17 +122,17 @@ MapgenV6Params::MapgenV6Params() {
freq_desert = 0.45; freq_desert = 0.45;
freq_beach = 0.15; freq_beach = 0.15;
np_terrain_base = NoiseParams(-4, 20.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); np_apple_trees = NoiseParams(0, 1.0, v3f(100.0, 100.0, 100.0), 342902, 3, 0.45, 2.0);
} }

@ -122,15 +122,15 @@ MapgenV7::~MapgenV7() {
MapgenV7Params::MapgenV7Params() { MapgenV7Params::MapgenV7Params() {
spflags = MGV7_MOUNTAINS | MGV7_RIDGES; spflags = MGV7_MOUNTAINS | MGV7_RIDGES;
np_terrain_base = NoiseParams(4, 70, v3f(300, 300, 300), 82341, 6, 0.7); 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); 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); 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); 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); 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); 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); 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); 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); 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++) for (int i = 0; i != csize.X * csize.Z; i++)
persistmap[i] = rangelim(persistmap[i], 0.4, 0.9); 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_base->transformNoiseMap();
noise_terrain_alt->perlinMap2DModulated(x, z, persistmap); noise_terrain_alt->perlinMap2D(x, z, persistmap);
noise_terrain_alt->transformNoiseMap(); noise_terrain_alt->transformNoiseMap();
noise_filler_depth->perlinMap2D(x, z); noise_filler_depth->perlinMap2D(x, z);
@ -728,7 +728,7 @@ void MapgenV7::addTopNodes() {
#endif #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) { void MapgenV7::generateCaves(int max_stone_y) {
PseudoRandom ps(blockseed + 21343); PseudoRandom ps(blockseed + 21343);

@ -29,8 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
const char *BiomeManager::ELEMENT_TITLE = "biome"; 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_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); NoiseParams nparams_biome_def_humidity(50, 50, v3f(500.0, 500.0, 500.0), 842, 3, 0.55, 2.0);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

@ -29,6 +29,7 @@
#include <string.h> // memset #include <string.h> // memset
#include "debug.h" #include "debug.h"
#include "util/numeric.h" #include "util/numeric.h"
#include "util/string.h"
#include "exceptions.h" #include "exceptions.h"
#define NOISE_MAGIC_X 1619 #define NOISE_MAGIC_X 1619
@ -36,6 +37,10 @@
#define NOISE_MAGIC_Z 52591 #define NOISE_MAGIC_Z 52591
#define NOISE_MAGIC_SEED 1013 #define NOISE_MAGIC_SEED 1013
typedef float (*Interp2dFxn)(
float v00, float v10, float v01, float v11,
float x, float y);
typedef float (*Interp3dFxn)( typedef float (*Interp3dFxn)(
float v000, float v100, float v010, float v110, float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111, 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 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) float noise2d(int x, int y, int seed)
{ {
int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y 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) inline float linearInterpolation(float v0, float v1, float t)
{ {
return v0 + (v1 - v0) * t; return v0 + (v1 - v0) * t;
} }
float biLinearInterpolation( float biLinearInterpolation(
float v00, float v10, float v00, float v10,
float v01, float v11, float v01, float v11,
float x, float y) float x, float y)
{ {
float tx = easeCurve(x); float tx = easeCurve(x);
float ty = easeCurve(y); float ty = easeCurve(y);
float u = linearInterpolation(v00, v10, tx); return (
float v = linearInterpolation(v01, v11, tx); v00 * (1 - tx) * (1 - ty) +
return linearInterpolation(u, v, 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 biLinearInterpolationNoEase(
float x0y0, float x1y0, float v00, float v10,
float x0y1, float x1y1, float v01, float v11,
float x, float y) float x, float y)
{ {
float u = linearInterpolation(x0y0, x1y0, x); float tx = x;
float v = linearInterpolation(x0y1, x1y1, x); float ty = y;
return linearInterpolation(u, v, 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 triLinearInterpolation(
float v000, float v100, float v010, float v110, float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111, float v001, float v101, float v011, float v111,
float x, float y, float z) float x, float y, float z)
{ {
float tx = easeCurve(x); float tx = easeCurve(x);
float ty = easeCurve(y); float ty = easeCurve(y);
float tz = easeCurve(z); float tz = easeCurve(z);
return ( return (
v000 * (1 - tx) * (1 - ty) * (1 - tz) + v000 * (1 - tx) * (1 - ty) * (1 - tz) +
v100 * tx * (1 - ty) * (1 - tz) + v100 * tx * (1 - ty) * (1 - tz) +
v010 * (1 - tx) * ty * (1 - tz) + v010 * (1 - tx) * ty * (1 - tz) +
v110 * tx * ty * (1 - tz) + v110 * tx * ty * (1 - tz) +
v001 * (1 - tx) * (1 - ty) * tz + v001 * (1 - tx) * (1 - ty) * tz +
v101 * tx * (1 - ty) * tz + v101 * tx * (1 - ty) * tz +
v011 * (1 - tx) * ty * tz + v011 * (1 - tx) * ty * tz +
v111 * 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 triLinearInterpolationNoEase(
float v000, float v100, float v010, float v110, float v000, float v100, float v010, float v110,
float v001, float v101, float v011, float v111, float v001, float v101, float v011, float v111,
float x, float y, float z) float x, float y, float z)
{ {
float tx = x; float tx = x;
float ty = y; float ty = y;
float tz = z; float tz = z;
return ( return (
v000 * (1 - tx) * (1 - ty) * (1 - tz) + v000 * (1 - tx) * (1 - ty) * (1 - tz) +
v100 * tx * (1 - ty) * (1 - tz) + v100 * tx * (1 - ty) * (1 - tz) +
v010 * (1 - tx) * ty * (1 - tz) + v010 * (1 - tx) * ty * (1 - tz) +
v110 * tx * ty * (1 - tz) + v110 * tx * ty * (1 - tz) +
v001 * (1 - tx) * (1 - ty) * tz + v001 * (1 - tx) * (1 - ty) * tz +
v101 * tx * (1 - ty) * tz + v101 * tx * (1 - ty) * tz +
v011 * (1 - tx) * ty * tz + v011 * (1 - tx) * ty * tz +
v111 * tx * ty * tz v111 * tx * ty * tz
); );
} }
@ -198,7 +200,7 @@ float noise2d_gradient(float x, float y, int seed)
#endif #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 // Calculate the integer coordinates
int x0 = myfloor(x); 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 v01 = noise2d(x0, y0+1, seed);
float v11 = noise2d(x0+1, y0+1, seed); float v11 = noise2d(x0+1, y0+1, seed);
// Interpolate // 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, float noise2d_perlin(float x, float y, int seed,
int octaves, float persistence) int octaves, float persistence, bool eased)
{ {
float a = 0; float a = 0;
float f = 1.0; float f = 1.0;
float g = 1.0; float g = 1.0;
for (int i = 0; i < octaves; i++) 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; f *= 2.0;
g *= persistence; 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, float noise2d_perlin_abs(float x, float y, int seed,
int octaves, float persistence) int octaves, float persistence, bool eased)
{ {
float a = 0; float a = 0;
float f = 1.0; float f = 1.0;
float g = 1.0; float g = 1.0;
for (int i = 0; i < octaves; i++) for (int i = 0; i < octaves; i++) {
{ a += g * fabs(noise2d_gradient(x * f, y * f, seed + i, eased));
a += g * fabs(noise2d_gradient(x * f, y * f, seed + i));
f *= 2.0; f *= 2.0;
g *= persistence; 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, 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 a = 0;
float f = 1.0; float f = 1.0;
float g = 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); a += g * noise3d_gradient(x * f, y * f, z * f, seed + i, eased);
f *= 2.0; f *= 2.0;
g *= persistence; 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, 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 a = 0;
float f = 1.0; float f = 1.0;
float g = 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)); a += g * fabs(noise3d_gradient(x * f, y * f, z * f, seed + i, eased));
f *= 2.0; f *= 2.0;
g *= persistence; g *= persistence;
@ -317,7 +319,7 @@ float noise3d_perlin_abs(float x, float y, float z, int seed,
float contour(float v) float contour(float v)
{ {
v = fabs(v); v = fabs(v);
if(v >= 1.0) if (v >= 1.0)
return 0.0; return 0.0;
return (1.0 - v); return (1.0 - v);
} }
@ -335,6 +337,12 @@ Noise::Noise(NoiseParams *np, int seed, int sx, int sy, int sz)
this->sz = sz; this->sz = sz;
this->noisebuf = NULL; 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); resizeNoiseBuf(sz > 1);
try { try {
@ -437,6 +445,9 @@ void Noise::gradientMap2D(
int index, i, j, x0, y0, noisex, noisey; int index, i, j, x0, y0, noisex, noisey;
int nlx, nly; int nlx, nly;
Interp2dFxn interpolate = (np->flags & NOISE_FLAG_EASED) ?
biLinearInterpolation : biLinearInterpolationNoEase;
x0 = floor(x); x0 = floor(x);
y0 = floor(y); y0 = floor(y);
u = x - (float)x0; u = x - (float)x0;
@ -463,7 +474,7 @@ void Noise::gradientMap2D(
u = orig_u; u = orig_u;
noisex = 0; noisex = 0;
for (i = 0; i != sx; i++) { 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; u += step_x;
if (u >= 1.0) { if (u >= 1.0) {
u -= 1.0; u -= 1.0;
@ -489,7 +500,7 @@ void Noise::gradientMap2D(
void Noise::gradientMap3D( void Noise::gradientMap3D(
float x, float y, float z, float x, float y, float z,
float step_x, float step_y, float step_z, float step_x, float step_y, float step_z,
int seed, bool eased) int seed)
{ {
float v000, v010, v100, v110; float v000, v010, v100, v110;
float v001, v011, v101, v111; float v001, v011, v101, v111;
@ -497,7 +508,7 @@ void Noise::gradientMap3D(
int index, i, j, k, x0, y0, z0, noisex, noisey, noisez; int index, i, j, k, x0, y0, z0, noisex, noisey, noisez;
int nlx, nly, nlz; int nlx, nly, nlz;
Interp3dFxn interpolate = eased ? Interp3dFxn interpolate = (np->flags & NOISE_FLAG_EASED) ?
triLinearInterpolation : triLinearInterpolationNoEase; triLinearInterpolation : triLinearInterpolationNoEase;
x0 = floor(x); x0 = floor(x);
@ -576,7 +587,7 @@ void Noise::gradientMap3D(
#undef idx #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; float f = 1.0, g = 1.0;
size_t bufsize = sx * sy; size_t bufsize = sx * sy;
@ -586,55 +597,30 @@ float *Noise::perlinMap2D(float x, float y)
memset(result, 0, sizeof(float) * bufsize); 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, gradientMap2D(x * f, y * f,
f / np->spread.X, f / np->spread.Y, f / np->spread.X, f / np->spread.Y,
seed + np->seed + oct); seed + np->seed + oct);
for (size_t i = 0; i != bufsize; i++) updateResults(g, gmap, persistence_map, bufsize);
result[i] += g * buf[i];
f *= 2.0; f *= np->lacunarity;
g *= np->persist; g *= np->persist;
} }
delete[] gmap;
return result; return result;
} }
float *Noise::perlinMap2DModulated(float x, float y, float *persist_map) float *Noise::perlinMap3D(float x, float y, float z, float *persistence_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 f = 1.0, g = 1.0; float f = 1.0, g = 1.0;
size_t bufsize = sx * sy * sz; 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); 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, gradientMap3D(x * f, y * f, z * f,
f / np->spread.X, f / np->spread.Y, f / np->spread.Z, 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++) updateResults(g, gmap, persistence_map, bufsize);
result[i] += g * buf[i];
f *= 2.0; f *= np->lacunarity;
g *= np->persist; g *= np->persist;
} }
delete[] gmap;
return result; 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() void Noise::transformNoiseMap()
{ {
size_t i = 0; size_t i = 0;

@ -28,6 +28,9 @@
#include "debug.h" #include "debug.h"
#include "irr_v3d.h" #include "irr_v3d.h"
#include "util/string.h"
extern FlagDesc flagdesc_noiseparams[];
class PseudoRandom class PseudoRandom
{ {
@ -66,6 +69,14 @@ private:
int m_next; 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 { struct NoiseParams {
float offset; float offset;
float scale; float scale;
@ -73,20 +84,32 @@ struct NoiseParams {
s32 seed; s32 seed;
u16 octaves; u16 octaves;
float persist; 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_, NoiseParams(float offset_, float scale_, v3f spread_, s32 seed_,
int seed_, int octaves_, float persist_, bool eased_=false) u16 octaves_, float persist_, float lacunarity_,
u32 flags_=NOISE_FLAG_DEFAULTS)
{ {
offset = offset_; offset = offset_;
scale = scale_; scale = scale_;
spread = spread_; spread = spread_;
seed = seed_; seed = seed_;
octaves = octaves_; octaves = octaves_;
persist = persist_; persist = persist_;
eased = eased_; lacunarity = lacunarity_;
flags = flags_;
} }
}; };
@ -123,10 +146,12 @@ public:
void gradientMap3D( void gradientMap3D(
float x, float y, float z, float x, float y, float z,
float step_x, float step_y, float step_z, float step_x, float step_y, float step_z,
int seed, bool eased=false); int seed);
float *perlinMap2D(float x, float y);
float *perlinMap2DModulated(float x, float y, float *persist_map); float *perlinMap2D(float x, float y, float *persistence_map=NULL);
float *perlinMap3D(float x, float y, float z, bool eased=false); 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(); void transformNoiseMap();
}; };
@ -134,14 +159,14 @@ public:
float noise2d(int x, int y, int seed); float noise2d(int x, int y, int seed);
float noise3d(int x, int y, int z, 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 noise3d_gradient(float x, float y, float z, int seed, bool eased=false);
float noise2d_perlin(float x, float y, int seed, 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, 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, float noise3d_perlin(float x, float y, float z, int seed,
int octaves, float persistence, bool eased=false); int octaves, float persistence, bool eased=false);

@ -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; NoiseParams *np = new NoiseParams;
if (!read_noiseparams_nc(L, index, np)) { if (!read_noiseparams(L, index, np)) {
delete np; delete np;
np = NULL; np = NULL;
} }
@ -987,7 +987,7 @@ NoiseParams *read_noiseparams(lua_State *L, int index)
return np; 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) if (index < 0)
index = lua_gettop(L) + 1 + index; 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)) if (!lua_istable(L, index))
return false; return false;
np->offset = getfloatfield_default(L, index, "offset", 0.0); np->offset = getfloatfield_default(L, index, "offset", 0.0);
np->scale = getfloatfield_default(L, index, "scale", 0.0); np->scale = getfloatfield_default(L, index, "scale", 0.0);
np->persist = getfloatfield_default(L, index, "persist", 0.0); np->persist = getfloatfield_default(L, index, "persist", 0.0);
np->seed = getintfield_default(L, index, "seed", 0); np->lacunarity = getfloatfield_default(L, index, "lacunarity", 2.0);
np->octaves = getintfield_default(L, index, "octaves", 0); np->seed = getintfield_default(L, index, "seed", 0);
np->eased = getboolfield_default(L, index, "eased", false); 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"); lua_getfield(L, index, "spread");
np->spread = read_v3f(L, -1); np->spread = read_v3f(L, -1);

@ -147,9 +147,9 @@ bool string_to_enum (const EnumString *spec,
int &result, int &result,
const std::string &str); 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); NoiseParams *np);
bool get_schematic (lua_State *L, int index, bool get_schematic (lua_State *L, int index,
Schematic *schem, Schematic *schem,

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

@ -274,7 +274,10 @@ int ModApiMapgen::l_set_noiseparam_defaults(lua_State *L)
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, 1)) { 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)) if (!serializeStructToString(&val, NOISEPARAMS_FMT_STR, &np))
continue; continue;
if (!lua_isstring(L, -2)) 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 //// Get NoiseParams to define how decoration is placed
lua_getfield(L, index, "noise_params"); lua_getfield(L, index, "noise_params");
deco->np = read_noiseparams(L, -1); deco->np = get_noiseparams(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
//// Get biomes associated with this decoration (if any) //// 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); getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);
lua_getfield(L, index, "noise_params"); lua_getfield(L, index, "noise_params");
ore->np = read_noiseparams(L, -1); ore->np = get_noiseparams(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
u32 id = oremgr->add(ore); u32 id = oremgr->add(ore);

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

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

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

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