--- ray/src/rt/ambient.c 1995/10/24 13:33:23 2.33 +++ ray/src/rt/ambient.c 1996/07/09 13:32:35 2.38 @@ -1,4 +1,4 @@ -/* Copyright (c) 1995 Regents of the University of California */ +/* Copyright (c) 1996 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -21,9 +21,6 @@ static char SCCSid[] = "$SunId$ LBL"; #ifndef OCTSCALE #define OCTSCALE 1.0 /* ceil((valid rad.)/(cube size)) */ #endif -#ifndef AMBVWT -#define AMBVWT 250 /* relative ambient value weight (# calcs) */ -#endif typedef struct ambtree { AMBVAL *alist; /* ambient value list */ @@ -60,7 +57,8 @@ static int nunflshed = 0; /* number of unflushed ambi #endif static COLOR avsum = BLKCOLOR; /* computed ambient value sum */ -static unsigned int nambvals = 0; /* number of computed ambient values */ +static unsigned int nambvals = 0; /* total number of indirect values */ +static unsigned int nambshare = 0; /* number of values from file */ static unsigned long ambclock = 0; /* ambient access clock */ static unsigned long lastsort = 0; /* time of last value sort */ static long sortintvl = SORT_INTVL; /* time until next sort */ @@ -69,9 +67,10 @@ static long sortintvl = SORT_INTVL; /* time until nex /* * Track access times unless we are sharing ambient values * through memory on a multiprocessor, when we want to avoid - * claiming our own memory (copy on write). + * claiming our own memory (copy on write). Go ahead anyway + * if more than two thirds of our values are unshared. */ -#define tracktime (shm_boundary == NULL || ambfp == NULL) +#define tracktime (shm_boundary == NULL || nambvals > 3*nambshare) #define AMBFLUSH (BUFSIZ/AMBVALSIZ) @@ -122,7 +121,7 @@ double newa; setambient(afile) /* initialize calculation */ char *afile; { - long headlen; + long pos, flen; AMBVAL amb; /* init ambient limits */ setambres(ambres); @@ -138,11 +137,20 @@ char *afile; /* open ambient file */ if ((ambfp = fopen(afile, "r+")) != NULL) { initambfile(0); - headlen = ftell(ambfp); + pos = ftell(ambfp); while (readambval(&amb, ambfp)) avinsert(avstore(&amb)); /* align */ - fseek(ambfp, -((ftell(ambfp)-headlen)%AMBVALSIZ), 1); + pos += (long)nambvals*AMBVALSIZ; + flen = lseek(fileno(ambfp), 0L, 2); + if (flen != pos) { + error(WARNING, + "ignoring last %ld values in ambient file (corrupted)", + (flen - pos)/AMBVALSIZ); + fseek(ambfp, pos, 0); + ftruncate(fileno(ambfp), pos); + } + nambshare = nambvals; } else if ((ambfp = fopen(afile, "w+")) != NULL) initambfile(1); else { @@ -176,9 +184,10 @@ OBJECT obj; } -ambient(acol, r) /* compute ambient component for ray */ +ambient(acol, r, nrm) /* compute ambient component for ray */ COLOR acol; register RAY *r; +FVECT nrm; { static int rdepth = 0; /* ambient recursion */ double d; @@ -205,34 +214,33 @@ register RAY *r; sortambvals(0); /* get ambient value */ setcolor(acol, 0.0, 0.0, 0.0); - d = sumambient(acol, r, rdepth, + d = sumambient(acol, r, nrm, rdepth, &atrunk, thescene.cuorg, thescene.cusize); if (d > FTINY) { scalecolor(acol, 1.0/d); return; } rdepth++; /* need to cache new value */ - d = makeambient(acol, r, rdepth-1); + d = makeambient(acol, r, nrm, rdepth-1); rdepth--; if (d > FTINY) return; dumbamb: /* return global value */ copycolor(acol, ambval); -#if AMBVWT - if (nambvals == 0) + if (ambvwt <= 0 | nambvals == 0) return; - scalecolor(acol, (double)AMBVWT); + scalecolor(acol, (double)ambvwt); addcolor(acol, avsum); /* average in computations */ - d = 1.0/(AMBVWT+nambvals); + d = 1.0/(ambvwt+nambvals); scalecolor(acol, d); -#endif } double -sumambient(acol, r, al, at, c0, s) /* get interpolated ambient value */ +sumambient(acol, r, rn, al, at, c0, s) /* get interpolated ambient value */ COLOR acol; register RAY *r; +FVECT rn; int al; AMBTREE *at; FVECT c0; @@ -296,7 +304,7 @@ double s; else wt = 1.0 / wt; wsum += wt; - extambient(ct, av, r->rop, r->ron); + extambient(ct, av, r->rop, rn); scalecolor(ct, wt); addcolor(acol, ct); } @@ -315,16 +323,17 @@ double s; break; } if (j == 3) - wsum += sumambient(acol, r, al, at->kid+i, ck0, s); + wsum += sumambient(acol, r, rn, al, at->kid+i, ck0, s); } return(wsum); } double -makeambient(acol, r, al) /* make a new ambient value */ +makeambient(acol, r, rn, al) /* make a new ambient value */ COLOR acol; register RAY *r; +FVECT rn; int al; { AMBVAL amb; @@ -346,6 +355,8 @@ int al; VCOPY(amb.gdir, gd); /* insert into tree */ avsave(&amb); /* and save to file */ + if (rn != r->ron) + extambient(acol, &amb, r->rop, rn); /* texture */ return(amb.rad); } @@ -561,7 +572,8 @@ static int alatcmp(avp1, avp2) /* compare ambient values for MRA */ AMBVAL **avp1, **avp2; { - return((**avp2).latick - (**avp1).latick); + register long lc = (**avp2).latick - (**avp1).latick; + return(lc<0 ? -1 : lc>0 ? 1 : 0); } @@ -573,7 +585,7 @@ AMBVAL **avp1, **avp2; } -#ifdef DEBUG +#if 1 static int avlmemi(avaddr) /* find list position from address */ AMBVAL *avaddr; @@ -728,7 +740,13 @@ ambsync() /* synchronize ambient file */ if (fseek(ambinp, lastpos, 0) < 0) goto seekerr; while (n >= AMBVALSIZ) { /* load contributed values */ - readambval(&avs, ambinp); + if (!readambval(&avs, ambinp)) { + sprintf(errmsg, + "ambient file corrupted near character %ld", + flen - n); + error(WARNING, errmsg); + break; + } avinsert(avstore(&avs)); n -= AMBVALSIZ; }