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

# 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 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 }