ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
Revision: 1.12
Committed: Fri Apr 12 10:28:36 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +9 -6 lines
Log Message:
minor changes and bug fixes

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