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/llmath/llperlin.cpp | |
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/llmath/llperlin.cpp')
-rw-r--r-- | linden/indra/llmath/llperlin.cpp | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/linden/indra/llmath/llperlin.cpp b/linden/indra/llmath/llperlin.cpp new file mode 100644 index 0000000..553b6a1 --- /dev/null +++ b/linden/indra/llmath/llperlin.cpp | |||
@@ -0,0 +1,295 @@ | |||
1 | /** | ||
2 | * @file llperlin.cpp | ||
3 | * | ||
4 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
5 | * | ||
6 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
7 | * to you under the terms of the GNU General Public License, version 2.0 | ||
8 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
9 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
10 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
11 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
12 | * | ||
13 | * There are special exceptions to the terms and conditions of the GPL as | ||
14 | * it is applied to this Source Code. View the full text of the exception | ||
15 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
16 | * online at http://secondlife.com/developers/opensource/flossexception | ||
17 | * | ||
18 | * By copying, modifying or distributing this software, you acknowledge | ||
19 | * that you have read and understood your obligations described above, | ||
20 | * and agree to abide by those obligations. | ||
21 | * | ||
22 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
23 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
24 | * COMPLETENESS OR PERFORMANCE. | ||
25 | */ | ||
26 | |||
27 | #include "linden_common.h" | ||
28 | #include "llmath.h" | ||
29 | |||
30 | #include "llperlin.h" | ||
31 | |||
32 | #define B 0x100 | ||
33 | #define BM 0xff | ||
34 | #define N 0x1000 | ||
35 | #define NF32 (4096.f) | ||
36 | #define NP 12 /* 2^N */ | ||
37 | #define NM 0xfff | ||
38 | |||
39 | static S32 p[B + B + 2]; | ||
40 | static F32 g3[B + B + 2][3]; | ||
41 | static F32 g2[B + B + 2][2]; | ||
42 | static F32 g1[B + B + 2]; | ||
43 | |||
44 | bool LLPerlinNoise::sInitialized = 0; | ||
45 | |||
46 | static void normalize2(F32 v[2]) | ||
47 | { | ||
48 | F32 s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]); | ||
49 | v[0] = v[0] * s; | ||
50 | v[1] = v[1] * s; | ||
51 | } | ||
52 | |||
53 | static void normalize3(F32 v[3]) | ||
54 | { | ||
55 | F32 s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); | ||
56 | v[0] = v[0] * s; | ||
57 | v[1] = v[1] * s; | ||
58 | v[2] = v[2] * s; | ||
59 | } | ||
60 | |||
61 | static void fast_setup(F32 vec, U8 &b0, U8 &b1, F32 &r0, F32 &r1) | ||
62 | { | ||
63 | S32 t_S32; | ||
64 | |||
65 | r1 = vec + NF32; | ||
66 | t_S32 = lltrunc(r1); | ||
67 | b0 = (U8)t_S32; | ||
68 | b1 = b0 + 1; | ||
69 | r0 = r1 - t_S32; | ||
70 | r1 = r0 - 1.f; | ||
71 | } | ||
72 | |||
73 | |||
74 | void LLPerlinNoise::init(void) | ||
75 | { | ||
76 | int i, j, k; | ||
77 | |||
78 | for (i = 0 ; i < B ; i++) | ||
79 | { | ||
80 | p[i] = i; | ||
81 | |||
82 | g1[i] = (F32)((rand() % (B + B)) - B) / B; | ||
83 | |||
84 | for (j = 0 ; j < 2 ; j++) | ||
85 | g2[i][j] = (F32)((rand() % (B + B)) - B) / B; | ||
86 | normalize2(g2[i]); | ||
87 | |||
88 | for (j = 0 ; j < 3 ; j++) | ||
89 | g3[i][j] = (F32)((rand() % (B + B)) - B) / B; | ||
90 | normalize3(g3[i]); | ||
91 | } | ||
92 | |||
93 | while (--i) | ||
94 | { | ||
95 | k = p[i]; | ||
96 | p[i] = p[j = rand() % B]; | ||
97 | p[j] = k; | ||
98 | } | ||
99 | |||
100 | for (i = 0 ; i < B + 2 ; i++) | ||
101 | { | ||
102 | p[B + i] = p[i]; | ||
103 | g1[B + i] = g1[i]; | ||
104 | for (j = 0 ; j < 2 ; j++) | ||
105 | g2[B + i][j] = g2[i][j]; | ||
106 | for (j = 0 ; j < 3 ; j++) | ||
107 | g3[B + i][j] = g3[i][j]; | ||
108 | } | ||
109 | |||
110 | sInitialized = true; | ||
111 | } | ||
112 | |||
113 | |||
114 | //============================================================================ | ||
115 | // Noise functions | ||
116 | |||
117 | #define s_curve(t) ( t * t * (3.f - 2.f * t) ) | ||
118 | |||
119 | #define lerp_m(t, a, b) ( a + t * (b - a) ) | ||
120 | |||
121 | F32 LLPerlinNoise::noise1(F32 x) | ||
122 | { | ||
123 | int bx0, bx1; | ||
124 | F32 rx0, rx1, sx, t, u, v; | ||
125 | |||
126 | if (!sInitialized) | ||
127 | init(); | ||
128 | |||
129 | t = x + N; | ||
130 | bx0 = (lltrunc(t)) & BM; | ||
131 | bx1 = (bx0+1) & BM; | ||
132 | rx0 = t - lltrunc(t); | ||
133 | rx1 = rx0 - 1.f; | ||
134 | |||
135 | sx = s_curve(rx0); | ||
136 | |||
137 | u = rx0 * g1[ p[ bx0 ] ]; | ||
138 | v = rx1 * g1[ p[ bx1 ] ]; | ||
139 | |||
140 | return lerp_m(sx, u, v); | ||
141 | } | ||
142 | |||
143 | static F32 fast_at2(F32 rx, F32 ry, F32 *q) | ||
144 | { | ||
145 | return rx * q[0] + ry * q[1]; | ||
146 | } | ||
147 | |||
148 | F32 LLPerlinNoise::noise2(F32 x, F32 y) | ||
149 | { | ||
150 | U8 bx0, bx1, by0, by1; | ||
151 | U32 b00, b10, b01, b11; | ||
152 | F32 rx0, rx1, ry0, ry1, *q, sx, sy, a, b, u, v; | ||
153 | S32 i, j; | ||
154 | |||
155 | if (!sInitialized) | ||
156 | init(); | ||
157 | |||
158 | fast_setup(x, bx0, bx1, rx0, rx1); | ||
159 | fast_setup(y, by0, by1, ry0, ry1); | ||
160 | |||
161 | i = *(p + bx0); | ||
162 | j = *(p + bx1); | ||
163 | |||
164 | b00 = *(p + i + by0); | ||
165 | b10 = *(p + j + by0); | ||
166 | b01 = *(p + i + by1); | ||
167 | b11 = *(p + j + by1); | ||
168 | |||
169 | sx = s_curve(rx0); | ||
170 | sy = s_curve(ry0); | ||
171 | |||
172 | |||
173 | q = *(g2 + b00); | ||
174 | u = fast_at2(rx0, ry0, q); | ||
175 | q = *(g2 + b10); | ||
176 | v = fast_at2(rx1, ry0, q); | ||
177 | a = lerp_m(sx, u, v); | ||
178 | |||
179 | q = *(g2 + b01); | ||
180 | u = fast_at2(rx0,ry1,q); | ||
181 | q = *(g2 + b11); | ||
182 | v = fast_at2(rx1,ry1,q); | ||
183 | b = lerp_m(sx, u, v); | ||
184 | |||
185 | return lerp_m(sy, a, b); | ||
186 | } | ||
187 | |||
188 | static F32 fast_at3(F32 rx, F32 ry, F32 rz, F32 *q) | ||
189 | { | ||
190 | return rx * q[0] + ry * q[1] + rz * q[2]; | ||
191 | } | ||
192 | |||
193 | F32 LLPerlinNoise::noise3(F32 x, F32 y, F32 z) | ||
194 | { | ||
195 | U8 bx0, bx1, by0, by1, bz0, bz1; | ||
196 | S32 b00, b10, b01, b11; | ||
197 | F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; | ||
198 | S32 i, j; | ||
199 | |||
200 | if (!sInitialized) | ||
201 | init(); | ||
202 | |||
203 | fast_setup(x, bx0,bx1, rx0,rx1); | ||
204 | fast_setup(y, by0,by1, ry0,ry1); | ||
205 | fast_setup(z, bz0,bz1, rz0,rz1); | ||
206 | |||
207 | i = p[ bx0 ]; | ||
208 | j = p[ bx1 ]; | ||
209 | |||
210 | b00 = p[ i + by0 ]; | ||
211 | b10 = p[ j + by0 ]; | ||
212 | b01 = p[ i + by1 ]; | ||
213 | b11 = p[ j + by1 ]; | ||
214 | |||
215 | t = s_curve(rx0); | ||
216 | sy = s_curve(ry0); | ||
217 | sz = s_curve(rz0); | ||
218 | |||
219 | q = g3[ b00 + bz0 ]; | ||
220 | u = fast_at3(rx0,ry0,rz0,q); | ||
221 | q = g3[ b10 + bz0 ]; | ||
222 | v = fast_at3(rx1,ry0,rz0,q); | ||
223 | a = lerp_m(t, u, v); | ||
224 | |||
225 | q = g3[ b01 + bz0 ]; | ||
226 | u = fast_at3(rx0,ry1,rz0,q); | ||
227 | q = g3[ b11 + bz0 ]; | ||
228 | v = fast_at3(rx1,ry1,rz0,q); | ||
229 | b = lerp_m(t, u, v); | ||
230 | |||
231 | c = lerp_m(sy, a, b); | ||
232 | |||
233 | q = g3[ b00 + bz1 ]; | ||
234 | u = fast_at3(rx0,ry0,rz1,q); | ||
235 | q = g3[ b10 + bz1 ]; | ||
236 | v = fast_at3(rx1,ry0,rz1,q); | ||
237 | a = lerp_m(t, u, v); | ||
238 | |||
239 | q = g3[ b01 + bz1 ]; | ||
240 | u = fast_at3(rx0,ry1,rz1,q); | ||
241 | q = g3[ b11 + bz1 ]; | ||
242 | v = fast_at3(rx1,ry1,rz1,q); | ||
243 | b = lerp_m(t, u, v); | ||
244 | |||
245 | d = lerp_m(sy, a, b); | ||
246 | |||
247 | return lerp_m(sz, c, d); | ||
248 | } | ||
249 | |||
250 | F32 LLPerlinNoise::turbulence2(F32 x, F32 y, F32 freq) | ||
251 | { | ||
252 | F32 t, lx, ly; | ||
253 | |||
254 | for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) | ||
255 | { | ||
256 | lx = freq * x; | ||
257 | ly = freq * y; | ||
258 | t += noise2(lx, ly)/freq; | ||
259 | } | ||
260 | return t; | ||
261 | } | ||
262 | |||
263 | F32 LLPerlinNoise::turbulence3(F32 x, F32 y, F32 z, F32 freq) | ||
264 | { | ||
265 | F32 t, lx, ly, lz; | ||
266 | |||
267 | for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) | ||
268 | { | ||
269 | lx = freq * x; | ||
270 | ly = freq * y; | ||
271 | lz = freq * z; | ||
272 | t += noise3(lx,ly,lz)/freq; | ||
273 | // t += fabs(noise3(lx,ly,lz)) / freq; // Like snow - bubbly at low frequencies | ||
274 | // t += sqrt(fabs(noise3(lx,ly,lz))) / freq; // Better at low freq | ||
275 | // t += (noise3(lx,ly,lz)*noise3(lx,ly,lz)) / freq; | ||
276 | } | ||
277 | return t; | ||
278 | } | ||
279 | |||
280 | F32 LLPerlinNoise::clouds3(F32 x, F32 y, F32 z, F32 freq) | ||
281 | { | ||
282 | F32 t, lx, ly, lz; | ||
283 | |||
284 | for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) | ||
285 | { | ||
286 | lx = freq * x; | ||
287 | ly = freq * y; | ||
288 | lz = freq * z; | ||
289 | // t += noise3(lx,ly,lz)/freq; | ||
290 | // t += fabs(noise3(lx,ly,lz)) / freq; // Like snow - bubbly at low frequencies | ||
291 | // t += sqrt(fabs(noise3(lx,ly,lz))) / freq; // Better at low freq | ||
292 | t += (noise3(lx,ly,lz)*noise3(lx,ly,lz)) / freq; | ||
293 | } | ||
294 | return t; | ||
295 | } | ||