#ifndef lint static const char RCSid[] = "$Id: noise3.c,v 2.13 2013/10/08 18:59:44 greg Exp $"; #endif /* * noise3.c - noise functions for random textures. * * Credit for the smooth algorithm goes to Ken Perlin, and code * translation/implementation to Rahul Narain. * (ref. Improving Noise, Computer Graphics; Vol. 35 No. 3., 2002) */ #include "copyright.h" #include "ray.h" #include "func.h" static char noise_name[4][8] = {"noise3x", "noise3y", "noise3z", "noise3"}; static char fnoise_name[] = "fnoise3"; #define EPSILON .0005 /* error allowed in fractal */ #define frand3(x,y,z) frand(17*(x)+23*(y)+29*(z)) static double l_noise3(char *nam); static double noise3(double xnew[3], int i); static double noise3partial(double f3, double x[3], int i); static double perlin_noise (double x, double y, double z); static double frand(long s); static double fnoise3(double x[3]); static double l_noise3( /* compute a noise function */ char *nam ) { int i; double x[3]; /* get point */ x[0] = argument(1); x[1] = argument(2); x[2] = argument(3); /* make appropriate call */ if (nam == fnoise_name) return(fnoise3(x)); i = 4; while (i--) if (nam == noise_name[i]) return(noise3(x,i)); eputs(nam); eputs(": called l_noise3!\n"); quit(1); return 1; /* pro forma return */ } void setnoisefuncs(void) /* add noise functions to library */ { int i; funset(fnoise_name, 3, ':', l_noise3); i = 4; while (i--) funset(noise_name[i], 3, ':', l_noise3); } static double frand( /* get random number from seed */ long s ) { s = s<<13 ^ s; return(1.0-((s*(s*s*15731+789221)+1376312589)&0x7fffffff)/1073741824.0); } static double fnoise3( /* compute fractal noise function */ double x[3] ) { long t[3], v[3], beg[3]; double fval[8], fc; int branch; long s; int i, j; /* get starting cube */ s = (long)(1.0/EPSILON); for (i = 0; i < 3; i++) { t[i] = s*x[i]; beg[i] = s*floor(x[i]); } for (j = 0; j < 8; j++) { for (i = 0; i < 3; i++) { v[i] = beg[i]; if (j & 1<>= 1) == 0) return(fc); /* close enough */ branch = 0; for (i = 0; i < 3; i++) { /* do center */ v[i] = beg[i] + s; if (t[i] > v[i]) { branch |= 1<>i & 1)) { f[i] = noise3partial(f[3], x, i); gotV |= 1<