ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
Revision: 1.6
Committed: Tue Mar 19 17:21:31 1991 UTC (33 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +0 -2 lines
Log Message:
added -t option to set threshold

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