diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/noise.h | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/noise.h')
-rw-r--r-- | linden/indra/newview/noise.h | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/linden/indra/newview/noise.h b/linden/indra/newview/noise.h new file mode 100644 index 0000000..63ad3ab --- /dev/null +++ b/linden/indra/newview/noise.h | |||
@@ -0,0 +1,353 @@ | |||
1 | /** | ||
2 | * @file noise.h | ||
3 | * @brief Perlin noise routines for procedural textures, etc | ||
4 | * | ||
5 | * Copyright (c) 2000-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_NOISE_H | ||
29 | #define LL_NOISE_H | ||
30 | |||
31 | #include "llmath.h" | ||
32 | |||
33 | F32 turbulence2(F32 *v, F32 freq); | ||
34 | F32 turbulence3(float *v, float freq); | ||
35 | F32 clouds3(float *v, float freq); | ||
36 | F32 noise2(float *vec); | ||
37 | F32 noise3(float *vec); | ||
38 | |||
39 | inline F32 bias(F32 a, F32 b) | ||
40 | { | ||
41 | return (F32)pow(a, (F32)(log(b) / log(0.5f))); | ||
42 | } | ||
43 | |||
44 | inline F32 gain(F32 a, F32 b) | ||
45 | { | ||
46 | F32 p = (F32) (log(1.f - b) / log(0.5f)); | ||
47 | |||
48 | if (a < .001f) | ||
49 | return 0.f; | ||
50 | else if (a > .999f) | ||
51 | return 1.f; | ||
52 | if (a < 0.5f) | ||
53 | return (F32)(pow(2 * a, p) / 2.f); | ||
54 | else | ||
55 | return (F32)(1.f - pow(2 * (1.f - a), p) / 2.f); | ||
56 | } | ||
57 | |||
58 | inline F32 turbulence2(F32 *v, F32 freq) | ||
59 | { | ||
60 | F32 t, vec[2]; | ||
61 | |||
62 | for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) { | ||
63 | vec[0] = freq * v[0]; | ||
64 | vec[1] = freq * v[1]; | ||
65 | t += noise2(vec)/freq; | ||
66 | } | ||
67 | return t; | ||
68 | } | ||
69 | |||
70 | inline F32 turbulence3(F32 *v, F32 freq) | ||
71 | { | ||
72 | F32 t, vec[3]; | ||
73 | |||
74 | for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) { | ||
75 | vec[0] = freq * v[0]; | ||
76 | vec[1] = freq * v[1]; | ||
77 | vec[2] = freq * v[2]; | ||
78 | t += noise3(vec)/freq; | ||
79 | // t += fabs(noise3(vec)) / freq; // Like snow - bubbly at low frequencies | ||
80 | // t += sqrt(fabs(noise3(vec))) / freq; // Better at low freq | ||
81 | // t += (noise3(vec)*noise3(vec)) / freq; | ||
82 | } | ||
83 | return t; | ||
84 | } | ||
85 | |||
86 | inline F32 clouds3(F32 *v, F32 freq) | ||
87 | { | ||
88 | F32 t, vec[3]; | ||
89 | |||
90 | for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) { | ||
91 | vec[0] = freq * v[0]; | ||
92 | vec[1] = freq * v[1]; | ||
93 | vec[2] = freq * v[2]; | ||
94 | //t += noise3(vec)/freq; | ||
95 | // t += fabs(noise3(vec)) / freq; // Like snow - bubbly at low frequencies | ||
96 | // t += sqrt(fabs(noise3(vec))) / freq; // Better at low freq | ||
97 | t += (noise3(vec)*noise3(vec)) / freq; | ||
98 | } | ||
99 | return t; | ||
100 | } | ||
101 | |||
102 | /* noise functions over 1, 2, and 3 dimensions */ | ||
103 | |||
104 | #define B 0x100 | ||
105 | #define BM 0xff | ||
106 | |||
107 | #define N 0x1000 | ||
108 | #define NF32 (4096.f) | ||
109 | #define NP 12 /* 2^N */ | ||
110 | #define NM 0xfff | ||
111 | |||
112 | extern S32 p[B + B + 2]; | ||
113 | extern F32 g3[B + B + 2][3]; | ||
114 | extern F32 g2[B + B + 2][2]; | ||
115 | extern F32 g1[B + B + 2]; | ||
116 | extern S32 gNoiseStart; | ||
117 | |||
118 | static void init(void); | ||
119 | |||
120 | #define s_curve(t) ( t * t * (3.f - 2.f * t) ) | ||
121 | |||
122 | #define lerp_m(t, a, b) ( a + t * (b - a) ) | ||
123 | |||
124 | #define setup_noise(i,b0,b1,r0,r1)\ | ||
125 | t = vec[i] + N;\ | ||
126 | b0 = (lltrunc(t)) & BM;\ | ||
127 | b1 = (b0+1) & BM;\ | ||
128 | r0 = t - lltrunc(t);\ | ||
129 | r1 = r0 - 1.f; | ||
130 | |||
131 | |||
132 | inline void fast_setup(F32 vec, U8 &b0, U8 &b1, F32 &r0, F32 &r1) | ||
133 | { | ||
134 | S32 t_S32; | ||
135 | |||
136 | r1 = vec + NF32; | ||
137 | t_S32 = lltrunc(r1); | ||
138 | b0 = (U8)t_S32; | ||
139 | b1 = b0 + 1; | ||
140 | r0 = r1 - t_S32; | ||
141 | r1 = r0 - 1.f; | ||
142 | } | ||
143 | |||
144 | inline F32 noise1(const F32 arg) | ||
145 | { | ||
146 | int bx0, bx1; | ||
147 | F32 rx0, rx1, sx, t, u, v, vec[1]; | ||
148 | |||
149 | vec[0] = arg; | ||
150 | if (gNoiseStart) { | ||
151 | gNoiseStart = 0; | ||
152 | init(); | ||
153 | } | ||
154 | |||
155 | setup_noise(0, bx0,bx1, rx0,rx1); | ||
156 | |||
157 | sx = s_curve(rx0); | ||
158 | |||
159 | u = rx0 * g1[ p[ bx0 ] ]; | ||
160 | v = rx1 * g1[ p[ bx1 ] ]; | ||
161 | |||
162 | return lerp_m(sx, u, v); | ||
163 | } | ||
164 | |||
165 | inline F32 fast_at2(F32 rx, F32 ry, F32 *q) | ||
166 | { | ||
167 | return rx * (*q) + ry * (*(q + 1)); | ||
168 | } | ||
169 | |||
170 | |||
171 | |||
172 | inline F32 fast_at3(F32 rx, F32 ry, F32 rz, F32 *q) | ||
173 | { | ||
174 | return rx * (*q) + ry * (*(q + 1)) + rz * (*(q + 2)); | ||
175 | } | ||
176 | |||
177 | |||
178 | |||
179 | inline F32 noise3(F32 *vec) | ||
180 | { | ||
181 | U8 bx0, bx1, by0, by1, bz0, bz1; | ||
182 | S32 b00, b10, b01, b11; | ||
183 | F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; | ||
184 | S32 i, j; | ||
185 | |||
186 | if (gNoiseStart) { | ||
187 | gNoiseStart = 0; | ||
188 | init(); | ||
189 | } | ||
190 | |||
191 | fast_setup(*vec, bx0,bx1, rx0,rx1); | ||
192 | fast_setup(*(vec + 1), by0,by1, ry0,ry1); | ||
193 | fast_setup(*(vec + 2), 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 = s_curve(rx0); | ||
204 | sy = s_curve(ry0); | ||
205 | sz = s_curve(rz0); | ||
206 | |||
207 | q = g3[ b00 + bz0 ]; | ||
208 | u = fast_at3(rx0,ry0,rz0,q); | ||
209 | q = g3[ b10 + bz0 ]; | ||
210 | v = fast_at3(rx1,ry0,rz0,q); | ||
211 | a = lerp_m(t, u, v); | ||
212 | |||
213 | q = g3[ b01 + bz0 ]; | ||
214 | u = fast_at3(rx0,ry1,rz0,q); | ||
215 | q = g3[ b11 + bz0 ]; | ||
216 | v = fast_at3(rx1,ry1,rz0,q); | ||
217 | b = lerp_m(t, u, v); | ||
218 | |||
219 | c = lerp_m(sy, a, b); | ||
220 | |||
221 | q = g3[ b00 + bz1 ]; | ||
222 | u = fast_at3(rx0,ry0,rz1,q); | ||
223 | q = g3[ b10 + bz1 ]; | ||
224 | v = fast_at3(rx1,ry0,rz1,q); | ||
225 | a = lerp_m(t, u, v); | ||
226 | |||
227 | q = g3[ b01 + bz1 ]; | ||
228 | u = fast_at3(rx0,ry1,rz1,q); | ||
229 | q = g3[ b11 + bz1 ]; | ||
230 | v = fast_at3(rx1,ry1,rz1,q); | ||
231 | b = lerp_m(t, u, v); | ||
232 | |||
233 | d = lerp_m(sy, a, b); | ||
234 | |||
235 | return lerp_m(sz, c, d); | ||
236 | } | ||
237 | |||
238 | |||
239 | /* | ||
240 | F32 noise3(F32 *vec) | ||
241 | { | ||
242 | int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; | ||
243 | F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; | ||
244 | S32 i, j; | ||
245 | |||
246 | if (gNoiseStart) { | ||
247 | gNoiseStart = 0; | ||
248 | init(); | ||
249 | } | ||
250 | |||
251 | setup_noise(0, bx0,bx1, rx0,rx1); | ||
252 | setup_noise(1, by0,by1, ry0,ry1); | ||
253 | setup_noise(2, bz0,bz1, rz0,rz1); | ||
254 | |||
255 | i = p[ bx0 ]; | ||
256 | j = p[ bx1 ]; | ||
257 | |||
258 | b00 = p[ i + by0 ]; | ||
259 | b10 = p[ j + by0 ]; | ||
260 | b01 = p[ i + by1 ]; | ||
261 | b11 = p[ j + by1 ]; | ||
262 | |||
263 | t = s_curve(rx0); | ||
264 | sy = s_curve(ry0); | ||
265 | sz = s_curve(rz0); | ||
266 | |||
267 | #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] ) | ||
268 | |||
269 | q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0); | ||
270 | q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0); | ||
271 | a = lerp_m(t, u, v); | ||
272 | |||
273 | q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0); | ||
274 | q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0); | ||
275 | b = lerp_m(t, u, v); | ||
276 | |||
277 | c = lerp_m(sy, a, b); | ||
278 | |||
279 | q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1); | ||
280 | q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1); | ||
281 | a = lerp_m(t, u, v); | ||
282 | |||
283 | q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1); | ||
284 | q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1); | ||
285 | b = lerp_m(t, u, v); | ||
286 | |||
287 | d = lerp_m(sy, a, b); | ||
288 | |||
289 | return lerp_m(sz, c, d); | ||
290 | } | ||
291 | */ | ||
292 | |||
293 | static void normalize2(F32 v[2]) | ||
294 | { | ||
295 | F32 s; | ||
296 | |||
297 | s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]); | ||
298 | v[0] = v[0] * s; | ||
299 | v[1] = v[1] * s; | ||
300 | } | ||
301 | |||
302 | static void normalize3(F32 v[3]) | ||
303 | { | ||
304 | F32 s; | ||
305 | |||
306 | s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); | ||
307 | v[0] = v[0] * s; | ||
308 | v[1] = v[1] * s; | ||
309 | v[2] = v[2] * s; | ||
310 | } | ||
311 | |||
312 | static void init(void) | ||
313 | { | ||
314 | int i, j, k; | ||
315 | |||
316 | for (i = 0 ; i < B ; i++) { | ||
317 | p[i] = i; | ||
318 | |||
319 | g1[i] = (F32)((rand() % (B + B)) - B) / B; | ||
320 | |||
321 | for (j = 0 ; j < 2 ; j++) | ||
322 | g2[i][j] = (F32)((rand() % (B + B)) - B) / B; | ||
323 | normalize2(g2[i]); | ||
324 | |||
325 | for (j = 0 ; j < 3 ; j++) | ||
326 | g3[i][j] = (F32)((rand() % (B + B)) - B) / B; | ||
327 | normalize3(g3[i]); | ||
328 | } | ||
329 | |||
330 | while (--i) { | ||
331 | k = p[i]; | ||
332 | p[i] = p[j = rand() % B]; | ||
333 | p[j] = k; | ||
334 | } | ||
335 | |||
336 | for (i = 0 ; i < B + 2 ; i++) { | ||
337 | p[B + i] = p[i]; | ||
338 | g1[B + i] = g1[i]; | ||
339 | for (j = 0 ; j < 2 ; j++) | ||
340 | g2[B + i][j] = g2[i][j]; | ||
341 | for (j = 0 ; j < 3 ; j++) | ||
342 | g3[B + i][j] = g3[i][j]; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | #undef B | ||
347 | #undef BM | ||
348 | #undef N | ||
349 | #undef NF32 | ||
350 | #undef NP | ||
351 | #undef NM | ||
352 | |||
353 | #endif // LL_NOISE_ | ||