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
00084
00085
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
00099
00100
00101 t += (noise3(vec)*noise3(vec)) / freq;
00102 }
00103 return t;
00104 }
00105
00106
00107
00108 #define B 0x100
00109 #define BM 0xff
00110
00111 #define N 0x1000
00112 #define NF32 (4096.f)
00113 #define NP 12
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
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
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_