ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
Revision: 1.3
Committed: Mon Mar 18 16:06:53 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +3 -2 lines
Log Message:
made option to change sample density

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,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,v,spanbr));
69 left = hsize + 1;
70 }
71 addindirect(h, spanbr[h+hsize]);
72 }
73 }
74 if (left < h)
75 addsrcspan(newspan(left,h,v,spanbr));
76 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 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 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 n = 0;
269 for (ss = sp->first; ss != NULL; ss = ss->next) {
270 sp->brt += ss->brsum;
271 n += ss->r - ss->l;
272 compdir(dright, ss->r, ss->v);
273 for (h = ss->r-1; h >= ss->l; h--) {
274 compdir(dthis, h, ss->v);
275 d = dist2(dthis, dright);
276 fvsum(sp->dir, sp->dir, dthis, d);
277 sp->dom += d;
278 VCOPY(dright, dthis);
279 }
280 free((char *)ss);
281 }
282 sp->first = NULL;
283 sp->brt /= (double)n;
284 sp->dir[0] /= sp->dom;
285 sp->dir[1] /= sp->dom;
286 sp->dir[2] /= sp->dom;
287 sp->next = donelist;
288 donelist = sp;
289 if (verbose)
290 fprintf(stderr,
291 "%s: found source at (%f,%f,%f), solid angle %f, brightness %f\n",
292 progname, sp->dir[0], sp->dir[1], sp->dir[2],
293 sp->dom, sp->brt);
294 }