PseudoRandom: Expose constant PSEUDORANDOM_MAX
[oweals/minetest.git] / src / noise.h
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 #ifndef NOISE_HEADER
27 #define NOISE_HEADER
28
29 #include "debug.h"
30 #include "irr_v3d.h"
31 #include "util/string.h"
32
33 #define PSEUDORANDOM_MAX 32767
34
35 extern FlagDesc flagdesc_noiseparams[];
36
37 class PseudoRandom
38 {
39 public:
40         PseudoRandom(): m_next(0)
41         {
42         }
43         PseudoRandom(int seed): m_next(seed)
44         {
45         }
46         void seed(int seed)
47         {
48                 m_next = seed;
49         }
50         // Returns 0...PSEUDORANDOM_MAX
51         int next()
52         {
53                 m_next = m_next * 1103515245 + 12345;
54                 return((unsigned)(m_next/65536) % (PSEUDORANDOM_MAX + 1));
55         }
56         int range(int min, int max)
57         {
58                 if (max-min > (PSEUDORANDOM_MAX + 1) / 10)
59                 {
60                         //dstream<<"WARNING: PseudoRandom::range: max > 32767"<<std::endl;
61                         assert(0);
62                 }
63                 if(min > max)
64                 {
65                         assert(0);
66                         return max;
67                 }
68                 return (next()%(max-min+1))+min;
69         }
70 private:
71         int m_next;
72 };
73
74 #define NOISE_FLAG_DEFAULTS    0x01
75 #define NOISE_FLAG_EASED       0x02
76 #define NOISE_FLAG_ABSVALUE    0x04
77
78 //// TODO(hmmmm): implement these!
79 #define NOISE_FLAG_POINTBUFFER 0x08
80 #define NOISE_FLAG_SIMPLEX     0x10
81
82 struct NoiseParams {
83         float offset;
84         float scale;
85         v3f spread;
86         s32 seed;
87         u16 octaves;
88         float persist;
89         float lacunarity;
90         u32 flags;
91
92         NoiseParams() {
93                 offset     = 0.0f;
94                 scale      = 1.0f;
95                 spread     = v3f(250, 250, 250);
96                 seed       = 12345;
97                 octaves    = 3;
98                 persist    = 0.6f;
99                 lacunarity = 2.0f;
100                 flags      = NOISE_FLAG_DEFAULTS;
101         }
102
103         NoiseParams(float offset_, float scale_, v3f spread_, s32 seed_,
104                 u16 octaves_, float persist_, float lacunarity_,
105                 u32 flags_=NOISE_FLAG_DEFAULTS)
106         {
107                 offset     = offset_;
108                 scale      = scale_;
109                 spread     = spread_;
110                 seed       = seed_;
111                 octaves    = octaves_;
112                 persist    = persist_;
113                 lacunarity = lacunarity_;
114                 flags      = flags_;
115         }
116 };
117
118
119 // Convenience macros for getting/setting NoiseParams in Settings as a string
120 // WARNING:  Deprecated, use Settings::getNoiseParamsFromValue() instead
121 #define NOISEPARAMS_FMT_STR "f,f,v3,s32,u16,f"
122 //#define getNoiseParams(x, y) getStruct((x), NOISEPARAMS_FMT_STR, &(y), sizeof(y))
123 //#define setNoiseParams(x, y) setStruct((x), NOISEPARAMS_FMT_STR, &(y))
124
125 class Noise {
126 public:
127         NoiseParams np;
128         int seed;
129         int sx;
130         int sy;
131         int sz;
132         float *noise_buf;
133         float *gradient_buf;
134         float *persist_buf;
135         float *result;
136
137         Noise(NoiseParams *np, int seed, int sx, int sy, int sz=1);
138         ~Noise();
139
140         void setSize(int sx, int sy, int sz=1);
141         void setSpreadFactor(v3f spread);
142         void setOctaves(int octaves);
143
144         void gradientMap2D(
145                 float x, float y,
146                 float step_x, float step_y,
147                 int seed);
148         void gradientMap3D(
149                 float x, float y, float z,
150                 float step_x, float step_y, float step_z,
151                 int seed);
152
153         float *perlinMap2D(float x, float y, float *persistence_map=NULL);
154         float *perlinMap3D(float x, float y, float z, float *persistence_map=NULL);
155
156         inline float *perlinMap2D_PO(float x, float xoff, float y, float yoff,
157                 float *persistence_map=NULL)
158         {
159                 return perlinMap2D(
160                         x + xoff * np.spread.X,
161                         y + yoff * np.spread.Y,
162                         persistence_map);
163         }
164
165         inline float *perlinMap3D_PO(float x, float xoff, float y, float yoff,
166                 float z, float zoff, float *persistence_map=NULL)
167         {
168                 return perlinMap3D(
169                         x + xoff * np.spread.X,
170                         y + yoff * np.spread.Y,
171                         z + zoff * np.spread.Z,
172                         persistence_map);
173         }
174
175 private:
176         void allocBuffers();
177         void resizeNoiseBuf(bool is3d);
178         void updateResults(float g, float *gmap, float *persistence_map, size_t bufsize);
179
180 };
181
182 float NoisePerlin2D(NoiseParams *np, float x, float y, int seed);
183 float NoisePerlin3D(NoiseParams *np, float x, float y, float z, int seed);
184
185 inline float NoisePerlin2D_PO(NoiseParams *np, float x, float xoff,
186         float y, float yoff, int seed)
187 {
188         return NoisePerlin2D(np,
189                 x + xoff * np->spread.X,
190                 y + yoff * np->spread.Y,
191                 seed);
192 }
193
194 inline float NoisePerlin3D_PO(NoiseParams *np, float x, float xoff,
195         float y, float yoff, float z, float zoff, int seed)
196 {
197         return NoisePerlin3D(np,
198                 x + xoff * np->spread.X,
199                 y + yoff * np->spread.Y,
200                 z + zoff * np->spread.Z,
201                 seed);
202 }
203
204 // Return value: -1 ... 1
205 float noise2d(int x, int y, int seed);
206 float noise3d(int x, int y, int z, int seed);
207
208 float noise2d_gradient(float x, float y, int seed, bool eased=true);
209 float noise3d_gradient(float x, float y, float z, int seed, bool eased=false);
210
211 float noise2d_perlin(float x, float y, int seed,
212                 int octaves, float persistence, bool eased=true);
213
214 float noise2d_perlin_abs(float x, float y, int seed,
215                 int octaves, float persistence, bool eased=true);
216
217 float noise3d_perlin(float x, float y, float z, int seed,
218                 int octaves, float persistence, bool eased=false);
219
220 float noise3d_perlin_abs(float x, float y, float z, int seed,
221                 int octaves, float persistence, bool eased=false);
222
223 inline float easeCurve(float t)
224 {
225         return t * t * t * (t * (6.f * t - 15.f) + 10.f);
226 }
227
228 float contour(float v);
229
230 #endif
231