--- ray/src/rt/ambient.c 2004/03/30 16:13:00 2.56 +++ ray/src/rt/ambient.c 2007/09/14 00:50:31 2.64 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: ambient.c,v 2.56 2004/03/30 16:13:00 schorsch Exp $"; +static const char RCSid[] = "$Id: ambient.c,v 2.64 2007/09/14 00:50:31 greg Exp $"; #endif /* * ambient.c - routines dealing with ambient (inter-reflected) component. @@ -24,7 +24,9 @@ static const char RCSid[] = "$Id: ambient.c,v 2.56 200 extern char *shm_boundary; /* memory sharing boundary */ -#define MAXASET 511 /* maximum number of elements in ambient set */ +#ifndef MAXASET +#define MAXASET 2047 /* maximum number of elements in ambient set */ +#endif OBJECT ambset[MAXASET+1]={0}; /* ambient include/exclude set */ double maxarad; /* maximum ambient radius */ @@ -190,8 +192,7 @@ setambient(void) /* initialize calculation */ sprintf(errmsg, "cannot open ambient file \"%s\"", ambfile); error(SYSTEM, errmsg); } - nunflshed++; /* lie */ - ambsync(); + ambsync(); /* load previous values */ } @@ -252,13 +253,14 @@ ambnotify( /* record new modifier */ extern void -ambient( /* compute ambient component for ray */ - COLOR acol, +multambient( /* compute ambient component & multiply by coef. */ + COLOR aval, register RAY *r, FVECT nrm ) { static int rdepth = 0; /* ambient recursion */ + COLOR acol; double d, l; if (ambdiv <= 0) /* no ambient calculation */ @@ -272,42 +274,50 @@ ambient( /* compute ambient component for ray */ goto dumbamb; if (ambacc <= FTINY) { /* no ambient storage */ + copycolor(acol, aval); rdepth++; d = doambient(acol, r, r->rweight, NULL, NULL); rdepth--; if (d <= FTINY) goto dumbamb; + 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, nrm, rdepth-1); rdepth--; - if (d > FTINY) + if (d > FTINY) { + multcolor(aval, acol); /* got new value */ return; + } dumbamb: /* return global value */ - copycolor(acol, ambval); - if ((ambvwt <= 0) | (navsum == 0)) + if ((ambvwt <= 0) | (navsum == 0)) { + multcolor(aval, ambval); return; + } l = bright(ambval); /* average in computations */ if (l > FTINY) { d = (log(l)*(double)ambvwt + avsum) / (double)(ambvwt + navsum); d = exp(d) / l; - scalecolor(acol, d); /* apply color of ambval */ + scalecolor(aval, d); + multcolor(aval, ambval); /* apply color of ambval */ } else { d = exp( avsum / (double)navsum ); - setcolor(acol, d, d, d); /* neutral color */ + scalecolor(aval, d); /* neutral color */ } } @@ -341,7 +351,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. @@ -420,31 +430,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, - register RAY *r, + RAY *r, FVECT rn, int al ) { AMBVAL amb; FVECT gp, gd; - /* compute weight */ - amb.weight = pow(AVGREFL, (double)al); - if (r->rweight < 0.1*amb.weight) /* heuristic */ - amb.weight = r->rweight; + 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, amb.weight, gp, gd); - if (amb.rad <= FTINY) + 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; @@ -858,12 +876,10 @@ ambsync(void) /* synchronize ambient file */ AMBVAL avs; register int n; - if (nunflshed == 0) - 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; @@ -886,9 +902,10 @@ 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 @@ -901,8 +918,11 @@ ambsync(void) /* synchronize ambient file */ #endif syncend: n = fflush(ambfp); /* calls write() at last */ - if ((lastpos = lseek(fileno(ambfp), (off_t)0, SEEK_CUR)) < 0) - goto seekerr; + if (n == EOF) { + if ((lastpos = lseek(fileno(ambfp), (off_t)0, SEEK_CUR)) < 0) + goto seekerr; + } else + lastpos += (long)nunflshed*AMBVALSIZ; aflock(F_UNLCK); /* release file */ nunflshed = 0; return(n); @@ -916,8 +936,6 @@ seekerr: extern int ambsync(void) /* flush ambient file */ { - if (nunflshed == 0) - return(0); nunflshed = 0; return(fflush(ambfp)); }