home *** CD-ROM | disk | FTP | other *** search
-
-
- #include <math.h>
-
- /* Perlin Noise Function -- from Graphics Gems II */
-
- #if 0
- #define hermite(p0,p1,r0,r1,t) ( p0*((2.*t-3.)*t*t+1.) + \
- p1*(-2.*t+3.)*t*t + \
- r0*((t-2.)*t+1.)*t + \
- r1*(t-1.)*t*t )
-
- #define dhermite(p0,p1,r0,r1,t) ( p0*(t-1.)*6.*t + \
- p1*(-t+1.)*6.*t + \
- r0*((3.*t-4.)*t + 1.) + \
- r1*(3.*t-2.)*t )
- #else
- #define hermite(p0,p1,r0,r1,t) ( (p0-p1)*((2.*t-3.)*t*t) + p0 \
- r0*((t-2.)*t+1.)*t + \
- r1*(t-1.)*t*t )
-
- #define dhermite(p0,p1,r0,r1,t) ( (p0-p1)*(t-1.)*6.*t + \
- r0*((3.*t-4.)*t + 1.) + \
- r1*(3.*t-2.)*t )
- #endif
-
- #define rand3a(x,y,z) frand(67*(x)+59*(y)+71*(z))
- #define rand3b(x,y,z) frand(73*(x)+79*(y)+83*(z))
- #define rand3c(x,y,z) frand(89*(x)+97*(y)+101*(z))
- #define rand3d(x,y,z) frand(103*(x)+107*(y)+109*(z))
-
- short xlim[3][2]; /* integer bounds for point */
- short xint[3]; /* fractional part */
- double xarg[3]; /* fractional part */
-
- #if 0
- double frand(long s)
- { s = s<<13 ^ s;
- return (1.0 - ((s*(s*s*15731+789221)+1376312589)&0x7fffffff)
- / 1073741824.0 );
- }
- #else
- double frand(long s)
- { return (float)(rand24(s) - 128) * .0078125; /* / 128 */
- }
- #endif
-
- double calc_hermite(double p0,double p1,double r0,double r1,double t)
- { return (p0*((2.*t-3.)*t*t+1.) +
- p1*(-2.*t+3.)*t*t +
- r0*((t-2.)*t+1.)*t +
- r1*(t-1.)*t*t );
- }
-
- double calc_dhermite(double p0,double p1,double r0,double r1,double t)
- { return (p0*(t-1.)*6.*t +
- p1*(-t+1.)*6.*t +
- r0*((3.*t-4.)*t + 1.) +
- r1*(3.*t-2.)*t );
- }
-
- extern char rtable0[256],
- rtable1[256],
- rtable2[256],
- rtable3[256];
-
- long xyzrand16t(short,short,short,char *);
-
- #define HERMITE_TABSIZ 1024
- #define HERMITE_SCALE 0x0400
- #define HERMITE_UNITY 0x8000
-
- struct HermiteTable {
- short cp0,cp1,cr0,cr1, /* hermite coefficients */
- dp0,dp1,dr0,dr1; /* hermite derivative coeff. */
- float ep0,ep1,er0,er1,
- fp0,fp1,fr0,fr1;
- short t;
- };
-
- static struct HermiteTable h_table[HERMITE_TABSIZ];
- struct HermiteTable *h_arg[4];
-
- init_hermite()
- { float t;
- short i;
- struct HermiteTable *ht;
-
- for (i=0; i<HERMITE_TABSIZ; i++)
- { ht = &h_table[i];
-
- t = (float)i / (float)HERMITE_TABSIZ;
-
- ht->cp0 = ((2.*t-3.)*t*t+1.) * (float)HERMITE_SCALE;
- ht->cp1 = (-2.*t+3.)*t*t * (float)HERMITE_SCALE;
- ht->cr0 = ((t-2.)*t+1.)*t * (float)HERMITE_SCALE;
- ht->cr1 = (t-1.)*t*t * (float)HERMITE_SCALE;
-
- ht->dp0 = (t-1.)*6.*t * (float)HERMITE_SCALE;
- ht->dp1 = (-t+1.)*6.*t * (float)HERMITE_SCALE;
- ht->dr0 = ((3.*t-4.)*t + 1.) * (float)HERMITE_SCALE;
- ht->dr1 = (3.*t-2.)*t * (float)HERMITE_SCALE;
- #if 0
- ht->ep0 = ((2.*t-3.)*t*t+1.);
- ht->ep1 = (-2.*t+3.)*t*t;
- ht->er0 = ((t-2.)*t+1.)*t;
- ht->er1 = (t-1.)*t*t;
-
- ht->fp0 = (t-1.)*6.*t;
- ht->fp1 = (-t+1.)*6.*t;
- ht->fr0 = ((3.*t-4.)*t);
- ht->fr1 = (3.*t-2.)*t;
- #endif
- ht->t = (int)(t * 4096.0);
- }
- }
-
- long lerp_i(short p1, short p2, short t)
- { return p1 + (((p2 - p1) * t) >> 12);
- }
-
- #if 0
- interpolate(double f[4], short e[4], int i, int n)
- {
- if (n == 0)
- { long ix = xlim[0][i&1],
- iy = xlim[1][i>>1&1],
- iz = xlim[2][i>>2];
-
- #if 0
- f[0] = (float)(xyzrand16t(ix,iy,iz,rtable0) - 128);
- f[1] = (float)(xyzrand16t(ix,iy,iz,rtable1) - 128);
- f[2] = (float)(xyzrand16t(ix,iy,iz,rtable2) - 128);
- f[3] = (float)(xyzrand16t(ix,iy,iz,rtable3) - 128);
- #endif
-
- e[0] = ((xyzrand16t(ix,iy,iz,rtable0) - 128) << 5) + (1<<4);
- e[1] = ((xyzrand16t(ix,iy,iz,rtable1) - 128) << 5) + (1<<4);
- e[2] = ((xyzrand16t(ix,iy,iz,rtable2) - 128) << 5) + (1<<4);
- e[3] = ((xyzrand16t(ix,iy,iz,rtable3) - 128) << 5) + (1<<4);
-
- #if 0
- f[0] = rand3a(ix,iy,iz);
- f[1] = rand3b(ix,iy,iz);
- f[2] = rand3c(ix,iy,iz);
- f[3] = rand3d(ix,iy,iz);
- #endif
- return;
- }
- else
- { double f0[4], /* result for first half */
- f1[4]; /* result for second half */
- double t,
- nt;
- short e0[4],
- e1[4];
- struct HermiteTable *ht;
-
- n--;
- interpolate(f0,e0,i,n);
- interpolate(f1,e1,i|1<<n,n);
-
- ht = h_arg[n];
-
- e[0] = lerp_i( e0[0], e1[0], ht->t );
- e[1] = lerp_i( e0[1], e1[1], ht->t );
- e[2] = lerp_i( e0[2], e1[2], ht->t );
-
- e[3] = (e0[3] * ht->cp0 +
- e1[3] * ht->cp1 +
- e0[n] * ht->cr0 +
- e1[n] * ht->cr1) >> 10;
-
- /* e[3] = (int)(f[3] * 32.0); */
-
- #if 0
- t = xarg[n];
- nt = 1.0 - t;
-
- f[0] = nt*f0[0] + t*f1[0];
- f[1] = nt*f0[1] + t*f1[1];
- f[2] = nt*f0[2] + t*f1[2];
-
- /* f[3] = calc_hermite(f0[3], f1[3], f0[n], f1[n], t); */
- /* f[n] = calc_dhermite(f0[3], f1[3], f0[n], f1[n], t); */
- #endif
- }
- }
- #else
- interpolate(short e[4], int i, int n)
- {
- if (n == 0)
- { long ix = xlim[0][i&1],
- iy = xlim[1][i>>1&1],
- iz = xlim[2][i>>2];
-
- e[0] = ((xyzrand16t(ix,iy,iz,rtable0) - 128) << 5) + (1<<4);
- e[1] = ((xyzrand16t(ix,iy,iz,rtable1) - 128) << 5) + (1<<4);
- e[2] = ((xyzrand16t(ix,iy,iz,rtable2) - 128) << 5) + (1<<4);
- e[3] = ((xyzrand16t(ix,iy,iz,rtable3) - 128) << 5) + (1<<4);
- return;
- }
- else
- { short e0[4],
- e1[4];
- struct HermiteTable *ht;
-
- n--;
- interpolate(e0,i,n);
- interpolate(e1,i|1<<n,n);
-
- ht = h_arg[n];
-
- e[0] = lerp_i( e0[0], e1[0], ht->t );
- e[1] = lerp_i( e0[1], e1[1], ht->t );
- e[2] = lerp_i( e0[2], e1[2], ht->t );
-
- e[3] = (e0[3] * ht->cp0 +
- e1[3] * ht->cp1 +
- e0[n] * ht->cr0 +
- e1[n] * ht->cr1) >> 10;
- }
- }
- #endif
-
- double *noise3(double x[3])
- { static double f[4];
- short e[4];
- long l;
-
- l = x[0] * (float)HERMITE_TABSIZ;
- xlim[0][0] = l >> 10; xlim[0][1] = xlim[0][0] + 1;
- h_arg[0] = &h_table[l & (HERMITE_TABSIZ - 1)];
-
- l = x[1] * (float)HERMITE_TABSIZ;
- xlim[1][0] = l >> 10; xlim[1][1] = xlim[1][0] + 1;
- h_arg[1] = &h_table[l & (HERMITE_TABSIZ - 1)];
-
- l = x[2] * (float)HERMITE_TABSIZ;
- xlim[2][0] = l >> 10; xlim[2][1] = xlim[2][0] + 1;
- h_arg[2] = &h_table[l & (HERMITE_TABSIZ - 1)];
-
- #if 0
- xlim[0][0] = floor(x[0]); xlim[0][1] = xlim[0][0] + 1;
- xlim[1][0] = floor(x[1]); xlim[1][1] = xlim[1][0] + 1;
- xlim[2][0] = floor(x[2]); xlim[2][1] = xlim[2][0] + 1;
- xarg[0] = x[0] - xlim[0][0];
- xarg[1] = x[1] - xlim[1][0];
- xarg[2] = x[2] - xlim[2][0];
- h_arg[0] = &h_table[ (int)(xarg[0] * HERMITE_TABSIZ) ];
- h_arg[1] = &h_table[ (int)(xarg[1] * HERMITE_TABSIZ) ];
- h_arg[2] = &h_table[ (int)(xarg[2] * HERMITE_TABSIZ) ];
- #endif
- interpolate(e,0,3);
- /* f[0] /= 128.0;
- f[1] /= 128.0;
- f[2] /= 128.0;
- f[3] /= 128.0;
- */
- f[3] = (float)e[3] / (32.0 * 128.0);
- return (f);
- }
-
- double *noise2(double x[2])
- { static double f[4];
- short e[4];
-
- xlim[0][0] = floor(x[0]); xlim[0][1] = xlim[0][0] + 1;
- xlim[1][0] = floor(x[1]); xlim[1][1] = xlim[1][0] + 1;
- /* xlim[2][0] = floor(x[2]); xlim[2][1] = xlim[2][0] + 1; */
- xarg[0] = x[0] - xlim[0][0];
- xarg[1] = x[1] - xlim[1][0];
- /* xarg[2] = x[2] - xlim[2][0]; */
- h_arg[0] = &h_table[ (int)(xarg[0] * HERMITE_TABSIZ) ];
- h_arg[1] = &h_table[ (int)(xarg[1] * HERMITE_TABSIZ) ];
- h_arg[2] = &h_table[ (int)(xarg[2] * HERMITE_TABSIZ) ];
- interpolate(e,0,2);
- f[0] /= 128.0;
- f[1] /= 128.0;
- f[2] /= 128.0;
- f[3] /= 128.0;
- return (f);
- }
-