PageRenderTime 65ms CodeModel.GetById 46ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/noise.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 352 lines | 204 code | 63 blank | 85 comment | 16 complexity | 60f53c5014245e9260ab51b15b23b0f1 MD5 | raw file
  1/** 
  2 * @file noise.h
  3 * @brief Perlin noise routines for procedural textures, etc
  4 *
  5 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_NOISE_H
 28#define LL_NOISE_H
 29
 30#include "llmath.h"
 31
 32F32 turbulence2(F32 *v, F32 freq);
 33F32 turbulence3(float *v, float freq);
 34F32 clouds3(float *v, float freq);
 35F32 noise2(float *vec);
 36F32 noise3(float *vec);
 37
 38inline F32 bias(F32 a, F32 b)
 39{
 40	return (F32)pow(a, (F32)(log(b) / log(0.5f)));
 41}
 42
 43inline F32 gain(F32 a, F32 b)
 44{
 45	F32 p = (F32) (log(1.f - b) / log(0.5f));
 46
 47	if (a < .001f)
 48		return 0.f;
 49	else if (a > .999f)
 50		return 1.f;
 51	if (a < 0.5f)
 52		return (F32)(pow(2 * a, p) / 2.f);
 53	else
 54		return (F32)(1.f - pow(2 * (1.f - a), p) / 2.f);
 55}
 56
 57inline F32 turbulence2(F32 *v, F32 freq)
 58{
 59	F32 t, vec[2];
 60
 61	for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
 62		vec[0] = freq * v[0];
 63		vec[1] = freq * v[1];
 64		t += noise2(vec)/freq;
 65	}
 66	return t;
 67}
 68
 69inline F32 turbulence3(F32 *v, F32 freq)
 70{
 71	F32 t, vec[3];
 72
 73	for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
 74		vec[0] = freq * v[0];
 75		vec[1] = freq * v[1];
 76		vec[2] = freq * v[2];
 77		t += noise3(vec)/freq;
 78//		t += fabs(noise3(vec)) / freq;				// Like snow - bubbly at low frequencies
 79//		t += sqrt(fabs(noise3(vec))) / freq;		// Better at low freq
 80//		t += (noise3(vec)*noise3(vec)) / freq;		
 81	}
 82	return t;
 83}
 84
 85inline F32 clouds3(F32 *v, F32 freq)
 86{
 87	F32 t, vec[3];
 88
 89	for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
 90		vec[0] = freq * v[0];
 91		vec[1] = freq * v[1];
 92		vec[2] = freq * v[2];
 93		//t += noise3(vec)/freq;
 94//		t += fabs(noise3(vec)) / freq;				// Like snow - bubbly at low frequencies
 95//		t += sqrt(fabs(noise3(vec))) / freq;		// Better at low freq
 96		t += (noise3(vec)*noise3(vec)) / freq;		
 97	}
 98	return t;
 99}
100
101/* noise functions over 1, 2, and 3 dimensions */
102
103#define B 0x100
104#define BM 0xff
105
106#define N 0x1000
107#define NF32 (4096.f)
108#define NP 12   /* 2^N */
109#define NM 0xfff
110
111extern S32 p[B + B + 2];
112extern F32 g3[B + B + 2][3];
113extern F32 g2[B + B + 2][2];
114extern F32 g1[B + B + 2];
115extern S32 gNoiseStart;
116
117static void init(void);
118
119#define s_curve(t) ( t * t * (3.f - 2.f * t) )
120
121#define lerp_m(t, a, b) ( a + t * (b - a) )
122
123#define setup_noise(i,b0,b1,r0,r1)\
124	t = vec[i] + N;\
125	b0 = (lltrunc(t)) & BM;\
126	b1 = (b0+1) & BM;\
127	r0 = t - lltrunc(t);\
128	r1 = r0 - 1.f;
129
130
131inline void fast_setup(F32 vec, U8 &b0, U8 &b1, F32 &r0, F32 &r1)
132{
133	S32 t_S32;
134
135	r1	= vec + NF32;
136	t_S32 = lltrunc(r1);
137	b0 = (U8)t_S32;
138	b1 = b0 + 1;
139	r0 = r1 - t_S32;
140	r1 = r0 - 1.f;
141}
142
143inline F32 noise1(const F32 arg)
144{
145	int bx0, bx1;
146	F32 rx0, rx1, sx, t, u, v, vec[1];
147
148	vec[0] = arg;
149	if (gNoiseStart) {
150		gNoiseStart = 0;
151		init();
152	}
153
154	setup_noise(0, bx0,bx1, rx0,rx1);
155
156	sx = s_curve(rx0);
157
158	u = rx0 * g1[ p[ bx0 ] ];
159	v = rx1 * g1[ p[ bx1 ] ];
160
161	return lerp_m(sx, u, v);
162}
163
164inline F32 fast_at2(F32 rx, F32 ry, F32 *q)
165{
166	return rx * (*q) + ry * (*(q + 1));
167}
168
169
170
171inline F32 fast_at3(F32 rx, F32 ry, F32 rz, F32 *q)
172{
173	return rx * (*q) + ry * (*(q + 1)) + rz * (*(q + 2));
174}
175
176
177
178inline F32 noise3(F32 *vec)
179{
180	U8 bx0, bx1, by0, by1, bz0, bz1;
181	S32 b00, b10, b01, b11;
182	F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
183	S32 i, j;
184
185	if (gNoiseStart) {
186		gNoiseStart = 0;
187		init();
188	}
189
190	fast_setup(*vec, bx0,bx1, rx0,rx1);
191	fast_setup(*(vec + 1), by0,by1, ry0,ry1);
192	fast_setup(*(vec + 2), bz0,bz1, rz0,rz1);
193
194	i = p[ bx0 ];
195	j = p[ bx1 ];
196
197	b00 = p[ i + by0 ];
198	b10 = p[ j + by0 ];
199	b01 = p[ i + by1 ];
200	b11 = p[ j + by1 ];
201
202	t  = s_curve(rx0);
203	sy = s_curve(ry0);
204	sz = s_curve(rz0);
205
206	q = g3[ b00 + bz0 ]; 
207	u = fast_at3(rx0,ry0,rz0,q);
208	q = g3[ b10 + bz0 ];
209	v = fast_at3(rx1,ry0,rz0,q);
210	a = lerp_m(t, u, v);
211
212	q = g3[ b01 + bz0 ];
213	u = fast_at3(rx0,ry1,rz0,q);
214	q = g3[ b11 + bz0 ];
215	v = fast_at3(rx1,ry1,rz0,q);
216	b = lerp_m(t, u, v);
217
218	c = lerp_m(sy, a, b);
219
220	q = g3[ b00 + bz1 ];
221	u = fast_at3(rx0,ry0,rz1,q);
222	q = g3[ b10 + bz1 ];
223	v = fast_at3(rx1,ry0,rz1,q);
224	a = lerp_m(t, u, v);
225
226	q = g3[ b01 + bz1 ];
227	u = fast_at3(rx0,ry1,rz1,q);
228	q = g3[ b11 + bz1 ];
229	v = fast_at3(rx1,ry1,rz1,q);
230	b = lerp_m(t, u, v);
231
232	d = lerp_m(sy, a, b);
233
234	return lerp_m(sz, c, d);
235}
236
237
238/*
239F32 noise3(F32 *vec)
240{
241	int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
242	F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
243	S32 i, j;
244
245	if (gNoiseStart) {
246		gNoiseStart = 0;
247		init();
248	}
249
250	setup_noise(0, bx0,bx1, rx0,rx1);
251	setup_noise(1, by0,by1, ry0,ry1);
252	setup_noise(2, bz0,bz1, rz0,rz1);
253
254	i = p[ bx0 ];
255	j = p[ bx1 ];
256
257	b00 = p[ i + by0 ];
258	b10 = p[ j + by0 ];
259	b01 = p[ i + by1 ];
260	b11 = p[ j + by1 ];
261
262	t  = s_curve(rx0);
263	sy = s_curve(ry0);
264	sz = s_curve(rz0);
265
266#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
267
268	q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
269	q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
270	a = lerp_m(t, u, v);
271
272	q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
273	q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
274	b = lerp_m(t, u, v);
275
276	c = lerp_m(sy, a, b);
277
278	q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
279	q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
280	a = lerp_m(t, u, v);
281
282	q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
283	q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
284	b = lerp_m(t, u, v);
285
286	d = lerp_m(sy, a, b);
287
288	return lerp_m(sz, c, d);
289}
290*/
291
292static void normalize2(F32 v[2])
293{
294	F32 s;
295
296	s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]);
297	v[0] = v[0] * s;
298	v[1] = v[1] * s;
299}
300
301static void normalize3(F32 v[3])
302{
303	F32 s;
304
305	s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
306	v[0] = v[0] * s;
307	v[1] = v[1] * s;
308	v[2] = v[2] * s;
309}
310
311static void init(void)
312{
313	int i, j, k;
314
315	for (i = 0 ; i < B ; i++) {
316		p[i] = i;
317
318		g1[i] = (F32)((rand() % (B + B)) - B) / B;
319
320		for (j = 0 ; j < 2 ; j++)
321			g2[i][j] = (F32)((rand() % (B + B)) - B) / B;
322		normalize2(g2[i]);
323
324		for (j = 0 ; j < 3 ; j++)
325			g3[i][j] = (F32)((rand() % (B + B)) - B) / B;
326		normalize3(g3[i]);
327	}
328
329	while (--i) {
330		k = p[i];
331		p[i] = p[j = rand() % B];
332		p[j] = k;
333	}
334
335	for (i = 0 ; i < B + 2 ; i++) {
336		p[B + i] = p[i];
337		g1[B + i] = g1[i];
338		for (j = 0 ; j < 2 ; j++)
339			g2[B + i][j] = g2[i][j];
340		for (j = 0 ; j < 3 ; j++)
341			g3[B + i][j] = g3[i][j];
342	}
343}
344
345#undef B
346#undef BM
347#undef N
348#undef NF32
349#undef NP
350#undef NM
351
352#endif // LL_NOISE_