ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/noise3.c
Revision: 2.12
Committed: Tue Feb 22 16:45:12 2011 UTC (13 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R1
Changes since 2.11: +2 -4 lines
Log Message:
Fixed a few compile errors due to code reorg

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.12 static const char RCSid[] = "$Id: noise3.c,v 2.11 2010/09/03 21:16:50 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * noise3.c - noise functions for random textures.
6     *
7     * Credit for the smooth algorithm goes to Ken Perlin.
8     * (ref. SIGGRAPH Vol 19, No 3, pp 287-96)
9 greg 2.6 */
10    
11 greg 2.7 #include "copyright.h"
12 greg 1.1
13 greg 2.12 #include "ray.h"
14 schorsch 2.9 #include "func.h"
15 greg 1.1
16     #define A 0
17     #define B 1
18     #define C 2
19     #define D 3
20    
21     #define rand3a(x,y,z) frand(67*(x)+59*(y)+71*(z))
22     #define rand3b(x,y,z) frand(73*(x)+79*(y)+83*(z))
23     #define rand3c(x,y,z) frand(89*(x)+97*(y)+101*(z))
24     #define rand3d(x,y,z) frand(103*(x)+107*(y)+109*(z))
25    
26 greg 1.7 #define hpoly1(t) ((2.0*t-3.0)*t*t+1.0)
27     #define hpoly2(t) (-2.0*t+3.0)*t*t
28     #define hpoly3(t) ((t-2.0)*t+1.0)*t
29     #define hpoly4(t) (t-1.0)*t*t
30 greg 1.1
31 greg 1.7 #define hermite(p0,p1,r0,r1,t) ( p0*hpoly1(t) + \
32     p1*hpoly2(t) + \
33     r0*hpoly3(t) + \
34     r1*hpoly4(t) )
35    
36 greg 2.5 static char noise_name[4][8] = {"noise3x", "noise3y", "noise3z", "noise3"};
37 greg 1.5 static char fnoise_name[] = "fnoise3";
38     static char hermite_name[] = "hermite";
39 greg 1.1
40     static long xlim[3][2];
41     static double xarg[3];
42    
43 greg 2.4 #define EPSILON .001 /* error allowed in fractal */
44 greg 1.1
45 greg 1.3 #define frand3(x,y,z) frand(17*(x)+23*(y)+29*(z))
46 greg 1.1
47 schorsch 2.9 static double l_noise3(char *nam);
48     static double l_hermite(char *nm);
49     static double * noise3(double xnew[3]);
50     static void interpolate(double f[4], int i, int n);
51     static double frand(long s);
52     static double fnoise3(double p[3]);
53    
54 greg 1.1
55 greg 1.5 static double
56 schorsch 2.9 l_noise3( /* compute a noise function */
57     register char *nam
58     )
59 greg 1.1 {
60 greg 1.5 register int i;
61     double x[3];
62     /* get point */
63     x[0] = argument(1);
64     x[1] = argument(2);
65     x[2] = argument(3);
66     /* make appropriate call */
67     if (nam == fnoise_name)
68     return(fnoise3(x));
69     i = 4;
70     while (i--)
71     if (nam == noise_name[i])
72     return(noise3(x)[i]);
73 greg 1.6 eputs(nam);
74     eputs(": called l_noise3!\n");
75 greg 1.5 quit(1);
76 schorsch 2.9 return 1; /* pro forma return */
77 greg 1.1 }
78    
79    
80 schorsch 2.9 static double
81 greg 2.8 l_hermite(char *nm) /* library call for hermite interpolation */
82 greg 1.1 {
83 greg 1.5 double t;
84    
85     t = argument(5);
86     return( hermite(argument(1), argument(2),
87     argument(3), argument(4), t) );
88 greg 1.1 }
89    
90    
91 schorsch 2.9 extern void
92     setnoisefuncs(void) /* add noise functions to library */
93 greg 1.1 {
94 greg 1.5 register int i;
95 greg 1.1
96 greg 1.5 funset(hermite_name, 5, ':', l_hermite);
97     funset(fnoise_name, 3, ':', l_noise3);
98     i = 4;
99     while (i--)
100     funset(noise_name[i], 3, ':', l_noise3);
101 greg 1.1 }
102    
103    
104 schorsch 2.9 static double *
105     noise3( /* compute the noise function */
106     register double xnew[3]
107     )
108 greg 1.1 {
109     static double x[3] = {-100000.0, -100000.0, -100000.0};
110     static double f[4];
111    
112     if (x[0]==xnew[0] && x[1]==xnew[1] && x[2]==xnew[2])
113     return(f);
114     x[0] = xnew[0]; x[1] = xnew[1]; x[2] = xnew[2];
115     xlim[0][0] = floor(x[0]); xlim[0][1] = xlim[0][0] + 1;
116     xlim[1][0] = floor(x[1]); xlim[1][1] = xlim[1][0] + 1;
117     xlim[2][0] = floor(x[2]); xlim[2][1] = xlim[2][0] + 1;
118     xarg[0] = x[0] - xlim[0][0];
119     xarg[1] = x[1] - xlim[1][0];
120     xarg[2] = x[2] - xlim[2][0];
121     interpolate(f, 0, 3);
122     return(f);
123     }
124    
125    
126 schorsch 2.9 static void
127     interpolate(
128     double f[4],
129     register int i,
130     register int n
131     )
132 greg 1.1 {
133 greg 1.7 double f0[4], f1[4], hp1, hp2;
134 greg 1.1
135     if (n == 0) {
136     f[A] = rand3a(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
137     f[B] = rand3b(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
138     f[C] = rand3c(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
139     f[D] = rand3d(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
140     } else {
141     n--;
142     interpolate(f0, i, n);
143     interpolate(f1, i | 1<<n, n);
144 greg 1.7 hp1 = hpoly1(xarg[n]); hp2 = hpoly2(xarg[n]);
145     f[A] = f0[A]*hp1 + f1[A]*hp2;
146     f[B] = f0[B]*hp1 + f1[B]*hp2;
147     f[C] = f0[C]*hp1 + f1[C]*hp2;
148     f[D] = f0[D]*hp1 + f1[D]*hp2 +
149     f0[n]*hpoly3(xarg[n]) + f1[n]*hpoly4(xarg[n]);
150 greg 1.1 }
151     }
152    
153    
154 schorsch 2.9 static double
155     frand( /* get random number from seed */
156     register long s
157     )
158 greg 1.1 {
159     s = s<<13 ^ s;
160     return(1.0-((s*(s*s*15731+789221)+1376312589)&0x7fffffff)/1073741824.0);
161     }
162    
163    
164 schorsch 2.9 static double
165     fnoise3( /* compute fractal noise function */
166     double p[3]
167     )
168 greg 1.1 {
169 greg 1.4 long t[3], v[3], beg[3];
170 greg 1.3 double fval[8], fc;
171     int branch;
172 greg 1.4 register long s;
173 greg 1.1 register int i, j;
174     /* get starting cube */
175 greg 1.3 s = (long)(1.0/EPSILON);
176     for (i = 0; i < 3; i++) {
177     t[i] = s*p[i];
178     beg[i] = s*floor(p[i]);
179     }
180 greg 1.1 for (j = 0; j < 8; j++) {
181     for (i = 0; i < 3; i++) {
182     v[i] = beg[i];
183     if (j & 1<<i)
184 greg 1.3 v[i] += s;
185 greg 1.1 }
186     fval[j] = frand3(v[0],v[1],v[2]);
187     }
188     /* compute fractal */
189     for ( ; ; ) {
190 greg 1.4 fc = 0.0;
191     for (j = 0; j < 8; j++)
192     fc += fval[j];
193     fc *= 0.125;
194     if ((s >>= 1) == 0)
195     return(fc); /* close enough */
196 greg 1.1 branch = 0;
197     for (i = 0; i < 3; i++) { /* do center */
198     v[i] = beg[i] + s;
199 greg 1.3 if (t[i] > v[i]) {
200 greg 1.1 branch |= 1<<i;
201 greg 1.3 }
202 greg 1.1 }
203 greg 1.3 fc += s*EPSILON*frand3(v[0],v[1],v[2]);
204 greg 1.1 fval[~branch & 7] = fc;
205     for (i = 0; i < 3; i++) { /* do faces */
206     if (branch & 1<<i)
207     v[i] += s;
208     else
209     v[i] -= s;
210     fc = 0.0;
211     for (j = 0; j < 8; j++)
212     if (~(j^branch) & 1<<i)
213     fc += fval[j];
214 greg 1.3 fc = 0.25*fc + s*EPSILON*frand3(v[0],v[1],v[2]);
215 greg 1.1 fval[~(branch^1<<i) & 7] = fc;
216     v[i] = beg[i] + s;
217     }
218     for (i = 0; i < 3; i++) { /* do edges */
219 greg 2.10 if ((j = i+1) == 3) j = 0;
220 greg 1.1 if (branch & 1<<j)
221     v[j] += s;
222     else
223     v[j] -= s;
224 greg 2.10 if (++j == 3) j = 0;
225 greg 1.1 if (branch & 1<<j)
226     v[j] += s;
227     else
228     v[j] -= s;
229     fc = fval[branch & ~(1<<i)];
230     fc += fval[branch | 1<<i];
231 greg 1.3 fc = 0.5*fc + s*EPSILON*frand3(v[0],v[1],v[2]);
232 greg 1.1 fval[branch^1<<i] = fc;
233 greg 2.10 if ((j = i+1) == 3) j = 0;
234 greg 1.1 v[j] = beg[j] + s;
235 greg 2.10 if (++j == 3) j = 0;
236 greg 1.1 v[j] = beg[j] + s;
237     }
238     for (i = 0; i < 3; i++) /* new cube */
239     if (branch & 1<<i)
240     beg[i] += s;
241     }
242     }