00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "PNoise.h"
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <math.h>
00027 #include <time.h>
00028
00029
00030
00031 #define B 0x100
00032 #define BM 0xff
00033 #define N 0x1000
00034 #define NP 12
00035 #define NM 0xfff
00036
00037 #define s_curve(t) ( t * t * (3. - 2. * t) )
00038 #define lerp(t, a, b) ( a + t * (b - a) )
00039 #define setup(i,b0,b1,r0,r1)\
00040 t = vec[i] + N;\
00041 b0 = ((int)t) & BM;\
00042 b1 = (b0+1) & BM;\
00043 r0 = t - (int)t;\
00044 r1 = r0 - 1.;
00045 #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
00046 #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
00047
00048
00049
00050
00051
00052 PNoise::PNoise()
00053 {
00054 p = new int[B + B + 2];
00055
00056 g3 = new double*[B + B + 2];
00057 for(int i=0; i<(B + B + 2); ++i){
00058 g3[i] = new double[3];
00059 }
00060
00061 g2 = new double*[B + B + 2];
00062 for(int i=0; i<(B + B + 2); ++i){
00063 g2[i] = new double[2];
00064 }
00065
00066 g1 = new double[B + B + 2];
00067
00068 start = 1;
00069
00070 _n = 1;
00071 _alpha = 2;
00072 _beta = 2;
00073
00074 seed();
00075 init();
00076 }
00077
00078 PNoise::PNoise(int s)
00079 {
00080 p = new int[B + B + 2];
00081
00082 g3 = new double*[B + B + 2];
00083 for(int i=0; i<(B + B + 2); ++i){
00084 g3[i] = new double[3];
00085 }
00086
00087 g2 = new double*[B + B + 2];
00088 for(int i=0; i<(B + B + 2); ++i){
00089 g2[i] = new double[2];
00090 }
00091
00092 g1 = new double[B + B + 2];
00093
00094 start = 1;
00095
00096 _n = 1;
00097 _alpha = 2;
00098 _beta = 2;
00099
00100 seed(s);
00101 init();
00102 }
00103
00104 PNoise::~PNoise()
00105 {
00106 delete[] p;
00107 for(int i=0; i< B+B+2; ++ i)
00108 delete[] g3[i];
00109 delete[] g3;
00110 for(int i=0; i< B+B+2; ++ i)
00111 delete[] g2[i];
00112 delete[] g2;
00113 delete[] g1;
00114 }
00115
00116
00117
00118
00119
00120 void PNoise::seed()
00121 {
00122 srand(time(NULL));
00123 }
00124
00125 void PNoise::seed(int s)
00126 {
00127 srand(s);
00128 }
00129
00130
00131 double PNoise::PerlinNoise1D(double x, int n, double alpha,double beta)
00132 {
00133 int i;
00134 double val,sum = 0;
00135 double p,scale = 1;
00136
00137 p = x;
00138 for (i=0;i<n;i++) {
00139 val = noise1(p);
00140 sum += val / scale;
00141 scale *= alpha;
00142 p *= beta;
00143 }
00144 return(sum);
00145 }
00146
00147
00148
00149 double PNoise::PerlinNoise2D(double x,double y, int n, double alpha,double beta)
00150 {
00151 int i;
00152 double val,sum = 0;
00153 double p[2],scale = 1;
00154
00155 p[0] = x;
00156 p[1] = y;
00157 for (i=0;i<n;i++) {
00158 val = noise2(p);
00159 sum += val / scale;
00160 scale *= alpha;
00161 p[0] *= beta;
00162 p[1] *= beta;
00163 }
00164 return(sum);
00165 }
00166
00167
00168
00169 double PNoise::PerlinNoise3D(double x,double y,double z, int n, double alpha,double beta)
00170 {
00171 int i;
00172 double val,sum = 0;
00173 double p[3],scale = 1;
00174
00175 p[0] = x;
00176 p[1] = y;
00177 p[2] = z;
00178 for (i=0;i<n;i++) {
00179 val = noise3(p);
00180 sum += val / scale;
00181 scale *= alpha;
00182 p[0] *= beta;
00183 p[1] *= beta;
00184 p[2] *= beta;
00185 }
00186 return(sum);
00187 }
00188
00189
00190
00191 #ifndef ABS
00192 #define ABS(x) ((x)<0 ? (-x) : (x))
00193 #endif
00194
00195 double PNoise::PerlinNoise3DABS(double x,double y,double z, int n, double alpha,double beta)
00196 {
00197 int i;
00198 double val,sum = 0;
00199 double p[3],scale = 1;
00200
00201 p[0] = x;
00202 p[1] = y;
00203 p[2] = z;
00204 for (i=0;i<n;i++) {
00205 val = noise3(p);
00206 val = ABS(val);
00207 sum += val / scale;
00208 scale *= alpha;
00209 p[0] *= beta;
00210 p[1] *= beta;
00211 p[2] *= beta;
00212 }
00213 return(sum);
00214 }
00215
00216
00217
00218 void PNoise::setParams(int n, double alpha, double beta)
00219 {
00220 _alpha = alpha;
00221 _beta = beta;
00222 _n = n;
00223 }
00224
00225
00226
00227 double PNoise::PN1D(double x)
00228 {
00229 return PerlinNoise1D(x,_n,_alpha,_beta);
00230 }
00231
00232
00233
00234 double PNoise::PN2D(double x, double y)
00235 {
00236 return PerlinNoise2D(x, y, _n, _alpha, _beta);
00237 }
00238
00239
00240
00241 double PNoise::PN3D(double x, double y, double z)
00242 {
00243 return PerlinNoise3D(x,y,z, _n, _alpha, _beta);
00244 }
00245
00246
00247
00248 double PNoise::PN3DA(double x, double y, double z)
00249 {
00250 return PerlinNoise3DABS(x,y,z, _n, _alpha, _beta);
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 inline int PNoise::random()
00263 {
00264 return rand();
00265 }
00266
00267
00268
00269 double PNoise::noise1(double arg)
00270 {
00271 int bx0, bx1;
00272 double rx0, rx1, sx, t, u, v, vec[1];
00273
00274 vec[0] = arg;
00275 if (start) {
00276 start = 0;
00277 init();
00278 }
00279
00280 setup(0,bx0,bx1,rx0,rx1);
00281
00282 sx = s_curve(rx0);
00283 u = rx0 * g1[ p[ bx0 ] ];
00284 v = rx1 * g1[ p[ bx1 ] ];
00285
00286 return(lerp(sx, u, v));
00287 }
00288
00289
00290
00291 double PNoise::noise2(double vec[2])
00292 {
00293 int bx0, bx1, by0, by1, b00, b10, b01, b11;
00294 double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
00295 int i, j;
00296
00297 if (start) {
00298 start = 0;
00299 init();
00300 }
00301
00302 setup(0, bx0,bx1, rx0,rx1);
00303 setup(1, by0,by1, ry0,ry1);
00304
00305 i = p[ bx0 ];
00306 j = p[ bx1 ];
00307
00308 b00 = p[ i + by0 ];
00309 b10 = p[ j + by0 ];
00310 b01 = p[ i + by1 ];
00311 b11 = p[ j + by1 ];
00312
00313 sx = s_curve(rx0);
00314 sy = s_curve(ry0);
00315
00316 q = g2[ b00 ] ; u = at2(rx0,ry0);
00317 q = g2[ b10 ] ; v = at2(rx1,ry0);
00318 a = lerp(sx, u, v);
00319
00320 q = g2[ b01 ] ; u = at2(rx0,ry1);
00321 q = g2[ b11 ] ; v = at2(rx1,ry1);
00322 b = lerp(sx, u, v);
00323
00324 return lerp(sy, a, b);
00325 }
00326
00327
00328
00329 double PNoise::noise3(double vec[3])
00330 {
00331 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
00332 double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
00333 int i, j;
00334
00335 if (start) {
00336 start = 0;
00337 init();
00338 }
00339
00340 setup(0, bx0,bx1, rx0,rx1);
00341 setup(1, by0,by1, ry0,ry1);
00342 setup(2, bz0,bz1, rz0,rz1);
00343
00344 i = p[ bx0 ];
00345 j = p[ bx1 ];
00346
00347 b00 = p[ i + by0 ];
00348 b10 = p[ j + by0 ];
00349 b01 = p[ i + by1 ];
00350 b11 = p[ j + by1 ];
00351
00352 t = s_curve(rx0);
00353 sy = s_curve(ry0);
00354 sz = s_curve(rz0);
00355
00356 q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
00357 q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
00358 a = lerp(t, u, v);
00359
00360 q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
00361 q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
00362 b = lerp(t, u, v);
00363
00364 c = lerp(sy, a, b);
00365
00366 q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
00367 q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
00368 a = lerp(t, u, v);
00369
00370 q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
00371 q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
00372 b = lerp(t, u, v);
00373
00374 d = lerp(sy, a, b);
00375
00376 return lerp(sz, c, d);
00377 }
00378
00379
00380
00381 void PNoise::normalize2(double v[2])
00382 {
00383 double s;
00384
00385 s = sqrt(v[0] * v[0] + v[1] * v[1]);
00386 v[0] = v[0] / s;
00387 v[1] = v[1] / s;
00388 }
00389
00390
00391
00392 void PNoise::normalize3(double v[3])
00393 {
00394 double s;
00395
00396 s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00397 v[0] = v[0] / s;
00398 v[1] = v[1] / s;
00399 v[2] = v[2] / s;
00400 }
00401
00402
00403
00404 void PNoise::init(void)
00405 {
00406 int i, j, k;
00407
00408 for (i = 0 ; i < B ; i++) {
00409 p[i] = i;
00410 g1[i] = (double)((random() % (B + B)) - B) / B;
00411
00412 for (j = 0 ; j < 2 ; j++)
00413 g2[i][j] = (double)((random() % (B + B)) - B) / B;
00414 normalize2(g2[i]);
00415
00416 for (j = 0 ; j < 3 ; j++)
00417 g3[i][j] = (double)((random() % (B + B)) - B) / B;
00418 normalize3(g3[i]);
00419 }
00420
00421 while (--i) {
00422 k = p[i];
00423 p[i] = p[j = random() % B];
00424 p[j] = k;
00425 }
00426
00427 for (i = 0 ; i < B + 2 ; i++) {
00428 p[B + i] = p[i];
00429 g1[B + i] = g1[i];
00430 for (j = 0 ; j < 2 ; j++)
00431 g2[B + i][j] = g2[i][j];
00432 for (j = 0 ; j < 3 ; j++)
00433 g3[B + i][j] = g3[i][j];
00434 }
00435 }
00436
00437
00438
00439 void gen2DPerlinTexture(float *&data, unsigned int sx, unsigned int sy,
00440 unsigned int comp,
00441 int octaves,
00442 float frequencyScale,
00443 float amplitudeScale,
00444 bool absNoise)
00445 {
00446 PNoise *parray = new PNoise[comp];
00447 for(unsigned int i=0; i< comp; ++i)
00448 {
00449 parray->seed(i);
00450 parray->setParams(octaves,frequencyScale, amplitudeScale);
00451 }
00452
00453 data = new float[sx*sy*comp];
00454
00455 for(unsigned int y=0; y<sy; ++y)
00456 {
00457 for(unsigned int x=0; x<sx; ++x)
00458 {
00459 for(unsigned int c=0; c<comp; ++c)
00460 {
00461 if(absNoise)
00462 {
00463 data[y*sx*comp + x*comp + c] = float(parray[c].PN2D(x/float(sx),y/float(sy))) * .5f + .5f;
00464 }
00465 else
00466 {
00467 data[y*sx*comp + x*comp + c] = float(parray[c].PN3DA(x/float(sx),y/float(sy),0)) * .5f + .5f;
00468 }
00469 }
00470 }
00471 }
00472
00473 }
00474
00475
00476
00477 void gen3DPerlinTexture(float *&data, unsigned int sx, unsigned int sy, unsigned int sz,
00478 unsigned int comp,
00479 int octaves,
00480 float frequencyScale,
00481 float amplitudeScale,
00482 bool absNoise)
00483 {
00484 PNoise *parray = new PNoise[comp];
00485 for(unsigned int i=0; i< comp; ++i)
00486 {
00487 parray->seed(rand());
00488 parray->setParams(octaves,frequencyScale, amplitudeScale);
00489 }
00490
00491 data = new float[sx*sy*sz*comp];
00492
00493 for(unsigned int z=0; z<sz; ++z)
00494 {
00495 for(unsigned int y=0; y<sy; ++y)
00496 {
00497 for(unsigned int x=0; x<sx; ++x)
00498 {
00499 for(unsigned int c=0; c<comp; ++c)
00500 {
00501 if(!absNoise)
00502 {
00503 data[z*sy*sx*comp + y*sx*comp + x*comp + c] = float(parray[c].PN3D(x/float(sx/8),y/float(sx/8),z/float(sx/8))) * .5f + .5f;
00504 }
00505 else
00506 {
00507 data[z*sy*sx*comp + y*sx*comp + x*comp + c] = float(parray[c].PN3DA(x/float(sx/8),y/float(sy/8),z/float(sz/8))) * .5f + .5f;
00508 }
00509 }
00510 }
00511 }
00512 }
00513 }
00514