ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
Revision: 1.11
Committed: Wed Apr 10 15:59:10 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.10: +2 -3 lines
Log Message:
fixed small bug in absorb_specks() and added -c option

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