ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
Revision: 1.5
Committed: Tue Mar 19 17:06:25 1991 UTC (33 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +20 -19 lines
Log Message:
various bug fixes and enhancements

File Contents

# Content
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 close_sources(v);
54 getviewspan(v, spanbr);
55 left = hsize + 1;
56 for (h = -hsize; h <= hsize; h++) {
57 if (spanbr[h+hsize] < 0.0) { /* off view */
58 if (left < h) {
59 addsrcspan(newspan(left,h,v,spanbr));
60 left = hsize + 1;
61 }
62 continue;
63 }
64 if (spanbr[h+hsize] > threshold) { /* in source */
65 if (left > h)
66 left = h;
67 } else { /* out of source */
68 if (left < h) {
69 addsrcspan(newspan(left,h,v,spanbr));
70 left = hsize + 1;
71 }
72 addindirect(h, spanbr[h+hsize]);
73 }
74 }
75 if (left < h)
76 addsrcspan(newspan(left,h,v,spanbr));
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 if (verbose) {
157 pict_stats();
158 fprintf(stderr,
159 "%s: threshold set to %f cd/m2 from %d samples\n",
160 progname, threshold, nsamps);
161 }
162 }
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
171 cs = NULL;
172 for (this = curlist; this != NULL; this = this->next) {
173 for (ss = this->first; ss != NULL; ss = ss->next) {
174 if (!vcont(nss->v, ss->v))
175 break;
176 if (hcont(ss, nss)) {
177 if (cs == NULL)
178 cs = this;
179 else {
180 mergesource(cs, this);
181 last->next = this->next;
182 free((char *)this);
183 this = last;
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, *next;
250
251 this = curlist;
252 while (this != NULL) {
253 next = this->next;
254 donesource(this);
255 this = next;
256 }
257 curlist = NULL;
258 }
259
260
261 donesource(sp) /* finished with this source */
262 register struct source *sp;
263 {
264 FVECT dthis, dright;
265 register struct srcspan *ss;
266 int h, n;
267 double d;
268
269 sp->dom = 0.0;
270 sp->dir[0] = sp->dir[1] = sp->dir[2] = 0.0;
271 sp->brt = 0.0;
272 n = 0;
273 for (ss = sp->first; ss != NULL; ss = ss->next) {
274 sp->brt += ss->brsum;
275 n += ss->r - ss->l;
276 if (compdir(dright, ss->r, ss->v) < 0)
277 compdir(dright, ss->r-2, ss->v);
278 for (h = ss->r-1; h >= ss->l; h--)
279 if (compdir(dthis, h, ss->v) == 0) {
280 d = dist2(dthis, dright);
281 fvsum(sp->dir, sp->dir, dthis, d);
282 sp->dom += d;
283 VCOPY(dright, dthis);
284 }
285 free((char *)ss);
286 }
287 sp->first = NULL;
288 sp->brt /= (double)n;
289 normalize(sp->dir);
290 sp->next = donelist;
291 donelist = sp;
292 if (verbose)
293 fprintf(stderr,
294 "%s: found source at (%.3f,%.3f,%.3f), dw %.5f, br %.1f (%d samps)\n",
295 progname, sp->dir[0], sp->dir[1], sp->dir[2],
296 sp->dom, sp->brt, n);
297 }