ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
Revision: 1.2
Committed: Mon Mar 18 14:32:17 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +11 -7 lines
Log Message:
bug fixes and enhancements

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     double threshold; /* glare threshold */
20    
21    
22     struct srcspan *
23     newspan(l, r, v, sb) /* allocate a new source span */
24     int l, r, v;
25     float *sb;
26     {
27     register struct srcspan *ss;
28     register int i;
29    
30     ss = (struct srcspan *)malloc(sizeof(struct srcspan));
31     if (ss == NULL)
32     memerr("source spans");
33     ss->l = l;
34     ss->r = r;
35     ss->v = v;
36     ss->brsum = 0.0;
37     for (i = l; i < r; i++)
38     ss->brsum += sb[i+hsize];
39     return(ss);
40     }
41    
42    
43     analyze() /* analyze our scene */
44     {
45     int h, v;
46     int left;
47     float *spanbr;
48    
49     spanbr = (float *)malloc((2*hsize+1)*sizeof(float));
50     if (spanbr == NULL)
51     memerr("view span brightness buffer");
52     for (v = vsize; v >= -vsize; v--) {
53     getviewspan(v, spanbr);
54     left = hsize + 1;
55 greg 1.2 for (h = -hsize; h <= hsize; h++) {
56 greg 1.1 if (spanbr[h+hsize] < 0.0) { /* off view */
57     if (left < h) {
58 greg 1.2 addsrcspan(newspan(left,h,v,spanbr));
59 greg 1.1 left = hsize + 1;
60     }
61     continue;
62     }
63     if (spanbr[h+hsize] > threshold) { /* in source */
64 greg 1.2 if (left > h)
65 greg 1.1 left = h;
66     } else { /* out of source */
67     if (left < h) {
68 greg 1.2 addsrcspan(newspan(left,h,v,spanbr));
69 greg 1.1 left = hsize + 1;
70     }
71     addindirect(h, spanbr[h+hsize]);
72     }
73 greg 1.2 }
74 greg 1.1 if (left < h)
75 greg 1.2 addsrcspan(newspan(left,h,v,spanbr));
76 greg 1.1 close_sources(v);
77     }
78     close_allsrcs();
79     free((char *)spanbr);
80     }
81    
82    
83     addindirect(h, br) /* add brightness to indirect illuminances */
84     int h;
85     double br;
86     {
87     double tanb, d;
88     register int i;
89    
90     if (h <= -hlim) { /* left region */
91     d = (double)(h+hlim)/SAMPDENS;
92     if (d <= -1.0+FTINY)
93     return;
94     tanb = d/sqrt(1.0-d*d);
95     for (i = 0; i < nglardirs; i++) {
96     d = indirect[i].lcos - tanb*indirect[i].lsin;
97     if (d > 0.0) {
98     indirect[i].sum += d * br;
99     indirect[i].n++;
100     }
101     }
102     return;
103     }
104     if (h >= hlim) { /* right region */
105     d = (double)(h-hlim)/SAMPDENS;
106     if (d >= 1.0-FTINY)
107     return;
108     tanb = d/sqrt(1.0-d*d);
109     for (i = 0; i < nglardirs; i++) {
110     d = indirect[i].rcos - tanb*indirect[i].rsin;
111     if (d > 0.0) {
112     indirect[i].sum += d * br;
113     indirect[i].n++;
114     }
115     }
116     return;
117     }
118     /* central region */
119     for (i = 0; i < nglardirs; i++) {
120     d = cos(h_theta(h) - indirect[i].theta);
121     if (d > 0.0) {
122     indirect[i].sum += d * br;
123     indirect[i].n++;
124     }
125     }
126     }
127    
128    
129     comp_thresh() /* compute glare threshold */
130     {
131     int h, v;
132     int nsamps;
133     double brsum, br;
134    
135     if (verbose)
136     fprintf(stderr, "%s: computing glare threshold...\n",
137     progname);
138     brsum = 0.0;
139     nsamps = 0;
140     for (v = vsize; v >= -vsize; v -= TSAMPSTEP)
141     for (h = -hsize; h <= hsize; h += TSAMPSTEP) {
142     if ((br = getviewpix(h, v)) < 0.0)
143     continue;
144     brsum += br;
145     nsamps++;
146     }
147     if (nsamps == 0) {
148     fprintf(stderr, "%s: no viewable scene!\n", progname);
149     exit(1);
150     }
151     threshold = GLAREBR * brsum / nsamps;
152     if (threshold <= FTINY) {
153     fprintf(stderr, "%s: threshold zero!\n", progname);
154     exit(1);
155     }
156 greg 1.2 if (verbose) {
157     pict_stats();
158 greg 1.1 fprintf(stderr,
159     "%s: threshold set to %f cd/m2 from %d samples\n",
160     progname, threshold, nsamps);
161 greg 1.2 }
162 greg 1.1 }
163    
164    
165     addsrcspan(nss) /* add new source span to our list */
166     struct srcspan *nss;
167     {
168     struct source *last, *cs, *this;
169     register struct srcspan *ss;
170     register int res;
171    
172     cs = NULL;
173     for (this = curlist; this != NULL; this = this->next) {
174     for (ss = this->first; ss != NULL; ss = ss->next) {
175     if (!vcont(nss->v, ss->v))
176     break;
177     if (hcont(ss, nss)) {
178     if (cs == NULL)
179     cs = this;
180     else {
181     mergesource(cs, this);
182     last->next = this->next;
183     free((char *)this);
184     }
185     break;
186     }
187     }
188     last = this;
189     }
190     if (cs == NULL) {
191     cs = (struct source *)malloc(sizeof(struct source));
192     if (cs == NULL)
193     memerr("source records");
194     cs->first = NULL;
195     cs->next = curlist;
196     curlist = cs;
197     }
198     nss->next = cs->first;
199     cs->first = nss;
200     }
201    
202    
203     mergesource(sp, ap) /* merge source ap into source sp */
204     struct source *sp, *ap;
205     {
206     struct srcspan head;
207     register struct srcspan *alp, *prev, *tp;
208    
209     head.next = sp->first;
210     prev = &head;
211     alp = ap->first;
212     while (alp != NULL && prev->next != NULL) {
213     if (prev->next->v > alp->v) {
214     tp = alp->next;
215     alp->next = prev->next;
216     prev->next = alp;
217     alp = tp;
218     }
219     prev = prev->next;
220     }
221     if (prev->next == NULL)
222     prev->next = alp;
223     sp->first = head.next;
224     ap->first = NULL;
225     }
226    
227    
228     close_sources(v) /* close sources above v */
229     int v;
230     {
231     struct source head;
232     register struct source *last, *this;
233    
234     head.next = curlist;
235     last = &head;
236     for (this = curlist; this != NULL; this = this->next)
237     if (!vcont(v, this->first->v)) {
238     last->next = this->next;
239     donesource(this);
240     this = last;
241     } else
242     last = this;
243     curlist = head.next;
244     }
245    
246    
247     close_allsrcs() /* done with everything */
248     {
249     register struct source *this;
250    
251     for (this = curlist; this != NULL; this = this->next)
252     donesource(this);
253     curlist = NULL;
254     }
255    
256    
257     donesource(sp) /* finished with this source */
258     register struct source *sp;
259     {
260     FVECT dthis, dright;
261     register struct srcspan *ss;
262     int h, n;
263     double d;
264    
265     sp->dom = 0.0;
266     sp->dir[0] = sp->dir[1] = sp->dir[1] = 0.0;
267     sp->brt = 0.0;
268     for (ss = sp->first; ss != NULL; ss = ss->next) {
269     sp->brt += ss->brsum;
270     n += ss->r - ss->l;
271     compdir(dright, ss->r, ss->v);
272     for (h = ss->r-1; h >= ss->l; h--) {
273     compdir(dthis, h, ss->v);
274     d = dist2(dthis, dright);
275     fvsum(sp->dir, sp->dir, dthis, d);
276     sp->dom += d;
277     VCOPY(dright, dthis);
278     }
279     free((char *)ss);
280     }
281     sp->first = NULL;
282     sp->brt /= (double)n;
283     sp->dir[0] /= sp->dom;
284     sp->dir[1] /= sp->dom;
285     sp->dir[2] /= sp->dom;
286     sp->next = donelist;
287     donelist = sp;
288     if (verbose)
289     fprintf(stderr,
290     "%s: found source at (%f,%f,%f), solid angle %f, brightness %f\n",
291 greg 1.2 progname, sp->dir[0], sp->dir[1], sp->dir[2],
292     sp->dom, sp->brt);
293 greg 1.1 }