Luanti 5.11.0-dev
 
Loading...
Searching...
No Matches
noise.h
Go to the documentation of this file.
1/*
2 * Minetest
3 * Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
4 * Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without modification, are
8 * permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "irr_v3d.h"
29#include "exceptions.h"
30#include "util/string.h"
31
32#if defined(RANDOM_MIN)
33#undef RANDOM_MIN
34#endif
35#if defined(RANDOM_MAX)
36#undef RANDOM_MAX
37#endif
38
40
41// Note: this class is not polymorphic so that its high level of
42// optimizability may be preserved in the common use case
44public:
45 const static u32 RANDOM_RANGE = 32767;
46
47 inline PseudoRandom(s32 seed_=0)
48 {
49 seed(seed_);
50 }
51
52 inline void seed(s32 seed)
53 {
54 m_next = seed;
55 }
56
57 inline u32 next()
58 {
59 m_next = static_cast<u32>(m_next) * 1103515245U + 12345U;
60 // Signed division is required due to backwards compatibility
61 return static_cast<u32>(m_next / 65536) % (RANDOM_RANGE + 1U);
62 }
63
64 inline s32 range(s32 min, s32 max)
65 {
66 if (max < min)
67 throw PrngException("Invalid range (max < min)");
68 /*
69 Here, we ensure the range is not too large relative to RANDOM_MAX,
70 as otherwise the effects of bias would become noticeable. Unlike
71 PcgRandom, we cannot modify this RNG's range as it would change the
72 output of this RNG for reverse compatibility.
73 */
74 if (static_cast<u32>(max - min) > (RANDOM_RANGE + 1) / 5)
75 throw PrngException("Range too large");
76
77 return (next() % (max - min + 1)) + min;
78 }
79
80 // Allow save and restore of state
81 inline s32 getState() const
82 {
83 return m_next;
84 }
85private:
86 s32 m_next;
87};
88
89class PcgRandom {
90public:
91 const static s32 RANDOM_MIN = -0x7fffffff - 1;
92 const static s32 RANDOM_MAX = 0x7fffffff;
93 const static u32 RANDOM_RANGE = 0xffffffff;
94
95 PcgRandom(u64 state=0x853c49e6748fea9bULL, u64 seq=0xda3e39cb94b95bdbULL);
96 void seed(u64 state, u64 seq=0xda3e39cb94b95bdbULL);
97 u32 next();
98 u32 range(u32 bound);
99 s32 range(s32 min, s32 max);
100 void bytes(void *out, size_t len);
101 s32 randNormalDist(s32 min, s32 max, int num_trials=6);
102
103 // Allow save and restore of state
104 void getState(u64 state[2]) const;
105 void setState(const u64 state[2]);
106private:
108 u64 m_inc;
109};
110
111#define NOISE_FLAG_DEFAULTS 0x01
112#define NOISE_FLAG_EASED 0x02
113#define NOISE_FLAG_ABSVALUE 0x04
114
116#define NOISE_FLAG_POINTBUFFER 0x08
117#define NOISE_FLAG_SIMPLEX 0x10
118
120 float offset = 0.0f;
121 float scale = 1.0f;
122 v3f spread = v3f(250, 250, 250);
123 s32 seed = 12345;
124 u16 octaves = 3;
125 float persist = 0.6f;
126 float lacunarity = 2.0f;
128
129 NoiseParams() = default;
130
131 NoiseParams(float offset_, float scale_, const v3f &spread_, s32 seed_,
132 u16 octaves_, float persist_, float lacunarity_,
133 u32 flags_=NOISE_FLAG_DEFAULTS)
134 {
135 offset = offset_;
136 scale = scale_;
137 spread = spread_;
138 seed = seed_;
139 octaves = octaves_;
140 persist = persist_;
141 lacunarity = lacunarity_;
142 flags = flags_;
143 }
144};
145
146class Noise {
147public:
149 s32 seed;
150 u32 sx;
151 u32 sy;
152 u32 sz;
153 float *noise_buf = nullptr;
154 float *gradient_buf = nullptr;
155 float *persist_buf = nullptr;
156 float *result = nullptr;
157
158 Noise(const NoiseParams *np, s32 seed, u32 sx, u32 sy, u32 sz=1);
159 ~Noise();
160
161 void setSize(u32 sx, u32 sy, u32 sz=1);
162 void setSpreadFactor(v3f spread);
163 void setOctaves(int octaves);
164
165 void gradientMap2D(
166 float x, float y,
167 float step_x, float step_y,
168 s32 seed);
169 void gradientMap3D(
170 float x, float y, float z,
171 float step_x, float step_y, float step_z,
172 s32 seed);
173
174 float *perlinMap2D(float x, float y, float *persistence_map=NULL);
175 float *perlinMap3D(float x, float y, float z, float *persistence_map=NULL);
176
177 inline float *perlinMap2D_PO(float x, float xoff, float y, float yoff,
178 float *persistence_map=NULL)
179 {
180 return perlinMap2D(
181 x + xoff * np.spread.X,
182 y + yoff * np.spread.Y,
183 persistence_map);
184 }
185
186 inline float *perlinMap3D_PO(float x, float xoff, float y, float yoff,
187 float z, float zoff, float *persistence_map=NULL)
188 {
189 return perlinMap3D(
190 x + xoff * np.spread.X,
191 y + yoff * np.spread.Y,
192 z + zoff * np.spread.Z,
193 persistence_map);
194 }
195
196private:
197 void allocBuffers();
198 void resizeNoiseBuf(bool is3d);
199 void updateResults(float g, float *gmap, const float *persistence_map,
200 size_t bufsize);
201
202};
203
204float NoisePerlin2D(const NoiseParams *np, float x, float y, s32 seed);
205float NoisePerlin3D(const NoiseParams *np, float x, float y, float z, s32 seed);
206
207inline float NoisePerlin2D_PO(NoiseParams *np, float x, float xoff,
208 float y, float yoff, s32 seed)
209{
210 return NoisePerlin2D(np,
211 x + xoff * np->spread.X,
212 y + yoff * np->spread.Y,
213 seed);
214}
215
216inline float NoisePerlin3D_PO(NoiseParams *np, float x, float xoff,
217 float y, float yoff, float z, float zoff, s32 seed)
218{
219 return NoisePerlin3D(np,
220 x + xoff * np->spread.X,
221 y + yoff * np->spread.Y,
222 z + zoff * np->spread.Z,
223 seed);
224}
225
226// Return value: -1 ... 1
227float noise2d(int x, int y, s32 seed);
228float noise3d(int x, int y, int z, s32 seed);
229
230float noise2d_gradient(float x, float y, s32 seed, bool eased=true);
231float noise3d_gradient(float x, float y, float z, s32 seed, bool eased=false);
232
233float noise2d_perlin(float x, float y, s32 seed,
234 int octaves, float persistence, bool eased=true);
235
236inline float easeCurve(float t)
237{
238 return t * t * t * (t * (6.f * t - 15.f) + 10.f);
239}
240
241float contour(float v);
Definition noise.h:146
u32 sz
Definition noise.h:152
Noise(const NoiseParams *np, s32 seed, u32 sx, u32 sy, u32 sz=1)
Definition noise.cpp:362
float * perlinMap3D(float x, float y, float z, float *persistence_map=NULL)
Definition noise.cpp:681
void setSize(u32 sx, u32 sy, u32 sz=1)
Definition noise.cpp:410
s32 seed
Definition noise.h:149
float * perlinMap2D(float x, float y, float *persistence_map=NULL)
Definition noise.cpp:644
float * perlinMap2D_PO(float x, float xoff, float y, float yoff, float *persistence_map=NULL)
Definition noise.h:177
float * perlinMap3D_PO(float x, float xoff, float y, float yoff, float z, float zoff, float *persistence_map=NULL)
Definition noise.h:186
float * result
Definition noise.h:156
float * persist_buf
Definition noise.h:155
void gradientMap3D(float x, float y, float z, float step_x, float step_y, float step_z, s32 seed)
Definition noise.cpp:553
float * gradient_buf
Definition noise.h:154
void setSpreadFactor(v3f spread)
Definition noise.cpp:420
u32 sx
Definition noise.h:150
~Noise()
Definition noise.cpp:374
void setOctaves(int octaves)
Definition noise.cpp:428
NoiseParams np
Definition noise.h:148
void gradientMap2D(float x, float y, float step_x, float step_y, s32 seed)
Definition noise.cpp:491
float * noise_buf
Definition noise.h:153
u32 sy
Definition noise.h:151
void allocBuffers()
Definition noise.cpp:383
void updateResults(float g, float *gmap, const float *persistence_map, size_t bufsize)
Definition noise.cpp:719
void resizeNoiseBuf(bool is3d)
Definition noise.cpp:436
Definition noise.h:89
u64 m_state
Definition noise.h:107
s32 randNormalDist(s32 min, s32 max, int num_trials=6)
Definition noise.cpp:147
void seed(u64 state, u64 seq=0xda3e39cb94b95bdbULL)
Definition noise.cpp:57
static const u32 RANDOM_RANGE
Definition noise.h:93
u32 range(u32 bound)
Definition noise.cpp:78
static const s32 RANDOM_MIN
Definition noise.h:91
u32 next()
Definition noise.cpp:67
PcgRandom(u64 state=0x853c49e6748fea9bULL, u64 seq=0xda3e39cb94b95bdbULL)
Definition noise.cpp:52
void bytes(void *out, size_t len)
Definition noise.cpp:127
u64 m_inc
Definition noise.h:108
void getState(u64 state[2]) const
Definition noise.cpp:155
void setState(const u64 state[2])
Definition noise.cpp:161
static const s32 RANDOM_MAX
Definition noise.h:92
Definition exceptions.h:75
Definition noise.h:43
s32 getState() const
Definition noise.h:81
PseudoRandom(s32 seed_=0)
Definition noise.h:47
u32 next()
Definition noise.h:57
s32 range(s32 min, s32 max)
Definition noise.h:64
void seed(s32 seed)
Definition noise.h:52
static const u32 RANDOM_RANGE
Definition noise.h:45
s32 m_next
Definition noise.h:86
core::vector3df v3f
Definition irr_v3d.h:11
float NoisePerlin2D_PO(NoiseParams *np, float x, float xoff, float y, float yoff, s32 seed)
Definition noise.h:207
float contour(float v)
Definition noise.cpp:297
FlagDesc flagdesc_noiseparams[]
Definition noise.cpp:41
float noise2d(int x, int y, s32 seed)
Definition noise.cpp:169
float noise3d(int x, int y, int z, s32 seed)
Definition noise.cpp:179
float NoisePerlin3D_PO(NoiseParams *np, float x, float xoff, float y, float yoff, float z, float zoff, s32 seed)
Definition noise.h:216
#define NOISE_FLAG_DEFAULTS
Definition noise.h:111
float noise3d_gradient(float x, float y, float z, s32 seed, bool eased=false)
Definition noise.cpp:253
float NoisePerlin2D(const NoiseParams *np, float x, float y, s32 seed)
Definition noise.cpp:309
float noise2d_gradient(float x, float y, s32 seed, bool eased=true)
Definition noise.cpp:235
float noise2d_perlin(float x, float y, s32 seed, int octaves, float persistence, bool eased=true)
Definition noise.cpp:281
float easeCurve(float t)
Definition noise.h:236
float NoisePerlin3D(const NoiseParams *np, float x, float y, float z, s32 seed)
Definition noise.cpp:335
Definition string.h:67
Definition noise.h:119
NoiseParams()=default
v3f spread
Definition noise.h:122
float persist
Definition noise.h:125
float offset
Definition noise.h:120
u16 octaves
Definition noise.h:124
u32 flags
Definition noise.h:127
float scale
Definition noise.h:121
NoiseParams(float offset_, float scale_, const v3f &spread_, s32 seed_, u16 octaves_, float persist_, float lacunarity_, u32 flags_=NOISE_FLAG_DEFAULTS)
Definition noise.h:131
float lacunarity
Definition noise.h:126
s32 seed
Definition noise.h:123