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

Comparing ray/src/rt/ambient.c (file contents):
Revision 2.58 by greg, Tue Apr 19 01:15:06 2005 UTC vs.
Revision 2.70 by greg, Thu Sep 22 02:15:56 2011 UTC

# Line 25 | Line 25 | static const char      RCSid[] = "$Id$";
25   extern char  *shm_boundary;     /* memory sharing boundary */
26  
27   #ifndef  MAXASET
28 < #define  MAXASET        2047    /* maximum number of elements in ambient set */
28 > #define  MAXASET        4095    /* maximum number of elements in ambient set */
29   #endif
30   OBJECT  ambset[MAXASET+1]={0};  /* ambient include/exclude set */
31  
# Line 140 | Line 140 | extern void
140   setambient(void)                                /* initialize calculation */
141   {
142          int     readonly = 0;
143 <        long  pos, flen;
143 >        long    flen;
144          AMBVAL  amb;
145                                                  /* make sure we're fresh */
146          ambdone();
# Line 160 | Line 160 | setambient(void)                               /* initialize calculation */
160                  readonly = (ambfp = fopen(ambfile, "r")) != NULL;
161          if (ambfp != NULL) {
162                  initambfile(0);                 /* file exists */
163 <                pos = ftell(ambfp);
163 >                lastpos = ftell(ambfp);
164                  while (readambval(&amb, ambfp))
165                          avinsert(avstore(&amb));
166                  nambshare = nambvals;           /* share loaded values */
# Line 174 | Line 174 | setambient(void)                               /* initialize calculation */
174                          return;                 /* avoid ambsync() */
175                  }
176                                                  /* align file pointer */
177 <                pos += (long)nambvals*AMBVALSIZ;
177 >                lastpos += (long)nambvals*AMBVALSIZ;
178                  flen = lseek(fileno(ambfp), (off_t)0, SEEK_END);
179 <                if (flen != pos) {
179 >                if (flen != lastpos) {
180                          sprintf(errmsg,
181                          "ignoring last %ld values in ambient file (corrupted)",
182 <                                        (flen - pos)/AMBVALSIZ);
182 >                                        (flen - lastpos)/AMBVALSIZ);
183                          error(WARNING, errmsg);
184 <                        fseek(ambfp, pos, 0);
184 >                        fseek(ambfp, lastpos, SEEK_SET);
185   #ifndef _WIN32 /* XXX we need a replacement for that one */
186 <                        ftruncate(fileno(ambfp), (off_t)pos);
186 >                        ftruncate(fileno(ambfp), (off_t)lastpos);
187   #endif
188                  }
189          } else if ((ambfp = fopen(ambfile, "w+")) != NULL) {
190                  initambfile(1);                 /* else create new file */
191 +                fflush(ambfp);
192 +                lastpos = ftell(ambfp);
193          } else {
194                  sprintf(errmsg, "cannot open ambient file \"%s\"", ambfile);
195                  error(SYSTEM, errmsg);
196          }
197 <        nunflshed++;    /* lie */
198 <        ambsync();
197 > #ifdef  F_SETLKW
198 >        aflock(F_UNLCK);                        /* release file */
199 > #endif
200   }
201  
202  
# Line 229 | Line 232 | ambnotify(                     /* record new modifier */
232   )
233   {
234          static int  hitlimit = 0;
235 <        register OBJREC  *o;
236 <        register char  **amblp;
235 >        OBJREC   *o;
236 >        char  **amblp;
237  
238          if (obj == OVOID) {             /* starting over */
239                  ambset[0] = 0;
# Line 256 | Line 259 | ambnotify(                     /* record new modifier */
259   extern void
260   multambient(            /* compute ambient component & multiply by coef. */
261          COLOR  aval,
262 <        register RAY  *r,
262 >        RAY  *r,
263          FVECT  nrm
264   )
265   {
# Line 275 | Line 278 | multambient(           /* compute ambient component & multiply
278                  goto dumbamb;
279  
280          if (ambacc <= FTINY) {                  /* no ambient storage */
281 +                copycolor(acol, aval);
282                  rdepth++;
283 <                d = doambient(acol, r, aval, intens(aval)*r->rweight,
280 <                                                        NULL, NULL);
283 >                d = doambient(acol, r, r->rweight, NULL, NULL);
284                  rdepth--;
285                  if (d <= FTINY)
286                          goto dumbamb;
287 <                multcolor(aval, acol);
287 >                copycolor(aval, acol);
288                  return;
289          }
290  
291          if (tracktime)                          /* sort to minimize thrashing */
292                  sortambvals(0);
293 <                                                /* get ambient value */
293 >                                                /* interpolate ambient value */
294          setcolor(acol, 0.0, 0.0, 0.0);
295          d = sumambient(acol, r, nrm, rdepth,
296                          &atrunk, thescene.cuorg, thescene.cusize);
297          if (d > FTINY) {
298 <                scalecolor(acol, 1.0/d);
298 >                d = 1.0/d;
299 >                scalecolor(acol, d);
300                  multcolor(aval, acol);
301                  return;
302          }
303          rdepth++;                               /* need to cache new value */
304 <        d = makeambient(acol, r, aval, nrm, rdepth-1);
304 >        d = makeambient(acol, r, nrm, rdepth-1);
305          rdepth--;
306          if (d > FTINY) {
307                  multcolor(aval, acol);          /* got new value */
# Line 325 | Line 329 | dumbamb:                                       /* return global value */
329   extern double
330   sumambient(     /* get interpolated ambient value */
331          COLOR  acol,
332 <        register RAY  *r,
332 >        RAY  *r,
333          FVECT  rn,
334          int  al,
335          AMBTREE  *at,
# Line 337 | Line 341 | sumambient(    /* get interpolated ambient value */
341          COLOR  ct;
342          FVECT  ck0;
343          int  i;
344 <        register int  j;
345 <        register AMBVAL  *av;
344 >        int  j;
345 >        AMBVAL   *av;
346  
347          wsum = 0.0;
348                                          /* do this node */
# Line 351 | Line 355 | sumambient(    /* get interpolated ambient value */
355                   */
356                  if (av->lvl > al)       /* list sorted, so this works */
357                          break;
358 <                if (av->weight < r->rweight-FTINY)
358 >                if (av->weight < 0.9*r->rweight)
359                          continue;
360                  /*
361                   *  Ambient radius test.
362                   */
363 <                d = av->pos[0] - r->rop[0];
364 <                e1 = d * d;
361 <                d = av->pos[1] - r->rop[1];
362 <                e1 += d * d;
363 <                d = av->pos[2] - r->rop[2];
364 <                e1 += d * d;
365 <                e1 /= av->rad * av->rad;
363 >                VSUB(ck0, av->pos, r->rop);
364 >                e1 = DOT(ck0, ck0) / (av->rad * av->rad);
365                  if (e1 > ambacc*ambacc*1.21)
366                          continue;
367                  /*
# Line 379 | Line 378 | sumambient(    /* get interpolated ambient value */
378                          }
379                  }
380                  e2 = (1.0 - d) * r->rweight;
381 <                if (e2 < 0.0) e2 = 0.0;
382 <                if (e1 + e2 > ambacc*ambacc*1.21)
381 >                if (e2 < 0.0)
382 >                        e2 = 0.0;
383 >                else if (e1 + e2 > ambacc*ambacc*1.21)
384                          continue;
385                  /*
386                   *  Ray behind test.
# Line 430 | Line 430 | sumambient(    /* get interpolated ambient value */
430                                  break;
431                  }
432                  if (j == 3)
433 <                        wsum += sumambient(acol, r, rn, al, at->kid+i, ck0, s);
433 >                        wsum += sumambient(acol, r, rn, al,
434 >                                                at->kid+i, ck0, s);
435          }
436          return(wsum);
437   }
438  
439  
440   extern double
441 < makeambient(    /* make a new ambient value */
441 > makeambient(            /* make a new ambient value for storage */
442          COLOR  acol,
443          RAY  *r,
443        COLOR  ac,
444          FVECT  rn,
445          int  al
446   )
447   {
448          AMBVAL  amb;
449        double  coef;
449          FVECT   gp, gd;
450 <                                                /* compute weight */
451 <        amb.weight = pow(AVGREFL, (double)al);
452 <        coef = intens(ac)*r->rweight;
453 <        if (coef < 0.1*amb.weight)              /* heuristic */
454 <                amb.weight = coef;
450 >        int     i;
451 >
452 >        amb.weight = 1.0;                       /* compute weight */
453 >        for (i = al; i-- > 0; )
454 >                amb.weight *= AVGREFL;
455 >        if (r->rweight < 0.1*amb.weight)        /* heuristic override */
456 >                amb.weight = 1.25*r->rweight;
457 >        setcolor(acol, AVGREFL, AVGREFL, AVGREFL);
458                                                  /* compute ambient */
459 <        amb.rad = doambient(acol, r, ac, amb.weight, gp, gd);
460 <        if (amb.rad <= FTINY)
459 >        amb.rad = doambient(acol, r, amb.weight, gp, gd);
460 >        if (amb.rad <= FTINY) {
461 >                setcolor(acol, 0.0, 0.0, 0.0);
462                  return(0.0);
463 <                                                /* store it */
463 >        }
464 >        scalecolor(acol, 1./AVGREFL);           /* undo assumed reflectance */
465 >                                                /* store value */
466          VCOPY(amb.pos, r->rop);
467          VCOPY(amb.dir, r->ron);
468          amb.lvl = al;
# Line 475 | Line 480 | makeambient(   /* make a new ambient value */
480   extern void
481   extambient(             /* extrapolate value at pv, nv */
482          COLOR  cr,
483 <        register AMBVAL  *ap,
483 >        AMBVAL   *ap,
484          FVECT  pv,
485          FVECT  nv
486   )
487   {
488          FVECT  v1;
489 <        register int  i;
489 >        int  i;
490          double  d;
491  
492          d = 1.0;                        /* zeroeth order */
# Line 502 | Line 507 | extambient(            /* extrapolate value at pv, nv */
507  
508   static void
509   initambfile(            /* initialize ambient file */
510 <        int  creat
510 >        int  cre8
511   )
512   {
513          extern char  *progname, *octname;
514          static char  *mybuf = NULL;
515  
516   #ifdef  F_SETLKW
517 <        aflock(creat ? F_WRLCK : F_RDLCK);
517 >        aflock(cre8 ? F_WRLCK : F_RDLCK);
518   #endif
519          SET_FILE_BINARY(ambfp);
520          if (mybuf == NULL)
521                  mybuf = (char *)bmalloc(BUFSIZ+8);
522          setbuf(ambfp, mybuf);
523 <        if (creat) {                    /* new file */
523 >        if (cre8) {                     /* new file */
524                  newheader("RADIANCE", ambfp);
525                  fprintf(ambfp, "%s -av %g %g %g -aw %d -ab %d -aa %g ",
526                                  progname, colval(ambval,RED),
# Line 524 | Line 529 | initambfile(           /* initialize ambient file */
529                  fprintf(ambfp, "-ad %d -as %d -ar %d ",
530                                  ambdiv, ambssamp, ambres);
531                  if (octname != NULL)
532 <                        printargs(1, &octname, ambfp);
533 <                else
529 <                        fputc('\n', ambfp);
532 >                        fputs(octname, ambfp);
533 >                fputc('\n', ambfp);
534                  fprintf(ambfp, "SOFTWARE= %s\n", VersionID);
535                  fputnow(ambfp);
536                  fputformat(AMBFMT, ambfp);
537 <                putc('\n', ambfp);
537 >                fputc('\n', ambfp);
538                  putambmagic(ambfp);
539          } else if (checkheader(ambfp, AMBFMT, NULL) < 0 || !hasambmagic(ambfp))
540                  error(USER, "bad ambient file");
# Line 558 | Line 562 | writerr:
562  
563   static AMBVAL *
564   avstore(                                /* allocate memory and store aval */
565 <        register AMBVAL  *aval
565 >        AMBVAL  *aval
566   )
567   {
568 <        register AMBVAL  *av;
568 >        AMBVAL  *av;
569          double  d;
570  
571          if ((av = newambval()) == NULL)
# Line 587 | Line 591 | static AMBTREE  *atfreelist = NULL;    /* free ambient tr
591   static AMBTREE *
592   newambtree(void)                                /* allocate 8 ambient tree structs */
593   {
594 <        register AMBTREE  *atp, *upperlim;
594 >        AMBTREE  *atp, *upperlim;
595  
596          if (atfreelist == NULL) {       /* get more nodes */
597                  atfreelist = (AMBTREE *)malloc(ATALLOCSZ*8*sizeof(AMBTREE));
# Line 621 | Line 625 | avinsert(                              /* insert ambient value in our tree */
625          void *av
626   )
627   {
628 <        register AMBTREE  *at;
629 <        register AMBVAL  *ap;
628 >        AMBTREE  *at;
629 >        AMBVAL  *ap;
630          AMBVAL  avh;
631          FVECT  ck0;
632          double  s;
633          int  branch;
634 <        register int  i;
634 >        int  i;
635  
636          if (((AMBVAL*)av)->rad <= FTINY)
637                  error(CONSISTENCY, "zero ambient radius in avinsert");
# Line 659 | Line 663 | avinsert(                              /* insert ambient value in our tree */
663  
664   static void
665   unloadatree(                    /* unload an ambient value tree */
666 <        register AMBTREE  *at,
666 >        AMBTREE  *at,
667          unloadtf_t *f
668   )
669   {
670 <        register AMBVAL  *av;
671 <        register int  i;
670 >        AMBVAL  *av;
671 >        int  i;
672                                          /* transfer values at this node */
673          for (av = at->alist; av != NULL; av = at->alist) {
674                  at->alist = av->next;
# Line 708 | Line 712 | alatcmp(                       /* compare ambient values for MRA */
712          const void *av2
713   )
714   {
715 <        register long  lc = ((struct avl *)av2)->t - ((struct avl *)av1)->t;
715 >        long  lc = ((struct avl *)av2)->t - ((struct avl *)av1)->t;
716          return(lc<0 ? -1 : lc>0 ? 1 : 0);
717   }
718  
# Line 725 | Line 729 | aposcmp(                       /* compare ambient value positions */
729          const void      *avp2
730   )
731   {
732 <        register long   diff = *(char * const *)avp1 - *(char * const *)avp2;
732 >        long    diff = *(char * const *)avp1 - *(char * const *)avp2;
733          if (diff < 0)
734                  return(-1);
735          return(diff > 0);
# Line 737 | Line 741 | avlmemi(                               /* find list position from address */
741          AMBVAL  *avaddr
742   )
743   {
744 <        register AMBVAL  **avlpp;
744 >        AMBVAL  **avlpp;
745  
746          avlpp = (AMBVAL **)bsearch((char *)&avaddr, (char *)avlist2,
747                          nambvals, sizeof(AMBVAL *), aposcmp);
# Line 758 | Line 762 | sortambvals(                   /* resort ambient values */
762   {
763          AMBTREE  oldatrunk;
764          AMBVAL  tav, *tap, *pnext;
765 <        register int    i, j;
765 >        int     i, j;
766                                          /* see if it's time yet */
767          if (!always && (ambclock++ < lastsort+sortintvl ||
768                          nambvals < SORT_THRESH))
# Line 858 | Line 862 | aflock(                        /* lock/unlock ambient file */
862   {
863          static struct flock  fls;       /* static so initialized to zeroes */
864  
865 +        if (typ == fls.l_type)          /* already called? */
866 +                return;
867          fls.l_type = typ;
868          if (fcntl(fileno(ambfp), F_SETLKW, &fls) < 0)
869                  error(SYSTEM, "cannot (un)lock ambient file");
# Line 869 | Line 875 | ambsync(void)                  /* synchronize ambient file */
875   {
876          long  flen;
877          AMBVAL  avs;
878 <        register int  n;
878 >        int  n;
879  
880 <        if (nunflshed == 0)
880 >        if (ambfp == NULL)      /* no ambient file? */
881                  return(0);
882 <        if (lastpos < 0)        /* initializing (locked in initambfile) */
883 <                goto syncend;
878 <                                /* gain exclusive access */
879 <        aflock(F_WRLCK);
882 >                                /* gain appropriate access */
883 >        aflock(nunflshed ? F_WRLCK : F_RDLCK);
884                                  /* see if file has grown */
885          if ((flen = lseek(fileno(ambfp), (off_t)0, SEEK_END)) < 0)
886                  goto seekerr;
887 <        if ( (n = flen - lastpos) ) {           /* file has grown */
887 >        if ((n = flen - lastpos) > 0) {         /* file has grown */
888                  if (ambinp == NULL) {           /* use duplicate filedes */
889                          ambinp = fdopen(dup(fileno(ambfp)), "r");
890                          if (ambinp == NULL)
891                                  error(SYSTEM, "fdopen failed in ambsync");
892                  }
893 <                if (fseek(ambinp, lastpos, 0) < 0)
893 >                if (fseek(ambinp, lastpos, SEEK_SET) < 0)
894                          goto seekerr;
895                  while (n >= AMBVALSIZ) {        /* load contributed values */
896                          if (!readambval(&avs, ambinp)) {
# Line 899 | Line 903 | ambsync(void)                  /* synchronize ambient file */
903                          avinsert(avstore(&avs));
904                          n -= AMBVALSIZ;
905                  }
906 +                lastpos = flen - n;
907                  /*** seek always as safety measure
908                  if (n) ***/                     /* alignment */
909 <                        if (lseek(fileno(ambfp), (off_t)(flen-n), SEEK_SET) < 0)
909 >                        if (lseek(fileno(ambfp), (off_t)lastpos, SEEK_SET) < 0)
910                                  goto seekerr;
911          }
907 #ifdef  DEBUG
908        if (ambfp->_ptr - ambfp->_base != nunflshed*AMBVALSIZ) {
909                sprintf(errmsg, "ambient file buffer at %d rather than %d",
910                                ambfp->_ptr - ambfp->_base,
911                                nunflshed*AMBVALSIZ);
912                error(CONSISTENCY, errmsg);
913        }
914 #endif
915 syncend:
912          n = fflush(ambfp);                      /* calls write() at last */
913 <        if ((lastpos = lseek(fileno(ambfp), (off_t)0, SEEK_CUR)) < 0)
913 >        if (n != EOF)
914 >                lastpos += (long)nunflshed*AMBVALSIZ;
915 >        else if ((lastpos = lseek(fileno(ambfp), (off_t)0, SEEK_CUR)) < 0)
916                  goto seekerr;
917 +                
918          aflock(F_UNLCK);                        /* release file */
919          nunflshed = 0;
920          return(n);
# Line 929 | Line 928 | seekerr:
928   extern int
929   ambsync(void)                   /* flush ambient file */
930   {
931 <        if (nunflshed == 0)
931 >        if (ambfp == NULL)
932                  return(0);
933          nunflshed = 0;
934          return(fflush(ambfp));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines