Fix various compiler warnings.
[blender-staging.git] / source / blender / freestyle / intern / geometry / Noise.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/freestyle/intern/geometry/Noise.cpp
22  *  \ingroup freestyle
23  *  \brief Class to define Perlin noise
24  *  \author Emmanuel Turquin
25  *  \date 12/01/2004
26  */
27
28 #include <math.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <time.h>
32
33 #include "Noise.h"
34
35 namespace Freestyle {
36
37 #define SCURVE(a) ((a) * (a) * (3.0 - 2.0 * (a)))
38
39 #if 0  // XXX Unused
40 #define REALSCALE (2.0 / 65536.0)
41 #define NREALSCALE (2.0 / 4096.0)
42
43 #define HASH3D(a, b, c) hashTable[hashTable[hashTable[(a) & 0xfff] ^ ((b) & 0xfff)] ^ ((c) & 0xfff)]
44 #define HASH(a, b, c) (xtab[(xtab[(xtab[(a) & 0xff] ^ (b)) & 0xff] ^ (c)) & 0xff] & 0xff)
45 #define INCRSUM(m, s, x, y, z) \
46         ((s) * (RTable[m] * 0.5 + RTable[m + 1] * (x) + RTable[m + 2] * (y) + RTable[m + 3] * (z)))
47
48 #define MAXSIZE 500
49 #define NRAND() ((float)rand() / (float)RAND_MAX)
50 #endif
51 #define SEEDNRAND(x) (srand(x * RAND_MAX))
52
53 #define BM 0xff
54 #define N  0x1000
55 #if 0  // XXX Unused
56 #define NP 12  /* 2^N */
57 #define NM 0xfff
58 #endif
59
60 #define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
61
62 #define SETUP(i, b0, b1, r0, r1) \
63         {                            \
64                 (t) = (i) + (N);         \
65                 (r0) = modff((t), &(u));  \
66                 (r1) = (r0) - 1.0;       \
67                 (b0) = ((int)(u)) & BM;  \
68                 (b1) = ((b0) + 1) & BM;  \
69         } (void)0
70
71 static void normalize2(float v[2])
72 {
73         float s;
74
75         s = sqrt(v[0] * v[0] + v[1] * v[1]);
76         v[0] = v[0] / s;
77         v[1] = v[1] / s;
78 }
79
80 static void normalize3(float v[3])
81 {
82         float s;
83
84         s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
85         v[0] = v[0] / s;
86         v[1] = v[1] / s;
87         v[2] = v[2] / s;
88 }
89
90 float Noise::turbulence1(float arg, float freq, float amp, unsigned oct)
91 {
92         float t;
93         float vec;
94
95         for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
96                 vec = freq * arg;
97                 t += smoothNoise1(vec) * amp;
98         }
99         return t;
100 }
101
102 float Noise::turbulence2(Vec2f& v, float freq, float amp, unsigned oct)
103 {
104         float t;
105         Vec2f vec;
106
107         for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
108                 vec.x() = freq * v.x();
109                 vec.y() = freq * v.y();
110                 t += smoothNoise2(vec) * amp;
111         }
112         return t;
113 }
114
115 float Noise::turbulence3(Vec3f& v, float freq, float amp, unsigned oct)
116 {
117         float t;
118         Vec3f vec;
119
120         for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
121                 vec.x() = freq * v.x();
122                 vec.y() = freq * v.y();
123                 vec.z() = freq * v.z();
124                 t += smoothNoise3(vec) * amp;
125         }
126         return t;
127 }
128
129 // Noise functions over 1, 2, and 3 dimensions
130 float Noise::smoothNoise1(float arg)
131 {
132         int bx0, bx1;
133         float rx0, rx1, sx, t, u, v, vec;
134
135         vec = arg;
136         SETUP(vec, bx0, bx1, rx0, rx1);
137
138         sx = SCURVE(rx0);
139
140         u = rx0 * g1[p[bx0]];
141         v = rx1 * g1[p[bx1]];
142
143         return LERP(sx, u, v);
144 }
145
146 float Noise::smoothNoise2(Vec2f& vec)
147 {
148         int bx0, bx1, by0, by1, b00, b10, b01, b11;
149         float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
150         int i, j;
151
152         SETUP(vec.x(), bx0, bx1, rx0, rx1);
153         SETUP(vec.y(), by0, by1, ry0, ry1);
154
155         i = p[bx0];
156         j = p[bx1];
157
158         b00 = p[i + by0];
159         b10 = p[j + by0];
160         b01 = p[i + by1];
161         b11 = p[j + by1];
162
163         sx = SCURVE(rx0);
164         sy = SCURVE(ry0);
165
166 #define AT2(rx, ry) ((rx) * q[0] + (ry) * q[1])
167
168         q = g2[b00];
169         u = AT2(rx0, ry0);
170         q = g2[b10];
171         v = AT2(rx1, ry0);
172         a = LERP(sx, u, v);
173
174         q = g2[b01];
175         u = AT2(rx0, ry1);
176         q = g2[b11];
177         v = AT2(rx1, ry1);
178         b = LERP(sx, u, v);
179
180 #undef AT2
181
182         return LERP(sy, a, b);
183 }
184
185 float Noise::smoothNoise3(Vec3f& vec)
186 {
187         int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
188         float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
189         int i, j;
190
191         SETUP(vec.x(), bx0, bx1, rx0, rx1);
192         SETUP(vec.y(), by0, by1, ry0, ry1);
193         SETUP(vec.z(), bz0, bz1, rz0, rz1);
194
195         i = p[bx0];
196         j = p[bx1];
197
198         b00 = p[i + by0];
199         b10 = p[j + by0];
200         b01 = p[i + by1];
201         b11 = p[j + by1];
202
203         t  = SCURVE(rx0);
204         sy = SCURVE(ry0);
205         sz = SCURVE(rz0);
206
207 #define AT3(rx, ry, rz) ((rx) * q[0] + (ry) * q[1] + (rz) * q[2])
208
209         q = g3[b00 + bz0];
210         u = AT3(rx0, ry0, rz0);
211         q = g3[b10 + bz0];
212         v = AT3(rx1, ry0, rz0);
213         a = LERP(t, u, v);
214
215         q = g3[b01 + bz0];
216         u = AT3(rx0, ry1, rz0);
217         q = g3[b11 + bz0];
218         v = AT3(rx1, ry1, rz0);
219         b = LERP(t, u, v);
220
221         c = LERP(sy, a, b);
222
223         q = g3[b00 + bz1];
224         u = AT3(rx0, ry0, rz1);
225         q = g3[b10 + bz1];
226         v = AT3(rx1, ry0, rz1);
227         a = LERP(t, u, v);
228
229         q = g3[b01 + bz1];
230         u = AT3(rx0, ry1, rz1);
231         q = g3[b11 + bz1];
232         v = AT3(rx1, ry1, rz1);
233         b = LERP(t, u, v);
234
235         d = LERP(sy, a, b);
236
237 #undef AT3
238
239         return LERP(sz, c, d);
240 }
241
242 Noise::Noise(long seed)
243 {
244         int i, j, k;
245
246         SEEDNRAND((seed < 0) ? time(NULL) : seed);
247         for (i = 0 ; i < _NOISE_B ; i++) {
248                 p[i] = i;
249                 g1[i] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
250
251                 for (j = 0 ; j < 2 ; j++)
252                         g2[i][j] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
253                 normalize2(g2[i]);
254
255                 for (j = 0 ; j < 3 ; j++)
256                         g3[i][j] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
257                 normalize3(g3[i]);
258         }
259
260         while (--i) {
261                 k = p[i];
262                 p[i] = p[j = rand() % _NOISE_B];
263                 p[j] = k;
264         }
265
266         for (i = 0 ; i < _NOISE_B + 2 ; i++) {
267                 p[_NOISE_B + i] = p[i];
268                 g1[_NOISE_B + i] = g1[i];
269
270                 for (j = 0 ; j < 2 ; j++)
271                         g2[_NOISE_B + i][j] = g2[i][j];
272
273                 for (j = 0 ; j < 3 ; j++)
274                         g3[_NOISE_B + i][j] = g3[i][j];
275         }
276 }
277
278 } /* namespace Freestyle */