--- ray/src/rt/ambient.c 2005/04/19 01:15:06 2.58 +++ ray/src/rt/ambient.c 2011/06/27 22:10:37 2.69 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: ambient.c,v 2.58 2005/04/19 01:15:06 greg Exp $"; +static const char RCSid[] = "$Id: ambient.c,v 2.69 2011/06/27 22:10:37 greg Exp $"; #endif /* * ambient.c - routines dealing with ambient (inter-reflected) component. @@ -25,7 +25,7 @@ static const char RCSid[] = "$Id: ambient.c,v 2.58 200 extern char *shm_boundary; /* memory sharing boundary */ #ifndef MAXASET -#define MAXASET 2047 /* maximum number of elements in ambient set */ +#define MAXASET 4095 /* maximum number of elements in ambient set */ #endif OBJECT ambset[MAXASET+1]={0}; /* ambient include/exclude set */ @@ -140,7 +140,7 @@ extern void setambient(void) /* initialize calculation */ { int readonly = 0; - long pos, flen; + long flen; AMBVAL amb; /* make sure we're fresh */ ambdone(); @@ -160,7 +160,7 @@ setambient(void) /* initialize calculation */ readonly = (ambfp = fopen(ambfile, "r")) != NULL; if (ambfp != NULL) { initambfile(0); /* file exists */ - pos = ftell(ambfp); + lastpos = ftell(ambfp); while (readambval(&amb, ambfp)) avinsert(avstore(&amb)); nambshare = nambvals; /* share loaded values */ @@ -174,26 +174,29 @@ setambient(void) /* initialize calculation */ return; /* avoid ambsync() */ } /* align file pointer */ - pos += (long)nambvals*AMBVALSIZ; + lastpos += (long)nambvals*AMBVALSIZ; flen = lseek(fileno(ambfp), (off_t)0, SEEK_END); - if (flen != pos) { + if (flen != lastpos) { sprintf(errmsg, "ignoring last %ld values in ambient file (corrupted)", - (flen - pos)/AMBVALSIZ); + (flen - lastpos)/AMBVALSIZ); error(WARNING, errmsg); - fseek(ambfp, pos, 0); + fseek(ambfp, lastpos, SEEK_SET); #ifndef _WIN32 /* XXX we need a replacement for that one */ - ftruncate(fileno(ambfp), (off_t)pos); + ftruncate(fileno(ambfp), (off_t)lastpos); #endif } } else if ((ambfp = fopen(ambfile, "w+")) != NULL) { initambfile(1); /* else create new file */ + fflush(ambfp); + lastpos = ftell(ambfp); } else { sprintf(errmsg, "cannot open ambient file \"%s\"", ambfile); error(SYSTEM, errmsg); } - nunflshed++; /* lie */ - ambsync(); +#ifdef F_SETLKW + aflock(F_UNLCK); /* release file */ +#endif } @@ -275,29 +278,30 @@ multambient( /* compute ambient component & multiply goto dumbamb; if (ambacc <= FTINY) { /* no ambient storage */ + copycolor(acol, aval); rdepth++; - d = doambient(acol, r, aval, intens(aval)*r->rweight, - NULL, NULL); + d = doambient(acol, r, r->rweight, NULL, NULL); rdepth--; if (d <= FTINY) goto dumbamb; - multcolor(aval, acol); + copycolor(aval, acol); return; } if (tracktime) /* sort to minimize thrashing */ sortambvals(0); - /* get ambient value */ + /* interpolate ambient value */ setcolor(acol, 0.0, 0.0, 0.0); d = sumambient(acol, r, nrm, rdepth, &atrunk, thescene.cuorg, thescene.cusize); if (d > FTINY) { - scalecolor(acol, 1.0/d); + d = 1.0/d; + scalecolor(acol, d); multcolor(aval, acol); return; } rdepth++; /* need to cache new value */ - d = makeambient(acol, r, aval, nrm, rdepth-1); + d = makeambient(acol, r, nrm, rdepth-1); rdepth--; if (d > FTINY) { multcolor(aval, acol); /* got new value */ @@ -351,7 +355,7 @@ sumambient( /* get interpolated ambient value */ */ if (av->lvl > al) /* list sorted, so this works */ break; - if (av->weight < r->rweight-FTINY) + if (av->weight < 0.9*r->rweight) continue; /* * Ambient radius test. @@ -430,34 +434,39 @@ sumambient( /* get interpolated ambient value */ break; } if (j == 3) - wsum += sumambient(acol, r, rn, al, at->kid+i, ck0, s); + wsum += sumambient(acol, r, rn, al, + at->kid+i, ck0, s); } return(wsum); } extern double -makeambient( /* make a new ambient value */ +makeambient( /* make a new ambient value for storage */ COLOR acol, RAY *r, - COLOR ac, FVECT rn, int al ) { AMBVAL amb; - double coef; FVECT gp, gd; - /* compute weight */ - amb.weight = pow(AVGREFL, (double)al); - coef = intens(ac)*r->rweight; - if (coef < 0.1*amb.weight) /* heuristic */ - amb.weight = coef; + int i; + + amb.weight = 1.0; /* compute weight */ + for (i = al; i-- > 0; ) + amb.weight *= AVGREFL; + if (r->rweight < 0.1*amb.weight) /* heuristic override */ + amb.weight = 1.25*r->rweight; + setcolor(acol, AVGREFL, AVGREFL, AVGREFL); /* compute ambient */ - amb.rad = doambient(acol, r, ac, amb.weight, gp, gd); - if (amb.rad <= FTINY) + amb.rad = doambient(acol, r, amb.weight, gp, gd); + if (amb.rad <= FTINY) { + setcolor(acol, 0.0, 0.0, 0.0); return(0.0); - /* store it */ + } + scalecolor(acol, 1./AVGREFL); /* undo assumed reflectance */ + /* store value */ VCOPY(amb.pos, r->rop); VCOPY(amb.dir, r->ron); amb.lvl = al; @@ -502,20 +511,20 @@ extambient( /* extrapolate value at pv, nv */ static void initambfile( /* initialize ambient file */ - int creat + int cre8 ) { extern char *progname, *octname; static char *mybuf = NULL; #ifdef F_SETLKW - aflock(creat ? F_WRLCK : F_RDLCK); + aflock(cre8 ? F_WRLCK : F_RDLCK); #endif SET_FILE_BINARY(ambfp); if (mybuf == NULL) mybuf = (char *)bmalloc(BUFSIZ+8); setbuf(ambfp, mybuf); - if (creat) { /* new file */ + if (cre8) { /* new file */ newheader("RADIANCE", ambfp); fprintf(ambfp, "%s -av %g %g %g -aw %d -ab %d -aa %g ", progname, colval(ambval,RED), @@ -524,13 +533,12 @@ initambfile( /* initialize ambient file */ fprintf(ambfp, "-ad %d -as %d -ar %d ", ambdiv, ambssamp, ambres); if (octname != NULL) - printargs(1, &octname, ambfp); - else - fputc('\n', ambfp); + fputs(octname, ambfp); + fputc('\n', ambfp); fprintf(ambfp, "SOFTWARE= %s\n", VersionID); fputnow(ambfp); fputformat(AMBFMT, ambfp); - putc('\n', ambfp); + fputc('\n', ambfp); putambmagic(ambfp); } else if (checkheader(ambfp, AMBFMT, NULL) < 0 || !hasambmagic(ambfp)) error(USER, "bad ambient file"); @@ -858,6 +866,8 @@ aflock( /* lock/unlock ambient file */ { static struct flock fls; /* static so initialized to zeroes */ + if (typ == fls.l_type) /* already called? */ + return; fls.l_type = typ; if (fcntl(fileno(ambfp), F_SETLKW, &fls) < 0) error(SYSTEM, "cannot (un)lock ambient file"); @@ -871,22 +881,20 @@ ambsync(void) /* synchronize ambient file */ AMBVAL avs; register int n; - if (nunflshed == 0) + if (ambfp == NULL) /* no ambient file? */ return(0); - if (lastpos < 0) /* initializing (locked in initambfile) */ - goto syncend; - /* gain exclusive access */ - aflock(F_WRLCK); + /* gain appropriate access */ + aflock(nunflshed ? F_WRLCK : F_RDLCK); /* see if file has grown */ if ((flen = lseek(fileno(ambfp), (off_t)0, SEEK_END)) < 0) goto seekerr; - if ( (n = flen - lastpos) ) { /* file has grown */ + if ((n = flen - lastpos) > 0) { /* file has grown */ if (ambinp == NULL) { /* use duplicate filedes */ ambinp = fdopen(dup(fileno(ambfp)), "r"); if (ambinp == NULL) error(SYSTEM, "fdopen failed in ambsync"); } - if (fseek(ambinp, lastpos, 0) < 0) + if (fseek(ambinp, lastpos, SEEK_SET) < 0) goto seekerr; while (n >= AMBVALSIZ) { /* load contributed values */ if (!readambval(&avs, ambinp)) { @@ -899,23 +907,18 @@ ambsync(void) /* synchronize ambient file */ avinsert(avstore(&avs)); n -= AMBVALSIZ; } + lastpos = flen - n; /*** seek always as safety measure if (n) ***/ /* alignment */ - if (lseek(fileno(ambfp), (off_t)(flen-n), SEEK_SET) < 0) + if (lseek(fileno(ambfp), (off_t)lastpos, SEEK_SET) < 0) goto seekerr; } -#ifdef DEBUG - if (ambfp->_ptr - ambfp->_base != nunflshed*AMBVALSIZ) { - sprintf(errmsg, "ambient file buffer at %d rather than %d", - ambfp->_ptr - ambfp->_base, - nunflshed*AMBVALSIZ); - error(CONSISTENCY, errmsg); - } -#endif -syncend: n = fflush(ambfp); /* calls write() at last */ - if ((lastpos = lseek(fileno(ambfp), (off_t)0, SEEK_CUR)) < 0) + if (n != EOF) + lastpos += (long)nunflshed*AMBVALSIZ; + else if ((lastpos = lseek(fileno(ambfp), (off_t)0, SEEK_CUR)) < 0) goto seekerr; + aflock(F_UNLCK); /* release file */ nunflshed = 0; return(n); @@ -929,7 +932,7 @@ seekerr: extern int ambsync(void) /* flush ambient file */ { - if (nunflshed == 0) + if (ambfp == NULL) return(0); nunflshed = 0; return(fflush(ambfp));