Blender  V2.93
Noise.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
22 #include <cmath>
23 #include <cstdio>
24 #include <cstdlib>
25 #include <ctime>
26 
27 #include "BLI_compiler_attrs.h"
28 #include "BLI_rand.h"
29 
30 #include "Noise.h"
31 
32 namespace Freestyle {
33 
34 #define SCURVE(a) ((a) * (a) * (3.0 - 2.0 * (a)))
35 
36 #if 0 // XXX Unused
37 # define REALSCALE (2.0 / 65536.0)
38 # define NREALSCALE (2.0 / 4096.0)
39 
40 # define HASH3D(a, b, c) hashTable[hashTable[hashTable[(a)&0xfff] ^ ((b)&0xfff)] ^ ((c)&0xfff)]
41 # define HASH(a, b, c) (xtab[(xtab[(xtab[(a)&0xff] ^ (b)) & 0xff] ^ (c)) & 0xff] & 0xff)
42 # define INCRSUM(m, s, x, y, z) \
43  ((s) * (RTable[m] * 0.5 + RTable[m + 1] * (x) + RTable[m + 2] * (y) + RTable[m + 3] * (z)))
44 
45 # define MAXSIZE 500
46 #endif
47 
48 #define BM 0xff
49 #define N 0x1000
50 #if 0 // XXX Unused
51 # define NP 12 /* 2^N */
52 # define NM 0xfff
53 #endif
54 
55 #define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
56 
57 #define SETUP(i, b0, b1, r0, r1) \
58  { \
59  (t) = (i) + (N); \
60  (r0) = modff((t), &(u)); \
61  (r1) = (r0)-1.0; \
62  (b0) = ((int)(u)) & BM; \
63  (b1) = ((b0) + 1) & BM; \
64  } \
65  (void)0
66 
67 static void normalize2(float v[2])
68 {
69  float s;
70 
71  s = sqrt(v[0] * v[0] + v[1] * v[1]);
72  v[0] = v[0] / s;
73  v[1] = v[1] / s;
74 }
75 
76 static void normalize3(float v[3])
77 {
78  float s;
79 
80  s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
81  v[0] = v[0] / s;
82  v[1] = v[1] / s;
83  v[2] = v[2] / s;
84 }
85 
86 float Noise::turbulence1(float arg, float freq, float amp, unsigned oct)
87 {
88  float t;
89  float vec;
90 
91  for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
92  vec = freq * arg;
93  t += smoothNoise1(vec) * amp;
94  }
95  return t;
96 }
97 
98 float Noise::turbulence2(Vec2f &v, float freq, float amp, unsigned oct)
99 {
100  float t;
101  Vec2f vec;
102 
103  for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
104  vec.x() = freq * v.x();
105  vec.y() = freq * v.y();
106  t += smoothNoise2(vec) * amp;
107  }
108  return t;
109 }
110 
111 float Noise::turbulence3(Vec3f &v, float freq, float amp, unsigned oct)
112 {
113  float t;
114  Vec3f vec;
115 
116  for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
117  vec.x() = freq * v.x();
118  vec.y() = freq * v.y();
119  vec.z() = freq * v.z();
120  t += smoothNoise3(vec) * amp;
121  }
122  return t;
123 }
124 
125 // Noise functions over 1, 2, and 3 dimensions
126 float Noise::smoothNoise1(float arg)
127 {
128  int bx0, bx1;
129  float rx0, rx1, sx, t, u, v, vec;
130 
131  vec = arg;
132  SETUP(vec, bx0, bx1, rx0, rx1);
133 
134  sx = SCURVE(rx0);
135 
136  u = rx0 * g1[p[bx0]];
137  v = rx1 * g1[p[bx1]];
138 
139  return LERP(sx, u, v);
140 }
141 
143 {
144  int bx0, bx1, by0, by1, b00, b10, b01, b11;
145  float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
146  int i, j;
147 
148  SETUP(vec.x(), bx0, bx1, rx0, rx1);
149  SETUP(vec.y(), by0, by1, ry0, ry1);
150 
151  i = p[bx0];
152  j = p[bx1];
153 
154  b00 = p[i + by0];
155  b10 = p[j + by0];
156  b01 = p[i + by1];
157  b11 = p[j + by1];
158 
159  sx = SCURVE(rx0);
160  sy = SCURVE(ry0);
161 
162 #define AT2(rx, ry) ((rx)*q[0] + (ry)*q[1])
163 
164  q = g2[b00];
165  u = AT2(rx0, ry0);
166  q = g2[b10];
167  v = AT2(rx1, ry0);
168  a = LERP(sx, u, v);
169 
170  q = g2[b01];
171  u = AT2(rx0, ry1);
172  q = g2[b11];
173  v = AT2(rx1, ry1);
174  b = LERP(sx, u, v);
175 
176 #undef AT2
177 
178  return LERP(sy, a, b);
179 }
180 
182 {
183  int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
184  float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
185  int i, j;
186 
187  SETUP(vec.x(), bx0, bx1, rx0, rx1);
188  SETUP(vec.y(), by0, by1, ry0, ry1);
189  SETUP(vec.z(), bz0, bz1, rz0, rz1);
190 
191  i = p[bx0];
192  j = p[bx1];
193 
194  b00 = p[i + by0];
195  b10 = p[j + by0];
196  b01 = p[i + by1];
197  b11 = p[j + by1];
198 
199  t = SCURVE(rx0);
200  sy = SCURVE(ry0);
201  sz = SCURVE(rz0);
202 
203 #define AT3(rx, ry, rz) ((rx)*q[0] + (ry)*q[1] + (rz)*q[2])
204 
205  q = g3[b00 + bz0];
206  u = AT3(rx0, ry0, rz0);
207  q = g3[b10 + bz0];
208  v = AT3(rx1, ry0, rz0);
209  a = LERP(t, u, v);
210 
211  q = g3[b01 + bz0];
212  u = AT3(rx0, ry1, rz0);
213  q = g3[b11 + bz0];
214  v = AT3(rx1, ry1, rz0);
215  b = LERP(t, u, v);
216 
217  c = LERP(sy, a, b);
218 
219  q = g3[b00 + bz1];
220  u = AT3(rx0, ry0, rz1);
221  q = g3[b10 + bz1];
222  v = AT3(rx1, ry0, rz1);
223  a = LERP(t, u, v);
224 
225  q = g3[b01 + bz1];
226  u = AT3(rx0, ry1, rz1);
227  q = g3[b11 + bz1];
228  v = AT3(rx1, ry1, rz1);
229  b = LERP(t, u, v);
230 
231  d = LERP(sy, a, b);
232 
233 #undef AT3
234 
235  return LERP(sz, c, d);
236 }
237 
239 {
240  /* Use Blender RNG for repeatable results across platforms. */
241  RNG *rng = BLI_rng_new(seed);
242  int i, j, k;
243 
244  for (i = 0; i < _NOISE_B; i++) {
245  p[i] = i;
246  g1[i] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
247 
248  for (j = 0; j < 2; j++) {
249  g2[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
250  }
251  normalize2(g2[i]);
252 
253  for (j = 0; j < 3; j++) {
254  g3[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
255  }
256  normalize3(g3[i]);
257  }
258 
259  while (--i) {
260  k = p[i];
261  p[i] = p[j = BLI_rng_get_int(rng) % _NOISE_B];
262  p[j] = k;
263  }
264 
265  for (i = 0; i < _NOISE_B + 2; i++) {
266  p[_NOISE_B + i] = p[i];
267  g1[_NOISE_B + i] = g1[i];
268 
269  for (j = 0; j < 2; j++) {
270  g2[_NOISE_B + i][j] = g2[i][j];
271  }
272 
273  for (j = 0; j < 3; j++) {
274  g3[_NOISE_B + i][j] = g3[i][j];
275  }
276  }
277 
278  BLI_rng_free(rng);
279 }
280 
281 } /* namespace Freestyle */
typedef float(TangentPoint)[2]
sqrt(x)+1/max(0
Random number functions.
void int BLI_rng_get_int(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:99
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:76
struct RNG * BLI_rng_new(unsigned int seed)
Definition: rand.cc:54
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
#define SCURVE(a)
Definition: Noise.cpp:34
#define AT2(rx, ry)
#define SETUP(i, b0, b1, r0, r1)
Definition: Noise.cpp:57
#define LERP(t, a, b)
Definition: Noise.cpp:55
#define AT3(rx, ry, rz)
Class to define Perlin noise.
#define _NOISE_B
Definition: Noise.h:36
ATTR_WARN_UNUSED_RESULT const BMVert * v
static unsigned long seed
Definition: btSoftBody.h:39
float turbulence2(Vec2f &v, float freq, float amp, unsigned oct=4)
Definition: Noise.cpp:98
float turbulence3(Vec3f &v, float freq, float amp, unsigned oct=4)
Definition: Noise.cpp:111
float smoothNoise3(Vec3f &vec)
Definition: Noise.cpp:181
float smoothNoise1(float arg)
Definition: Noise.cpp:126
float turbulence1(float arg, float freq, float amp, unsigned oct=4)
Definition: Noise.cpp:86
Noise(long seed=-1)
Definition: Noise.cpp:238
float smoothNoise2(Vec2f &vec)
Definition: Noise.cpp:142
value_type x() const
Definition: VecMat.h:319
value_type y() const
Definition: VecMat.h:329
value_type x() const
Definition: VecMat.h:532
value_type z() const
Definition: VecMat.h:552
value_type y() const
Definition: VecMat.h:542
inherits from class Rep
Definition: AppCanvas.cpp:32
static unsigned c
Definition: RandGen.cpp:97
static void normalize3(float v[3])
Definition: Noise.cpp:76
static void normalize2(float v[2])
Definition: Noise.cpp:67
static unsigned a[3]
Definition: RandGen.cpp:92
Definition: rand.cc:48