ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum2.c
Revision: 1.8
Committed: Thu Jul 25 14:43:15 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.7: +2 -8 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1991 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8 greg 1.4 * Routines to do the actual calculation for mkillum
9 greg 1.1 */
10    
11     #include "mkillum.h"
12    
13     #include "face.h"
14    
15     #include "cone.h"
16    
17 greg 1.2 #include "random.h"
18 greg 1.1
19 greg 1.2
20     o_default(ob, il, rt, nm) /* default illum action */
21 greg 1.1 OBJREC *ob;
22     struct illum_args *il;
23     struct rtproc *rt;
24 greg 1.2 char *nm;
25 greg 1.1 {
26 greg 1.2 sprintf(errmsg, "(%s): cannot make illum for %s \"%s\"",
27     nm, ofun[ob->otype].funame, ob->oname);
28     error(WARNING, errmsg);
29     if (!(il->flags & IL_LIGHT))
30 greg 1.4 printobj(il->altmat, ob);
31 greg 1.2 }
32    
33    
34     o_face(ob, il, rt, nm) /* make an illum face */
35     OBJREC *ob;
36     struct illum_args *il;
37     struct rtproc *rt;
38     char *nm;
39     {
40 greg 1.3 #define MAXMISS (5*n*il->nsamps)
41     int dim[4];
42     int n, nalt, nazi;
43     float *distarr;
44     double r1, r2;
45 greg 1.4 FVECT dn, org, dir;
46 greg 1.3 FVECT u, v;
47     double ur[2], vr[2];
48     int nmisses;
49     register FACE *fa;
50     register int i, j;
51     /* get/check arguments */
52     fa = getface(ob);
53     if (fa->area == 0.0) {
54     freeface(ob);
55     o_default(ob, il, rt, nm);
56     return;
57     }
58     /* set up sampling */
59     n = PI * il->sampdens;
60     nalt = sqrt(n/PI) + .5;
61     nazi = PI*nalt + .5;
62     n = nalt*nazi;
63     distarr = (float *)calloc(n, 3*sizeof(float));
64     if (distarr == NULL)
65     error(SYSTEM, "out of memory in o_face");
66     mkaxes(u, v, fa->norm);
67     ur[0] = vr[0] = FHUGE;
68     ur[1] = vr[1] = -FHUGE;
69     for (i = 0; i < fa->nv; i++) {
70     r1 = DOT(VERTEX(fa,i),u);
71     if (r1 < ur[0]) ur[0] = r1;
72     if (r1 > ur[1]) ur[1] = r1;
73     r2 = DOT(VERTEX(fa,i),v);
74     if (r2 < vr[0]) vr[0] = r2;
75     if (r2 > vr[1]) vr[1] = r2;
76     }
77     dim[0] = random();
78     /* sample polygon */
79     nmisses = 0;
80     for (dim[1] = 0; dim[1] < nalt; dim[1]++)
81     for (dim[2] = 0; dim[2] < nazi; dim[2]++)
82     for (i = 0; i < il->nsamps; i++) {
83     /* random direction */
84     dim[3] = 1;
85     r1 = (dim[1]+urand(urind(ilhash(dim,4),i)))/nalt;
86     dim[3] = 2;
87 greg 1.5 r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nazi;
88 greg 1.3 flatdir(dn, r1, r2);
89     for (j = 0; j < 3; j++)
90 greg 1.5 dir[j] = -dn[0]*u[j] - dn[1]*v[j] - dn[2]*fa->norm[j];
91 greg 1.3 /* random location */
92     do {
93     dim[3] = 3;
94 greg 1.4 r1 = ur[0] + (ur[1]-ur[0]) *
95     urand(urind(ilhash(dim,4),i+nmisses));
96 greg 1.3 dim[3] = 4;
97 greg 1.4 r2 = vr[0] + (vr[1]-vr[0]) *
98     urand(urind(ilhash(dim,4),i+nmisses));
99 greg 1.3 for (j = 0; j < 3; j++)
100     org[j] = r1*u[j] + r2*v[j]
101     + fa->offset*fa->norm[j];
102     } while (!inface(org, fa) && nmisses++ < MAXMISS);
103     if (nmisses > MAXMISS) {
104     objerror(ob, WARNING, "bad aspect");
105     rt->nrays = 0;
106     freeface(ob);
107     free((char *)distarr);
108     o_default(ob, il, rt, nm);
109     return;
110     }
111     for (j = 0; j < 3; j++)
112     org[j] += .001*fa->norm[j];
113     /* send sample */
114 greg 1.7 raysamp(distarr+3*(dim[1]*nazi+dim[2]), org, dir, rt);
115 greg 1.3 }
116     rayflush(rt);
117 greg 1.4 /* write out the face w/ distribution */
118     flatout(il, distarr, nalt, nazi, u, v, fa->norm);
119     illumout(il, ob);
120 greg 1.3 /* clean up */
121     freeface(ob);
122     free((char *)distarr);
123     #undef MAXMISS
124 greg 1.2 }
125    
126    
127     o_sphere(ob, il, rt, nm) /* make an illum sphere */
128 greg 1.3 register OBJREC *ob;
129 greg 1.2 struct illum_args *il;
130     struct rtproc *rt;
131     char *nm;
132     {
133     int dim[4];
134     int n, nalt, nazi;
135     float *distarr;
136 greg 1.5 double r1, r2, r3;
137 greg 1.4 FVECT org, dir;
138 greg 1.2 FVECT u, v;
139     register int i, j;
140     /* check arguments */
141     if (ob->oargs.nfargs != 4)
142     objerror(ob, USER, "bad # of arguments");
143     /* set up sampling */
144     n = 4.*PI * il->sampdens;
145     nalt = sqrt(n/PI) + .5;
146     nazi = PI*nalt + .5;
147     n = nalt*nazi;
148     distarr = (float *)calloc(n, 3*sizeof(float));
149     if (distarr == NULL)
150     error(SYSTEM, "out of memory in o_sphere");
151     dim[0] = random();
152     /* sample sphere */
153     for (dim[1] = 0; dim[1] < nalt; dim[1]++)
154 greg 1.8 for (dim[2] = 0; dim[2] < nazi; dim[2]++)
155 greg 1.2 for (i = 0; i < il->nsamps; i++) {
156     /* random direction */
157     dim[3] = 1;
158     r1 = (dim[1]+urand(urind(ilhash(dim,4),i)))/nalt;
159     dim[3] = 2;
160 greg 1.5 r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nazi;
161 greg 1.2 rounddir(dir, r1, r2);
162     /* random location */
163 greg 1.8 mkaxes(u, v, dir); /* yuck! */
164 greg 1.2 dim[3] = 3;
165 greg 1.5 r3 = sqrt(urand(urind(ilhash(dim,4),i)));
166 greg 1.2 dim[3] = 4;
167     r2 = 2.*PI*urand(urind(ilhash(dim,4),i));
168 greg 1.5 r1 = r3*ob->oargs.farg[3]*cos(r2);
169     r2 = r3*ob->oargs.farg[3]*sin(r2);
170     r3 = ob->oargs.farg[3]*sqrt(1.01-r3*r3);
171     for (j = 0; j < 3; j++) {
172     org[j] = ob->oargs.farg[j] + r1*u[j] + r2*v[j] +
173     r3*dir[j];
174     dir[j] = -dir[j];
175     }
176 greg 1.2 /* send sample */
177 greg 1.7 raysamp(distarr+3*(dim[1]*nazi+dim[2]), org, dir, rt);
178 greg 1.2 }
179     rayflush(rt);
180 greg 1.4 /* write out the sphere w/ distribution */
181     roundout(il, distarr, nalt, nazi);
182     illumout(il, ob);
183 greg 1.2 /* clean up */
184     free((char *)distarr);
185     }
186    
187    
188     o_ring(ob, il, rt, nm) /* make an illum ring */
189     OBJREC *ob;
190     struct illum_args *il;
191     struct rtproc *rt;
192     char *nm;
193     {
194 greg 1.3 int dim[4];
195     int n, nalt, nazi;
196     float *distarr;
197 greg 1.5 double r1, r2, r3;
198 greg 1.4 FVECT dn, org, dir;
199 greg 1.3 FVECT u, v;
200     register CONE *co;
201     register int i, j;
202     /* get/check arguments */
203     co = getcone(ob, 0);
204     /* set up sampling */
205     n = PI * il->sampdens;
206     nalt = sqrt(n/PI) + .5;
207     nazi = PI*nalt + .5;
208     n = nalt*nazi;
209     distarr = (float *)calloc(n, 3*sizeof(float));
210     if (distarr == NULL)
211     error(SYSTEM, "out of memory in o_ring");
212     mkaxes(u, v, co->ad);
213     dim[0] = random();
214     /* sample disk */
215     for (dim[1] = 0; dim[1] < nalt; dim[1]++)
216     for (dim[2] = 0; dim[2] < nazi; dim[2]++)
217     for (i = 0; i < il->nsamps; i++) {
218     /* random direction */
219     dim[3] = 1;
220     r1 = (dim[1]+urand(urind(ilhash(dim,4),i)))/nalt;
221     dim[3] = 2;
222     r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nalt;
223     flatdir(dn, r1, r2);
224     for (j = 0; j < 3; j++)
225 greg 1.5 dir[j] = -dn[0]*u[j] - dn[1]*v[j] - dn[2]*co->ad[j];
226 greg 1.3 /* random location */
227     dim[3] = 3;
228 greg 1.5 r3 = sqrt(CO_R0(co)*CO_R0(co) +
229 greg 1.3 urand(urind(ilhash(dim,4),i))*
230     (CO_R1(co)*CO_R1(co) - CO_R0(co)*CO_R0(co)));
231     dim[3] = 4;
232     r2 = 2.*PI*urand(urind(ilhash(dim,4),i));
233 greg 1.5 r1 = r3*cos(r2);
234     r2 = r3*sin(r2);
235 greg 1.3 for (j = 0; j < 3; j++)
236 greg 1.5 org[j] = CO_P0(co)[j] + r1*u[j] + r1*v[j] +
237     .001*co->ad[j];
238 greg 1.3
239     /* send sample */
240 greg 1.7 raysamp(distarr+3*(dim[1]*nazi+dim[2]), org, dir, rt);
241 greg 1.3 }
242     rayflush(rt);
243 greg 1.4 /* write out the ring w/ distribution */
244     flatout(il, distarr, nalt, nazi, u, v, co->ad);
245     illumout(il, ob);
246 greg 1.3 /* clean up */
247     freecone(ob);
248     free((char *)distarr);
249 greg 1.2 }
250    
251    
252     raysamp(res, org, dir, rt) /* compute a ray sample */
253     float res[3];
254     FVECT org, dir;
255     register struct rtproc *rt;
256     {
257     register float *fp;
258    
259     if (rt->nrays == rt->bsiz)
260     rayflush(rt);
261     rt->dest[rt->nrays] = res;
262     fp = rt->buf + 6*rt->nrays++;
263     *fp++ = org[0]; *fp++ = org[1]; *fp++ = org[2];
264     *fp++ = dir[0]; *fp++ = dir[1]; *fp = dir[2];
265     }
266    
267    
268     rayflush(rt) /* flush buffered rays */
269     register struct rtproc *rt;
270     {
271     register int i;
272    
273     if (rt->nrays <= 0)
274     return;
275     i = 6*rt->nrays + 3;
276     rt->buf[i++] = 0.; rt->buf[i++] = 0.; rt->buf[i] = 0.;
277     if ( process(rt->pd, (char *)rt->buf, (char *)rt->buf,
278     3*sizeof(float)*rt->nrays,
279     6*sizeof(float)*(rt->nrays+1)) <
280     3*sizeof(float)*rt->nrays )
281     error(SYSTEM, "error reading from rtrace process");
282     i = rt->nrays;
283     while (i--) {
284     rt->dest[i][0] += rt->buf[3*i];
285     rt->dest[i][1] += rt->buf[3*i+1];
286     rt->dest[i][2] += rt->buf[3*i+2];
287     }
288     rt->nrays = 0;
289 greg 1.4 }
290    
291    
292     mkaxes(u, v, n) /* compute u and v to go with n */
293     FVECT u, v, n;
294     {
295     register int i;
296    
297     v[0] = v[1] = v[2] = 0.0;
298     for (i = 0; i < 3; i++)
299     if (n[i] < 0.6 && n[i] > -0.6)
300     break;
301     v[i] = 1.0;
302     fcross(u, v, n);
303     normalize(u);
304     fcross(v, n, u);
305     }
306    
307    
308     rounddir(dv, alt, azi) /* compute uniform spherical direction */
309     register FVECT dv;
310     double alt, azi;
311     {
312     double d1, d2;
313    
314     dv[2] = 1. - 2.*alt;
315     d1 = sqrt(1. - dv[2]*dv[2]);
316     d2 = 2.*PI * azi;
317     dv[0] = d1*cos(d2);
318     dv[1] = d1*sin(d2);
319     }
320    
321    
322     flatdir(dv, alt, azi) /* compute uniform hemispherical direction */
323     register FVECT dv;
324     double alt, azi;
325     {
326     double d1, d2;
327    
328     d1 = sqrt(alt);
329     d2 = 2.*PI * azi;
330     dv[0] = d1*cos(d2);
331     dv[1] = d1*sin(d2);
332 greg 1.6 dv[2] = sqrt(1. - alt);
333 greg 1.1 }