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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: noise3.c,v 2.11 2010/09/03 21:16:50 greg Exp $";
3 #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 */
10
11 #include "copyright.h"
12
13 #include "ray.h"
14 #include "func.h"
15
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 #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
31 #define hermite(p0,p1,r0,r1,t) ( p0*hpoly1(t) + \
32 p1*hpoly2(t) + \
33 r0*hpoly3(t) + \
34 r1*hpoly4(t) )
35
36 static char noise_name[4][8] = {"noise3x", "noise3y", "noise3z", "noise3"};
37 static char fnoise_name[] = "fnoise3";
38 static char hermite_name[] = "hermite";
39
40 static long xlim[3][2];
41 static double xarg[3];
42
43 #define EPSILON .001 /* error allowed in fractal */
44
45 #define frand3(x,y,z) frand(17*(x)+23*(y)+29*(z))
46
47 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
55 static double
56 l_noise3( /* compute a noise function */
57 register char *nam
58 )
59 {
60 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 eputs(nam);
74 eputs(": called l_noise3!\n");
75 quit(1);
76 return 1; /* pro forma return */
77 }
78
79
80 static double
81 l_hermite(char *nm) /* library call for hermite interpolation */
82 {
83 double t;
84
85 t = argument(5);
86 return( hermite(argument(1), argument(2),
87 argument(3), argument(4), t) );
88 }
89
90
91 extern void
92 setnoisefuncs(void) /* add noise functions to library */
93 {
94 register int i;
95
96 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 }
102
103
104 static double *
105 noise3( /* compute the noise function */
106 register double xnew[3]
107 )
108 {
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 static void
127 interpolate(
128 double f[4],
129 register int i,
130 register int n
131 )
132 {
133 double f0[4], f1[4], hp1, hp2;
134
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 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 }
151 }
152
153
154 static double
155 frand( /* get random number from seed */
156 register long s
157 )
158 {
159 s = s<<13 ^ s;
160 return(1.0-((s*(s*s*15731+789221)+1376312589)&0x7fffffff)/1073741824.0);
161 }
162
163
164 static double
165 fnoise3( /* compute fractal noise function */
166 double p[3]
167 )
168 {
169 long t[3], v[3], beg[3];
170 double fval[8], fc;
171 int branch;
172 register long s;
173 register int i, j;
174 /* get starting cube */
175 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 for (j = 0; j < 8; j++) {
181 for (i = 0; i < 3; i++) {
182 v[i] = beg[i];
183 if (j & 1<<i)
184 v[i] += s;
185 }
186 fval[j] = frand3(v[0],v[1],v[2]);
187 }
188 /* compute fractal */
189 for ( ; ; ) {
190 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 branch = 0;
197 for (i = 0; i < 3; i++) { /* do center */
198 v[i] = beg[i] + s;
199 if (t[i] > v[i]) {
200 branch |= 1<<i;
201 }
202 }
203 fc += s*EPSILON*frand3(v[0],v[1],v[2]);
204 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 fc = 0.25*fc + s*EPSILON*frand3(v[0],v[1],v[2]);
215 fval[~(branch^1<<i) & 7] = fc;
216 v[i] = beg[i] + s;
217 }
218 for (i = 0; i < 3; i++) { /* do edges */
219 if ((j = i+1) == 3) j = 0;
220 if (branch & 1<<j)
221 v[j] += s;
222 else
223 v[j] -= s;
224 if (++j == 3) j = 0;
225 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 fc = 0.5*fc + s*EPSILON*frand3(v[0],v[1],v[2]);
232 fval[branch^1<<i] = fc;
233 if ((j = i+1) == 3) j = 0;
234 v[j] = beg[j] + s;
235 if (++j == 3) j = 0;
236 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 }