ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
(Generate patch)

Comparing ray/src/util/glaresrc.c (file contents):
Revision 1.1 by greg, Mon Mar 18 12:15:40 1991 UTC vs.
Revision 1.7 by greg, Wed Mar 20 12:18:14 1991 UTC

# Line 16 | Line 16 | static char SCCSid[] = "$SunId$ LBL";
16   struct source   *curlist = NULL;        /* current source list */
17   struct source   *donelist = NULL;       /* finished sources */
18  
19 double  threshold;                      /* glare threshold */
19  
21
20   struct srcspan *
21   newspan(l, r, v, sb)            /* allocate a new source span */
22   int     l, r, v;
# Line 50 | Line 48 | analyze()                      /* analyze our scene */
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++)
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-1,v,spanbr));
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)
63 >                                if (left > h)
64                                          left = h;
65                          } else {                        /* out of source */
66                                  if (left < h) {
67 <                                        addsrcspan(newspan(left,h-1,v,spanbr));
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-1,v,spanbr));
75 <                close_sources(v);
74 >                        addsrcspan(newspan(left,h,v,spanbr));
75          }
77        close_allsrcs();
76          free((char *)spanbr);
77 +        close_allsrcs();
78 +        absorb_specks();
79   }
80  
81  
# Line 87 | Line 87 | double br;
87          register int    i;
88  
89          if (h <= -hlim) {                       /* left region */
90 <                d = (double)(h+hlim)/SAMPDENS;
90 >                d = (double)(h+hlim)/sampdens;
91                  if (d <= -1.0+FTINY)
92                          return;
93                  tanb = d/sqrt(1.0-d*d);
# Line 101 | Line 101 | double br;
101                  return;
102          }
103          if (h >= hlim) {                        /* right region */
104 <                d = (double)(h-hlim)/SAMPDENS;
104 >                d = (double)(h-hlim)/sampdens;
105                  if (d >= 1.0-FTINY)
106                          return;
107                  tanb = d/sqrt(1.0-d*d);
# Line 152 | Line 152 | comp_thresh()                  /* compute glare threshold */
152                  fprintf(stderr, "%s: threshold zero!\n", progname);
153                  exit(1);
154          }
155 <        if (verbose)
155 >        if (verbose) {
156 >                pict_stats();
157                  fprintf(stderr,
158                          "%s: threshold set to %f cd/m2 from %d samples\n",
159                                  progname, threshold, nsamps);
160 +        }
161   }
162  
163  
# Line 164 | Line 166 | struct srcspan *nss;
166   {
167          struct source   *last, *cs, *this;
168          register struct srcspan *ss;
167        register int    res;
169  
170          cs = NULL;
171          for (this = curlist; this != NULL; this = this->next) {
# Line 175 | Line 176 | struct srcspan *nss;
176                                  if (cs == NULL)
177                                          cs = this;
178                                  else {
178                                        mergesource(cs, this);
179                                          last->next = this->next;
180 <                                        free((char *)this);
180 >                                        mergesource(cs, this);
181 >                                        this = last;
182                                  }
183                                  break;
184                          }
# Line 188 | Line 189 | struct srcspan *nss;
189                  cs = (struct source *)malloc(sizeof(struct source));
190                  if (cs == NULL)
191                          memerr("source records");
192 +                cs->dom = 0.0;
193                  cs->first = NULL;
194                  cs->next = curlist;
195                  curlist = cs;
# Line 218 | Line 220 | struct source  *sp, *ap;
220          if (prev->next == NULL)
221                  prev->next = alp;
222          sp->first = head.next;
223 <        ap->first = NULL;
223 >        if (ap->dom > 0.0 && sp->dom > 0.0) {           /* sources are done */
224 >                sp->dir[0] *= sp->dom;
225 >                sp->dir[1] *= sp->dom;
226 >                sp->dir[2] *= sp->dom;
227 >                fvsum(sp->dir, sp->dir, ap->dir, ap->dom);
228 >                normalize(sp->dir);
229 >                sp->brt = (sp->brt*sp->dom + ap->brt*ap->dom)
230 >                                / (sp->dom + ap->dom);
231 >        }
232 >        free((char *)ap);
233   }
234  
235  
# Line 243 | Line 254 | int    v;
254  
255   close_allsrcs()                 /* done with everything */
256   {
257 <        register struct source  *this;
257 >        register struct source  *this, *next;
258  
259 <        for (this = curlist; this != NULL; this = this->next)
259 >        this = curlist;
260 >        while (this != NULL) {
261 >                next = this->next;
262                  donesource(this);
263 +                this = next;
264 +        }
265          curlist = NULL;
266   }
267  
# Line 260 | Line 275 | register struct source *sp;
275          double  d;
276  
277          sp->dom = 0.0;
278 <        sp->dir[0] = sp->dir[1] = sp->dir[1] = 0.0;
278 >        sp->dir[0] = sp->dir[1] = sp->dir[2] = 0.0;
279          sp->brt = 0.0;
280 +        n = 0;
281          for (ss = sp->first; ss != NULL; ss = ss->next) {
282                  sp->brt += ss->brsum;
283                  n += ss->r - ss->l;
284 <                compdir(dright, ss->r, ss->v);
285 <                for (h = ss->r-1; h >= ss->l; h--) {
286 <                        compdir(dthis, h, ss->v);
287 <                        d = dist2(dthis, dright);
288 <                        fvsum(sp->dir, sp->dir, dthis, d);
289 <                        sp->dom += d;
290 <                        VCOPY(dright, dthis);
291 <                }
284 >                if (compdir(dright, ss->r, ss->v) < 0)
285 >                        compdir(dright, ss->r-2, ss->v);
286 >                for (h = ss->r-1; h >= ss->l; h--)
287 >                        if (compdir(dthis, h, ss->v) == 0) {
288 >                                d = dist2(dthis, dright);
289 >                                fvsum(sp->dir, sp->dir, dthis, d);
290 >                                sp->dom += d;
291 >                                VCOPY(dright, dthis);
292 >                        }
293                  free((char *)ss);
294          }
295          sp->first = NULL;
296          sp->brt /= (double)n;
297 <        sp->dir[0] /= sp->dom;
281 <        sp->dir[1] /= sp->dom;
282 <        sp->dir[2] /= sp->dom;
297 >        normalize(sp->dir);
298          sp->next = donelist;
299          donelist = sp;
300          if (verbose)
301                  fprintf(stderr,
302 <        "%s: found source at (%f,%f,%f), solid angle %f, brightness %f\n",
303 <                        progname, sp->dir[0], sp->dir[1], sp->dir[2], sp->brt);
302 >        "%s: found source at (%.3f,%.3f,%.3f), dw %.5f, br %.1f (%d samps)\n",
303 >                        progname, sp->dir[0], sp->dir[1], sp->dir[2],
304 >                        sp->dom, sp->brt, n);
305 > }
306 >
307 >
308 > struct source *
309 > findbuddy(s, l)                 /* find close enough source to s in l*/
310 > register struct source  *s, *l;
311 > {
312 >        struct source   *bestbuddy = NULL;
313 >        double  d, r, mindist = MAXBUDDY;
314 >
315 >        r = sqrt(s->dom/PI);
316 >        for ( ; l != NULL; l = l->next) {
317 >                d = sqrt(dist2(l->dir, s->dir)) - sqrt(l->dom/PI) - r;
318 >                if (d < mindist) {
319 >                        bestbuddy = l;
320 >                        mindist = d;
321 >                }
322 >        }
323 >        return(bestbuddy);
324 > }
325 >
326 >
327 > absorb_specks()                 /* eliminate too-small sources */
328 > {
329 >        struct source   head, *buddy;
330 >        register struct source  *last, *this;
331 >
332 >        if (verbose)
333 >                fprintf(stderr, "%s: absorbing small sources...\n", progname);
334 >        head.next = donelist;
335 >        last = &head;
336 >        for (this = donelist; this != NULL; this = this->next)
337 >                if (TOOSMALL(this)) {
338 >                        last->next = this->next;
339 >                        buddy = findbuddy(this, donelist);
340 >                        if (buddy != NULL)
341 >                                mergesource(buddy, this);
342 >                        else
343 >                                absorb(this);
344 >                        this = last;
345 >                } else
346 >                        last = this;
347 >        donelist = head.next;
348 > }
349 >
350 >
351 > absorb(s)                       /* absorb a source into indirect */
352 > register struct source  *s;
353 > {
354 >        FVECT   dir;
355 >        register int    i, n;
356 >
357 >        for (i = 0; i < nglardirs; i++) {
358 >                spinvector(dir, ourview.vdir, ourview.vup, indirect[i].theta);
359 >                n = DOT(dir,s->dir)*s->dom*(sampdens*sampdens) + 0.5;
360 >                if (n == 0)
361 >                        continue;
362 >                indirect[i].sum += n * s->brt;
363 >                indirect[i].n += n;
364 >        }
365 >        for ( ; s->first != NULL; s->first = s->first->next)
366 >                free((char *)s->first);
367 >        free((char *)s);
368   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines