ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
Revision: 1.10
Committed: Thu Mar 21 17:11:50 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.9: +9 -8 lines
Log Message:
changed sample count to real number it should have been

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     * Gather samples and compute glare sources.
9     */
10    
11     #include "glare.h"
12    
13     #define vcont(vd,vu) ((vu)-(vd)<=SEPS)
14     #define hcont(s1,s2) ((s1)->r-(s2)->l>=-SEPS&&(s2)->r-(s1)->l>=-SEPS)
15    
16     struct source *curlist = NULL; /* current source list */
17     struct source *donelist = NULL; /* finished sources */
18    
19    
20     struct srcspan *
21     newspan(l, r, v, sb) /* allocate a new source span */
22     int l, r, v;
23     float *sb;
24     {
25     register struct srcspan *ss;
26     register int i;
27    
28     ss = (struct srcspan *)malloc(sizeof(struct srcspan));
29     if (ss == NULL)
30     memerr("source spans");
31     ss->l = l;
32     ss->r = r;
33     ss->v = v;
34     ss->brsum = 0.0;
35     for (i = l; i < r; i++)
36     ss->brsum += sb[i+hsize];
37     return(ss);
38     }
39    
40    
41     analyze() /* analyze our scene */
42     {
43     int h, v;
44     int left;
45     float *spanbr;
46    
47     spanbr = (float *)malloc((2*hsize+1)*sizeof(float));
48     if (spanbr == NULL)
49     memerr("view span brightness buffer");
50     for (v = vsize; v >= -vsize; v--) {
51 greg 1.5 close_sources(v);
52 greg 1.8 #ifndef DEBUG
53     if (verbose)
54     fprintf(stderr, "%s: analyzing... %3ld%%\r",
55     progname, 100L*(vsize-v)/(2*vsize));
56     #endif
57 greg 1.1 getviewspan(v, spanbr);
58     left = hsize + 1;
59 greg 1.2 for (h = -hsize; h <= hsize; h++) {
60 greg 1.1 if (spanbr[h+hsize] < 0.0) { /* off view */
61     if (left < h) {
62 greg 1.2 addsrcspan(newspan(left,h,v,spanbr));
63 greg 1.1 left = hsize + 1;
64     }
65     continue;
66     }
67     if (spanbr[h+hsize] > threshold) { /* in source */
68 greg 1.2 if (left > h)
69 greg 1.1 left = h;
70     } else { /* out of source */
71     if (left < h) {
72 greg 1.2 addsrcspan(newspan(left,h,v,spanbr));
73 greg 1.1 left = hsize + 1;
74     }
75     addindirect(h, spanbr[h+hsize]);
76     }
77 greg 1.2 }
78 greg 1.1 if (left < h)
79 greg 1.2 addsrcspan(newspan(left,h,v,spanbr));
80 greg 1.1 }
81 greg 1.7 free((char *)spanbr);
82 greg 1.1 close_allsrcs();
83 greg 1.7 absorb_specks();
84 greg 1.1 }
85    
86    
87     addindirect(h, br) /* add brightness to indirect illuminances */
88     int h;
89     double br;
90     {
91     double tanb, d;
92     register int i;
93    
94     if (h <= -hlim) { /* left region */
95 greg 1.9 d = (double)(-h-hlim)/sampdens;
96     if (d >= 1.0-FTINY)
97 greg 1.1 return;
98     tanb = d/sqrt(1.0-d*d);
99     for (i = 0; i < nglardirs; i++) {
100     d = indirect[i].lcos - tanb*indirect[i].lsin;
101     if (d > 0.0) {
102     indirect[i].sum += d * br;
103 greg 1.10 indirect[i].n += d;
104 greg 1.1 }
105     }
106     return;
107     }
108     if (h >= hlim) { /* right region */
109 greg 1.9 d = (double)(-h+hlim)/sampdens;
110     if (d <= -1.0+FTINY)
111 greg 1.1 return;
112     tanb = d/sqrt(1.0-d*d);
113     for (i = 0; i < nglardirs; i++) {
114     d = indirect[i].rcos - tanb*indirect[i].rsin;
115     if (d > 0.0) {
116     indirect[i].sum += d * br;
117 greg 1.10 indirect[i].n += d;
118 greg 1.1 }
119     }
120     return;
121     }
122     /* central region */
123     for (i = 0; i < nglardirs; i++) {
124     d = cos(h_theta(h) - indirect[i].theta);
125     if (d > 0.0) {
126     indirect[i].sum += d * br;
127 greg 1.10 indirect[i].n += d;
128 greg 1.1 }
129     }
130     }
131    
132    
133     comp_thresh() /* compute glare threshold */
134     {
135     int h, v;
136     int nsamps;
137     double brsum, br;
138    
139     if (verbose)
140     fprintf(stderr, "%s: computing glare threshold...\n",
141     progname);
142     brsum = 0.0;
143     nsamps = 0;
144     for (v = vsize; v >= -vsize; v -= TSAMPSTEP)
145     for (h = -hsize; h <= hsize; h += TSAMPSTEP) {
146     if ((br = getviewpix(h, v)) < 0.0)
147     continue;
148     brsum += br;
149     nsamps++;
150     }
151     if (nsamps == 0) {
152     fprintf(stderr, "%s: no viewable scene!\n", progname);
153     exit(1);
154     }
155     threshold = GLAREBR * brsum / nsamps;
156     if (threshold <= FTINY) {
157     fprintf(stderr, "%s: threshold zero!\n", progname);
158     exit(1);
159     }
160 greg 1.2 if (verbose) {
161 greg 1.8 #ifdef DEBUG
162 greg 1.2 pict_stats();
163 greg 1.8 #endif
164 greg 1.1 fprintf(stderr,
165     "%s: threshold set to %f cd/m2 from %d samples\n",
166     progname, threshold, nsamps);
167 greg 1.2 }
168 greg 1.1 }
169    
170    
171     addsrcspan(nss) /* add new source span to our list */
172     struct srcspan *nss;
173     {
174     struct source *last, *cs, *this;
175     register struct srcspan *ss;
176    
177     cs = NULL;
178     for (this = curlist; this != NULL; this = this->next) {
179     for (ss = this->first; ss != NULL; ss = ss->next) {
180     if (!vcont(nss->v, ss->v))
181     break;
182     if (hcont(ss, nss)) {
183     if (cs == NULL)
184     cs = this;
185     else {
186 greg 1.7 last->next = this->next;
187 greg 1.1 mergesource(cs, this);
188 greg 1.5 this = last;
189 greg 1.1 }
190     break;
191     }
192     }
193     last = this;
194     }
195     if (cs == NULL) {
196     cs = (struct source *)malloc(sizeof(struct source));
197     if (cs == NULL)
198     memerr("source records");
199 greg 1.7 cs->dom = 0.0;
200 greg 1.1 cs->first = NULL;
201     cs->next = curlist;
202     curlist = cs;
203     }
204     nss->next = cs->first;
205     cs->first = nss;
206     }
207    
208    
209     mergesource(sp, ap) /* merge source ap into source sp */
210     struct source *sp, *ap;
211     {
212     struct srcspan head;
213     register struct srcspan *alp, *prev, *tp;
214    
215     head.next = sp->first;
216     prev = &head;
217     alp = ap->first;
218     while (alp != NULL && prev->next != NULL) {
219     if (prev->next->v > alp->v) {
220     tp = alp->next;
221     alp->next = prev->next;
222     prev->next = alp;
223     alp = tp;
224     }
225     prev = prev->next;
226     }
227     if (prev->next == NULL)
228     prev->next = alp;
229     sp->first = head.next;
230 greg 1.7 if (ap->dom > 0.0 && sp->dom > 0.0) { /* sources are done */
231     sp->dir[0] *= sp->dom;
232     sp->dir[1] *= sp->dom;
233     sp->dir[2] *= sp->dom;
234     fvsum(sp->dir, sp->dir, ap->dir, ap->dom);
235     normalize(sp->dir);
236     sp->brt = (sp->brt*sp->dom + ap->brt*ap->dom)
237     / (sp->dom + ap->dom);
238     }
239     free((char *)ap);
240 greg 1.1 }
241    
242    
243     close_sources(v) /* close sources above v */
244     int v;
245     {
246     struct source head;
247     register struct source *last, *this;
248    
249     head.next = curlist;
250     last = &head;
251     for (this = curlist; this != NULL; this = this->next)
252     if (!vcont(v, this->first->v)) {
253     last->next = this->next;
254     donesource(this);
255     this = last;
256     } else
257     last = this;
258     curlist = head.next;
259     }
260    
261    
262     close_allsrcs() /* done with everything */
263     {
264 greg 1.5 register struct source *this, *next;
265 greg 1.1
266 greg 1.5 this = curlist;
267     while (this != NULL) {
268     next = this->next;
269 greg 1.1 donesource(this);
270 greg 1.5 this = next;
271 greg 1.4 }
272 greg 1.1 curlist = NULL;
273     }
274    
275    
276     donesource(sp) /* finished with this source */
277     register struct source *sp;
278     {
279     FVECT dthis, dright;
280     register struct srcspan *ss;
281     int h, n;
282     double d;
283    
284     sp->dom = 0.0;
285 greg 1.5 sp->dir[0] = sp->dir[1] = sp->dir[2] = 0.0;
286 greg 1.1 sp->brt = 0.0;
287 greg 1.3 n = 0;
288 greg 1.1 for (ss = sp->first; ss != NULL; ss = ss->next) {
289     sp->brt += ss->brsum;
290     n += ss->r - ss->l;
291 greg 1.5 if (compdir(dright, ss->r, ss->v) < 0)
292     compdir(dright, ss->r-2, ss->v);
293     for (h = ss->r-1; h >= ss->l; h--)
294     if (compdir(dthis, h, ss->v) == 0) {
295     d = dist2(dthis, dright);
296     fvsum(sp->dir, sp->dir, dthis, d);
297     sp->dom += d;
298     VCOPY(dright, dthis);
299     }
300 greg 1.1 free((char *)ss);
301     }
302     sp->first = NULL;
303     sp->brt /= (double)n;
304 greg 1.5 normalize(sp->dir);
305 greg 1.1 sp->next = donelist;
306     donelist = sp;
307     if (verbose)
308     fprintf(stderr,
309 greg 1.5 "%s: found source at (%.3f,%.3f,%.3f), dw %.5f, br %.1f (%d samps)\n",
310 greg 1.2 progname, sp->dir[0], sp->dir[1], sp->dir[2],
311 greg 1.5 sp->dom, sp->brt, n);
312 greg 1.7 }
313    
314    
315     struct source *
316     findbuddy(s, l) /* find close enough source to s in l*/
317     register struct source *s, *l;
318     {
319     struct source *bestbuddy = NULL;
320     double d, r, mindist = MAXBUDDY;
321    
322     r = sqrt(s->dom/PI);
323     for ( ; l != NULL; l = l->next) {
324     d = sqrt(dist2(l->dir, s->dir)) - sqrt(l->dom/PI) - r;
325     if (d < mindist) {
326     bestbuddy = l;
327     mindist = d;
328     }
329     }
330     return(bestbuddy);
331     }
332    
333    
334     absorb_specks() /* eliminate too-small sources */
335     {
336     struct source head, *buddy;
337     register struct source *last, *this;
338    
339     if (verbose)
340     fprintf(stderr, "%s: absorbing small sources...\n", progname);
341     head.next = donelist;
342     last = &head;
343     for (this = donelist; this != NULL; this = this->next)
344     if (TOOSMALL(this)) {
345     last->next = this->next;
346     buddy = findbuddy(this, donelist);
347     if (buddy != NULL)
348     mergesource(buddy, this);
349     else
350     absorb(this);
351     this = last;
352     } else
353     last = this;
354     donelist = head.next;
355     }
356    
357    
358     absorb(s) /* absorb a source into indirect */
359     register struct source *s;
360     {
361     FVECT dir;
362 greg 1.10 double d;
363     register int i;
364 greg 1.7
365     for (i = 0; i < nglardirs; i++) {
366     spinvector(dir, ourview.vdir, ourview.vup, indirect[i].theta);
367 greg 1.10 d = DOT(dir,s->dir)*s->dom*(sampdens*sampdens);
368     if (d <= 0.0)
369 greg 1.7 continue;
370 greg 1.10 indirect[i].sum += d * s->brt;
371     indirect[i].n += d;
372 greg 1.7 }
373     for ( ; s->first != NULL; s->first = s->first->next)
374     free((char *)s->first);
375     free((char *)s);
376 greg 1.1 }