ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum2.c
Revision: 1.3
Committed: Wed Jul 24 13:32:05 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +138 -2 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     * Routines to do the actual calcultion and output for mkillum
9     */
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 greg 1.1 printobj(mod, obj) /* print out an object */
21     char *mod;
22     register OBJREC *obj;
23     {
24     register int i;
25    
26     printf("\n%s %s %s", mod, ofun[obj->otype].funame, obj->oname);
27     printf("\n%d", obj->oargs.nsargs);
28     for (i = 0; i < obj->oargs.nsargs; i++)
29     printf(" %s", obj->oargs.sarg[i]);
30     #ifdef IARGS
31     printf("\n%d", obj->oargs.niargs);
32     for (i = 0; i < obj->oargs.niargs; i++)
33     printf(" %d", obj->oargs.iarg[i]);
34     #else
35     printf("\n0");
36     #endif
37     printf("\n%d", obj->oargs.nfargs);
38     for (i = 0; i < obj->oargs.nfargs; i++) {
39     if (i%3 == 0)
40     putchar('\n');
41     printf(" %18.12g", obj->oargs.farg[i]);
42     }
43     putchar('\n');
44     }
45    
46    
47 greg 1.2 o_default(ob, il, rt, nm) /* default illum action */
48 greg 1.1 OBJREC *ob;
49     struct illum_args *il;
50     struct rtproc *rt;
51 greg 1.2 char *nm;
52 greg 1.1 {
53 greg 1.2 sprintf(errmsg, "(%s): cannot make illum for %s \"%s\"",
54     nm, ofun[ob->otype].funame, ob->oname);
55     error(WARNING, errmsg);
56     if (!(il->flags & IL_LIGHT))
57     printobj(il->altname, ob);
58     }
59    
60    
61     o_face(ob, il, rt, nm) /* make an illum face */
62     OBJREC *ob;
63     struct illum_args *il;
64     struct rtproc *rt;
65     char *nm;
66     {
67 greg 1.3 #define MAXMISS (5*n*il->nsamps)
68     int dim[4];
69     int n, nalt, nazi;
70     float *distarr;
71     double r1, r2;
72     FVECT dn, pos, dir;
73     FVECT u, v;
74     double ur[2], vr[2];
75     int nmisses;
76     register FACE *fa;
77     register int i, j;
78     /* get/check arguments */
79     fa = getface(ob);
80     if (fa->area == 0.0) {
81     freeface(ob);
82     o_default(ob, il, rt, nm);
83     return;
84     }
85     /* set up sampling */
86     n = PI * il->sampdens;
87     nalt = sqrt(n/PI) + .5;
88     nazi = PI*nalt + .5;
89     n = nalt*nazi;
90     distarr = (float *)calloc(n, 3*sizeof(float));
91     if (distarr == NULL)
92     error(SYSTEM, "out of memory in o_face");
93     mkaxes(u, v, fa->norm);
94     ur[0] = vr[0] = FHUGE;
95     ur[1] = vr[1] = -FHUGE;
96     for (i = 0; i < fa->nv; i++) {
97     r1 = DOT(VERTEX(fa,i),u);
98     if (r1 < ur[0]) ur[0] = r1;
99     if (r1 > ur[1]) ur[1] = r1;
100     r2 = DOT(VERTEX(fa,i),v);
101     if (r2 < vr[0]) vr[0] = r2;
102     if (r2 > vr[1]) vr[1] = r2;
103     }
104     dim[0] = random();
105     /* sample polygon */
106     nmisses = 0;
107     for (dim[1] = 0; dim[1] < nalt; dim[1]++)
108     for (dim[2] = 0; dim[2] < nazi; dim[2]++)
109     for (i = 0; i < il->nsamps; i++) {
110     /* random direction */
111     dim[3] = 1;
112     r1 = (dim[1]+urand(urind(ilhash(dim,4),i)))/nalt;
113     dim[3] = 2;
114     r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nalt;
115     flatdir(dn, r1, r2);
116     for (j = 0; j < 3; j++)
117     dir[j] = dn[0]*u[j] + dn[1]*v[j] - dn[2]*fa->norm[j];
118     /* random location */
119     do {
120     dim[3] = 3;
121     r1 = ur[0] +
122     (ur[1]-ur[0])*urand(urind(ilhash(dim,4),i));
123     dim[3] = 4;
124     r2 = vr[0] +
125     (vr[1]-vr[0])*urand(urind(ilhash(dim,4),i));
126     for (j = 0; j < 3; j++)
127     org[j] = r1*u[j] + r2*v[j]
128     + fa->offset*fa->norm[j];
129     } while (!inface(org, fa) && nmisses++ < MAXMISS);
130     if (nmisses > MAXMISS) {
131     objerror(ob, WARNING, "bad aspect");
132     rt->nrays = 0;
133     freeface(ob);
134     free((char *)distarr);
135     o_default(ob, il, rt, nm);
136     return;
137     }
138     for (j = 0; j < 3; j++)
139     org[j] += .001*fa->norm[j];
140     /* send sample */
141     raysamp(distarr+dim[1]*nazi+dim[2], org, dir, rt);
142     }
143     rayflush(rt);
144     /* write out the distribution */
145     flatdist(distarr, nalt, nazi, il, ob);
146     /* clean up */
147     freeface(ob);
148     free((char *)distarr);
149     #undef MAXMISS
150 greg 1.2 }
151    
152    
153     o_sphere(ob, il, rt, nm) /* make an illum sphere */
154 greg 1.3 register OBJREC *ob;
155 greg 1.2 struct illum_args *il;
156     struct rtproc *rt;
157     char *nm;
158     {
159     int dim[4];
160     int n, nalt, nazi;
161     float *distarr;
162     double r1, r2;
163     FVECT pos, dir;
164     FVECT u, v;
165     register int i, j;
166     /* check arguments */
167     if (ob->oargs.nfargs != 4)
168     objerror(ob, USER, "bad # of arguments");
169     /* set up sampling */
170     n = 4.*PI * il->sampdens;
171     nalt = sqrt(n/PI) + .5;
172     nazi = PI*nalt + .5;
173     n = nalt*nazi;
174     distarr = (float *)calloc(n, 3*sizeof(float));
175     if (distarr == NULL)
176     error(SYSTEM, "out of memory in o_sphere");
177     dim[0] = random();
178     /* sample sphere */
179     for (dim[1] = 0; dim[1] < nalt; dim[1]++)
180     for (dim[2] = 0; dim[2] < nazi; dim[2]++)
181     for (i = 0; i < il->nsamps; i++) {
182     /* random direction */
183     dim[3] = 1;
184     r1 = (dim[1]+urand(urind(ilhash(dim,4),i)))/nalt;
185     dim[3] = 2;
186     r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nalt;
187     rounddir(dir, r1, r2);
188     /* random location */
189     mkaxes(u, v, dir); /* yuck! */
190     dim[3] = 3;
191     r1 = sqrt(urand(urind(ilhash(dim,4),i)));
192     dim[3] = 4;
193     r2 = 2.*PI*urand(urind(ilhash(dim,4),i));
194     for (j = 0; j < 3; j++)
195     org[j] = obj->oargs.farg[j] + obj->oargs.farg[3] *
196     ( r1*cos(r2)*u[j] + r1*sin(r2)*v[j]
197     - sqrt(1.01-r1*r1)*dir[j] );
198    
199     /* send sample */
200     raysamp(distarr+dim[1]*nazi+dim[2], org, dir, rt);
201     }
202     rayflush(rt);
203 greg 1.3 /* write out the distribution */
204 greg 1.2 rounddist(distarr, nalt, nazi, il, ob);
205     /* clean up */
206     free((char *)distarr);
207     }
208    
209    
210     o_ring(ob, il, rt, nm) /* make an illum ring */
211     OBJREC *ob;
212     struct illum_args *il;
213     struct rtproc *rt;
214     char *nm;
215     {
216 greg 1.3 int dim[4];
217     int n, nalt, nazi;
218     float *distarr;
219     double r1, r2;
220     FVECT dn, pos, dir;
221     FVECT u, v;
222     register CONE *co;
223     register int i, j;
224     /* get/check arguments */
225     co = getcone(ob, 0);
226     /* set up sampling */
227     n = PI * il->sampdens;
228     nalt = sqrt(n/PI) + .5;
229     nazi = PI*nalt + .5;
230     n = nalt*nazi;
231     distarr = (float *)calloc(n, 3*sizeof(float));
232     if (distarr == NULL)
233     error(SYSTEM, "out of memory in o_ring");
234     mkaxes(u, v, co->ad);
235     dim[0] = random();
236     /* sample disk */
237     for (dim[1] = 0; dim[1] < nalt; dim[1]++)
238     for (dim[2] = 0; dim[2] < nazi; dim[2]++)
239     for (i = 0; i < il->nsamps; i++) {
240     /* random direction */
241     dim[3] = 1;
242     r1 = (dim[1]+urand(urind(ilhash(dim,4),i)))/nalt;
243     dim[3] = 2;
244     r2 = (dim[2]+urand(urind(ilhash(dim,4),i)))/nalt;
245     flatdir(dn, r1, r2);
246     for (j = 0; j < 3; j++)
247     dir[j] = dn[0]*u[j] + dn[1]*v[j] - dn[2]*co->ad[j];
248     /* random location */
249     dim[3] = 3;
250     r1 = sqrt(CO_R0(co)*CO_R0(co) +
251     urand(urind(ilhash(dim,4),i))*
252     (CO_R1(co)*CO_R1(co) - CO_R0(co)*CO_R0(co)));
253     dim[3] = 4;
254     r2 = 2.*PI*urand(urind(ilhash(dim,4),i));
255     for (j = 0; j < 3; j++)
256     org[j] = CO_P0(co)[j] +
257     r1*cos(r2)*u[j] + r1*sin(r2)*v[j]
258     + .001*co->ad[j];
259    
260     /* send sample */
261     raysamp(distarr+dim[1]*nazi+dim[2], org, dir, rt);
262     }
263     rayflush(rt);
264     /* write out the distribution */
265     flatdist(distarr, nalt, nazi, il, ob);
266     /* clean up */
267     freecone(ob);
268     free((char *)distarr);
269 greg 1.2 }
270    
271    
272     raysamp(res, org, dir, rt) /* compute a ray sample */
273     float res[3];
274     FVECT org, dir;
275     register struct rtproc *rt;
276     {
277     register float *fp;
278    
279     if (rt->nrays == rt->bsiz)
280     rayflush(rt);
281     rt->dest[rt->nrays] = res;
282     fp = rt->buf + 6*rt->nrays++;
283     *fp++ = org[0]; *fp++ = org[1]; *fp++ = org[2];
284     *fp++ = dir[0]; *fp++ = dir[1]; *fp = dir[2];
285     }
286    
287    
288     rayflush(rt) /* flush buffered rays */
289     register struct rtproc *rt;
290     {
291     register int i;
292    
293     if (rt->nrays <= 0)
294     return;
295     i = 6*rt->nrays + 3;
296     rt->buf[i++] = 0.; rt->buf[i++] = 0.; rt->buf[i] = 0.;
297     if ( process(rt->pd, (char *)rt->buf, (char *)rt->buf,
298     3*sizeof(float)*rt->nrays,
299     6*sizeof(float)*(rt->nrays+1)) <
300     3*sizeof(float)*rt->nrays )
301     error(SYSTEM, "error reading from rtrace process");
302     i = rt->nrays;
303     while (i--) {
304     rt->dest[i][0] += rt->buf[3*i];
305     rt->dest[i][1] += rt->buf[3*i+1];
306     rt->dest[i][2] += rt->buf[3*i+2];
307     }
308     rt->nrays = 0;
309 greg 1.1 }