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