ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum2.c
Revision: 1.4
Committed: Wed Jul 24 16:48:26 1991 UTC (32 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +63 -43 lines
Log Message:
first version of mkillum

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     r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nalt;
88     flatdir(dn, r1, r2);
89     for (j = 0; j < 3; j++)
90     dir[j] = dn[0]*u[j] + dn[1]*v[j] - dn[2]*fa->norm[j];
91     /* 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     raysamp(distarr+dim[1]*nazi+dim[2], org, dir, rt);
115     }
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     double r1, r2;
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     for (dim[2] = 0; dim[2] < nazi; dim[2]++)
155     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     r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nalt;
161     rounddir(dir, r1, r2);
162     /* random location */
163     mkaxes(u, v, dir); /* yuck! */
164     dim[3] = 3;
165     r1 = sqrt(urand(urind(ilhash(dim,4),i)));
166     dim[3] = 4;
167     r2 = 2.*PI*urand(urind(ilhash(dim,4),i));
168     for (j = 0; j < 3; j++)
169 greg 1.4 org[j] = ob->oargs.farg[j] + ob->oargs.farg[3] *
170 greg 1.2 ( r1*cos(r2)*u[j] + r1*sin(r2)*v[j]
171     - sqrt(1.01-r1*r1)*dir[j] );
172    
173     /* send sample */
174     raysamp(distarr+dim[1]*nazi+dim[2], org, dir, rt);
175     }
176     rayflush(rt);
177 greg 1.4 /* write out the sphere w/ distribution */
178     roundout(il, distarr, nalt, nazi);
179     illumout(il, ob);
180 greg 1.2 /* clean up */
181     free((char *)distarr);
182     }
183    
184    
185     o_ring(ob, il, rt, nm) /* make an illum ring */
186     OBJREC *ob;
187     struct illum_args *il;
188     struct rtproc *rt;
189     char *nm;
190     {
191 greg 1.3 int dim[4];
192     int n, nalt, nazi;
193     float *distarr;
194     double r1, r2;
195 greg 1.4 FVECT dn, org, dir;
196 greg 1.3 FVECT u, v;
197     register CONE *co;
198     register int i, j;
199     /* get/check arguments */
200     co = getcone(ob, 0);
201     /* set up sampling */
202     n = PI * il->sampdens;
203     nalt = sqrt(n/PI) + .5;
204     nazi = PI*nalt + .5;
205     n = nalt*nazi;
206     distarr = (float *)calloc(n, 3*sizeof(float));
207     if (distarr == NULL)
208     error(SYSTEM, "out of memory in o_ring");
209     mkaxes(u, v, co->ad);
210     dim[0] = random();
211     /* sample disk */
212     for (dim[1] = 0; dim[1] < nalt; dim[1]++)
213     for (dim[2] = 0; dim[2] < nazi; dim[2]++)
214     for (i = 0; i < il->nsamps; i++) {
215     /* random direction */
216     dim[3] = 1;
217     r1 = (dim[1]+urand(urind(ilhash(dim,4),i)))/nalt;
218     dim[3] = 2;
219     r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nalt;
220     flatdir(dn, r1, r2);
221     for (j = 0; j < 3; j++)
222     dir[j] = dn[0]*u[j] + dn[1]*v[j] - dn[2]*co->ad[j];
223     /* random location */
224     dim[3] = 3;
225     r1 = sqrt(CO_R0(co)*CO_R0(co) +
226     urand(urind(ilhash(dim,4),i))*
227     (CO_R1(co)*CO_R1(co) - CO_R0(co)*CO_R0(co)));
228     dim[3] = 4;
229     r2 = 2.*PI*urand(urind(ilhash(dim,4),i));
230     for (j = 0; j < 3; j++)
231     org[j] = CO_P0(co)[j] +
232     r1*cos(r2)*u[j] + r1*sin(r2)*v[j]
233     + .001*co->ad[j];
234    
235     /* send sample */
236     raysamp(distarr+dim[1]*nazi+dim[2], org, dir, rt);
237     }
238     rayflush(rt);
239 greg 1.4 /* write out the ring w/ distribution */
240     flatout(il, distarr, nalt, nazi, u, v, co->ad);
241     illumout(il, ob);
242 greg 1.3 /* clean up */
243     freecone(ob);
244     free((char *)distarr);
245 greg 1.2 }
246    
247    
248     raysamp(res, org, dir, rt) /* compute a ray sample */
249     float res[3];
250     FVECT org, dir;
251     register struct rtproc *rt;
252     {
253     register float *fp;
254    
255     if (rt->nrays == rt->bsiz)
256     rayflush(rt);
257     rt->dest[rt->nrays] = res;
258     fp = rt->buf + 6*rt->nrays++;
259     *fp++ = org[0]; *fp++ = org[1]; *fp++ = org[2];
260     *fp++ = dir[0]; *fp++ = dir[1]; *fp = dir[2];
261     }
262    
263    
264     rayflush(rt) /* flush buffered rays */
265     register struct rtproc *rt;
266     {
267     register int i;
268    
269     if (rt->nrays <= 0)
270     return;
271     i = 6*rt->nrays + 3;
272     rt->buf[i++] = 0.; rt->buf[i++] = 0.; rt->buf[i] = 0.;
273     if ( process(rt->pd, (char *)rt->buf, (char *)rt->buf,
274     3*sizeof(float)*rt->nrays,
275     6*sizeof(float)*(rt->nrays+1)) <
276     3*sizeof(float)*rt->nrays )
277     error(SYSTEM, "error reading from rtrace process");
278     i = rt->nrays;
279     while (i--) {
280     rt->dest[i][0] += rt->buf[3*i];
281     rt->dest[i][1] += rt->buf[3*i+1];
282     rt->dest[i][2] += rt->buf[3*i+2];
283     }
284     rt->nrays = 0;
285 greg 1.4 }
286    
287    
288     mkaxes(u, v, n) /* compute u and v to go with n */
289     FVECT u, v, n;
290     {
291     register int i;
292    
293     v[0] = v[1] = v[2] = 0.0;
294     for (i = 0; i < 3; i++)
295     if (n[i] < 0.6 && n[i] > -0.6)
296     break;
297     v[i] = 1.0;
298     fcross(u, v, n);
299     normalize(u);
300     fcross(v, n, u);
301     }
302    
303    
304     rounddir(dv, alt, azi) /* compute uniform spherical direction */
305     register FVECT dv;
306     double alt, azi;
307     {
308     double d1, d2;
309    
310     dv[2] = 1. - 2.*alt;
311     d1 = sqrt(1. - dv[2]*dv[2]);
312     d2 = 2.*PI * azi;
313     dv[0] = d1*cos(d2);
314     dv[1] = d1*sin(d2);
315     }
316    
317    
318     flatdir(dv, alt, azi) /* compute uniform hemispherical direction */
319     register FVECT dv;
320     double alt, azi;
321     {
322     double d1, d2;
323    
324     d1 = sqrt(alt);
325     d2 = 2.*PI * azi;
326     dv[0] = d1*cos(d2);
327     dv[1] = d1*sin(d2);
328     dv[2] = sqrt(1. - d1*d1);
329 greg 1.1 }