noise.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_NOISE_H
00033 #define LL_NOISE_H
00034 
00035 #include "llmath.h"
00036 
00037 F32 turbulence2(F32 *v, F32 freq);
00038 F32 turbulence3(float *v, float freq);
00039 F32 clouds3(float *v, float freq);
00040 F32 noise2(float *vec);
00041 F32 noise3(float *vec);
00042 
00043 inline F32 bias(F32 a, F32 b)
00044 {
00045         return (F32)pow(a, (F32)(log(b) / log(0.5f)));
00046 }
00047 
00048 inline F32 gain(F32 a, F32 b)
00049 {
00050         F32 p = (F32) (log(1.f - b) / log(0.5f));
00051 
00052         if (a < .001f)
00053                 return 0.f;
00054         else if (a > .999f)
00055                 return 1.f;
00056         if (a < 0.5f)
00057                 return (F32)(pow(2 * a, p) / 2.f);
00058         else
00059                 return (F32)(1.f - pow(2 * (1.f - a), p) / 2.f);
00060 }
00061 
00062 inline F32 turbulence2(F32 *v, F32 freq)
00063 {
00064         F32 t, vec[2];
00065 
00066         for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
00067                 vec[0] = freq * v[0];
00068                 vec[1] = freq * v[1];
00069                 t += noise2(vec)/freq;
00070         }
00071         return t;
00072 }
00073 
00074 inline F32 turbulence3(F32 *v, F32 freq)
00075 {
00076         F32 t, vec[3];
00077 
00078         for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
00079                 vec[0] = freq * v[0];
00080                 vec[1] = freq * v[1];
00081                 vec[2] = freq * v[2];
00082                 t += noise3(vec)/freq;
00083 //              t += fabs(noise3(vec)) / freq;                          // Like snow - bubbly at low frequencies
00084 //              t += sqrt(fabs(noise3(vec))) / freq;            // Better at low freq
00085 //              t += (noise3(vec)*noise3(vec)) / freq;          
00086         }
00087         return t;
00088 }
00089 
00090 inline F32 clouds3(F32 *v, F32 freq)
00091 {
00092         F32 t, vec[3];
00093 
00094         for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
00095                 vec[0] = freq * v[0];
00096                 vec[1] = freq * v[1];
00097                 vec[2] = freq * v[2];
00098                 //t += noise3(vec)/freq;
00099 //              t += fabs(noise3(vec)) / freq;                          // Like snow - bubbly at low frequencies
00100 //              t += sqrt(fabs(noise3(vec))) / freq;            // Better at low freq
00101                 t += (noise3(vec)*noise3(vec)) / freq;          
00102         }
00103         return t;
00104 }
00105 
00106 /* noise functions over 1, 2, and 3 dimensions */
00107 
00108 #define B 0x100
00109 #define BM 0xff
00110 
00111 #define N 0x1000
00112 #define NF32 (4096.f)
00113 #define NP 12   /* 2^N */
00114 #define NM 0xfff
00115 
00116 extern S32 p[B + B + 2];
00117 extern F32 g3[B + B + 2][3];
00118 extern F32 g2[B + B + 2][2];
00119 extern F32 g1[B + B + 2];
00120 extern S32 gNoiseStart;
00121 
00122 static void init(void);
00123 
00124 #define s_curve(t) ( t * t * (3.f - 2.f * t) )
00125 
00126 #define lerp_m(t, a, b) ( a + t * (b - a) )
00127 
00128 #define setup_noise(i,b0,b1,r0,r1)\
00129         t = vec[i] + N;\
00130         b0 = (lltrunc(t)) & BM;\
00131         b1 = (b0+1) & BM;\
00132         r0 = t - lltrunc(t);\
00133         r1 = r0 - 1.f;
00134 
00135 
00136 inline void fast_setup(F32 vec, U8 &b0, U8 &b1, F32 &r0, F32 &r1)
00137 {
00138         S32 t_S32;
00139 
00140         r1      = vec + NF32;
00141         t_S32 = lltrunc(r1);
00142         b0 = (U8)t_S32;
00143         b1 = b0 + 1;
00144         r0 = r1 - t_S32;
00145         r1 = r0 - 1.f;
00146 }
00147 
00148 inline F32 noise1(const F32 arg)
00149 {
00150         int bx0, bx1;
00151         F32 rx0, rx1, sx, t, u, v, vec[1];
00152 
00153         vec[0] = arg;
00154         if (gNoiseStart) {
00155                 gNoiseStart = 0;
00156                 init();
00157         }
00158 
00159         setup_noise(0, bx0,bx1, rx0,rx1);
00160 
00161         sx = s_curve(rx0);
00162 
00163         u = rx0 * g1[ p[ bx0 ] ];
00164         v = rx1 * g1[ p[ bx1 ] ];
00165 
00166         return lerp_m(sx, u, v);
00167 }
00168 
00169 inline F32 fast_at2(F32 rx, F32 ry, F32 *q)
00170 {
00171         return rx * (*q) + ry * (*(q + 1));
00172 }
00173 
00174 
00175 
00176 inline F32 fast_at3(F32 rx, F32 ry, F32 rz, F32 *q)
00177 {
00178         return rx * (*q) + ry * (*(q + 1)) + rz * (*(q + 2));
00179 }
00180 
00181 
00182 
00183 inline F32 noise3(F32 *vec)
00184 {
00185         U8 bx0, bx1, by0, by1, bz0, bz1;
00186         S32 b00, b10, b01, b11;
00187         F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
00188         S32 i, j;
00189 
00190         if (gNoiseStart) {
00191                 gNoiseStart = 0;
00192                 init();
00193         }
00194 
00195         fast_setup(*vec, bx0,bx1, rx0,rx1);
00196         fast_setup(*(vec + 1), by0,by1, ry0,ry1);
00197         fast_setup(*(vec + 2), bz0,bz1, rz0,rz1);
00198 
00199         i = p[ bx0 ];
00200         j = p[ bx1 ];
00201 
00202         b00 = p[ i + by0 ];
00203         b10 = p[ j + by0 ];
00204         b01 = p[ i + by1 ];
00205         b11 = p[ j + by1 ];
00206 
00207         t  = s_curve(rx0);
00208         sy = s_curve(ry0);
00209         sz = s_curve(rz0);
00210 
00211         q = g3[ b00 + bz0 ]; 
00212         u = fast_at3(rx0,ry0,rz0,q);
00213         q = g3[ b10 + bz0 ];
00214         v = fast_at3(rx1,ry0,rz0,q);
00215         a = lerp_m(t, u, v);
00216 
00217         q = g3[ b01 + bz0 ];
00218         u = fast_at3(rx0,ry1,rz0,q);
00219         q = g3[ b11 + bz0 ];
00220         v = fast_at3(rx1,ry1,rz0,q);
00221         b = lerp_m(t, u, v);
00222 
00223         c = lerp_m(sy, a, b);
00224 
00225         q = g3[ b00 + bz1 ];
00226         u = fast_at3(rx0,ry0,rz1,q);
00227         q = g3[ b10 + bz1 ];
00228         v = fast_at3(rx1,ry0,rz1,q);
00229         a = lerp_m(t, u, v);
00230 
00231         q = g3[ b01 + bz1 ];
00232         u = fast_at3(rx0,ry1,rz1,q);
00233         q = g3[ b11 + bz1 ];
00234         v = fast_at3(rx1,ry1,rz1,q);
00235         b = lerp_m(t, u, v);
00236 
00237         d = lerp_m(sy, a, b);
00238 
00239         return lerp_m(sz, c, d);
00240 }
00241 
00242 
00243 /*
00244 F32 noise3(F32 *vec)
00245 {
00246         int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
00247         F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
00248         S32 i, j;
00249 
00250         if (gNoiseStart) {
00251                 gNoiseStart = 0;
00252                 init();
00253         }
00254 
00255         setup_noise(0, bx0,bx1, rx0,rx1);
00256         setup_noise(1, by0,by1, ry0,ry1);
00257         setup_noise(2, bz0,bz1, rz0,rz1);
00258 
00259         i = p[ bx0 ];
00260         j = p[ bx1 ];
00261 
00262         b00 = p[ i + by0 ];
00263         b10 = p[ j + by0 ];
00264         b01 = p[ i + by1 ];
00265         b11 = p[ j + by1 ];
00266 
00267         t  = s_curve(rx0);
00268         sy = s_curve(ry0);
00269         sz = s_curve(rz0);
00270 
00271 #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
00272 
00273         q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
00274         q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
00275         a = lerp_m(t, u, v);
00276 
00277         q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
00278         q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
00279         b = lerp_m(t, u, v);
00280 
00281         c = lerp_m(sy, a, b);
00282 
00283         q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
00284         q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
00285         a = lerp_m(t, u, v);
00286 
00287         q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
00288         q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
00289         b = lerp_m(t, u, v);
00290 
00291         d = lerp_m(sy, a, b);
00292 
00293         return lerp_m(sz, c, d);
00294 }
00295 */
00296 
00297 static void normalize2(F32 v[2])
00298 {
00299         F32 s;
00300 
00301         s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]);
00302         v[0] = v[0] * s;
00303         v[1] = v[1] * s;
00304 }
00305 
00306 static void normalize3(F32 v[3])
00307 {
00308         F32 s;
00309 
00310         s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00311         v[0] = v[0] * s;
00312         v[1] = v[1] * s;
00313         v[2] = v[2] * s;
00314 }
00315 
00316 static void init(void)
00317 {
00318         int i, j, k;
00319 
00320         for (i = 0 ; i < B ; i++) {
00321                 p[i] = i;
00322 
00323                 g1[i] = (F32)((rand() % (B + B)) - B) / B;
00324 
00325                 for (j = 0 ; j < 2 ; j++)
00326                         g2[i][j] = (F32)((rand() % (B + B)) - B) / B;
00327                 normalize2(g2[i]);
00328 
00329                 for (j = 0 ; j < 3 ; j++)
00330                         g3[i][j] = (F32)((rand() % (B + B)) - B) / B;
00331                 normalize3(g3[i]);
00332         }
00333 
00334         while (--i) {
00335                 k = p[i];
00336                 p[i] = p[j = rand() % B];
00337                 p[j] = k;
00338         }
00339 
00340         for (i = 0 ; i < B + 2 ; i++) {
00341                 p[B + i] = p[i];
00342                 g1[B + i] = g1[i];
00343                 for (j = 0 ; j < 2 ; j++)
00344                         g2[B + i][j] = g2[i][j];
00345                 for (j = 0 ; j < 3 ; j++)
00346                         g3[B + i][j] = g3[i][j];
00347         }
00348 }
00349 
00350 #undef B
00351 #undef BM
00352 #undef N
00353 #undef NF32
00354 #undef NP
00355 #undef NM
00356 
00357 #endif // LL_NOISE_

Generated on Thu Jul 1 06:09:57 2010 for Second Life Viewer by  doxygen 1.4.7