ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
Revision: 1.1
Committed: Mon Mar 18 12:15:40 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

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