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.3 by greg, Mon Mar 18 16:06:53 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++) {
# Line 73 | Line 72 | analyze()                      /* analyze our scene */
72                  }
73                  if (left < h)
74                          addsrcspan(newspan(left,h,v,spanbr));
76                close_sources(v);
75          }
78        close_allsrcs();
76          free((char *)spanbr);
77 +        close_allsrcs();
78 +        absorb_specks();
79   }
80  
81  
# Line 167 | Line 166 | struct srcspan *nss;
166   {
167          struct source   *last, *cs, *this;
168          register struct srcspan *ss;
170        register int    res;
169  
170          cs = NULL;
171          for (this = curlist; this != NULL; this = this->next) {
# Line 178 | Line 176 | struct srcspan *nss;
176                                  if (cs == NULL)
177                                          cs = this;
178                                  else {
181                                        mergesource(cs, this);
179                                          last->next = this->next;
180 <                                        free((char *)this);
180 >                                        mergesource(cs, this);
181 >                                        this = last;
182                                  }
183                                  break;
184                          }
# Line 191 | 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 221 | 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 246 | 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 263 | 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;
285 <        sp->dir[1] /= sp->dom;
286 <        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",
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);
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