--- ray/src/rt/ambient.c 2023/11/15 18:02:52 2.118 +++ ray/src/rt/ambient.c 2025/01/23 22:03:08 2.131 @@ -1,4 +1,4 @@ -static const char RCSid[] = "$Id: ambient.c,v 2.118 2023/11/15 18:02:52 greg Exp $"; +static const char RCSid[] = "$Id: ambient.c,v 2.131 2025/01/23 22:03:08 greg Exp $"; /* * ambient.c - routines dealing with ambient (inter-reflected) component. * @@ -33,14 +33,13 @@ double minarad; /* minimum ambient radius */ static AMBTREE atrunk; /* our ambient trunk node */ static FILE *ambfp = NULL; /* ambient file pointer */ -static int nunflshed = 0; /* number of unflushed ambient values */ +static int nunflshed; /* number of unflushed ambient values */ static double avsum = 0.; /* computed ambient value sum (log) */ static unsigned int navsum = 0; /* number of values in avsum */ static unsigned int nambvals = 0; /* total number of indirect values */ -static unsigned int nambshare = 0; /* number of values from file */ static FILE *ambinp = NULL; /* auxiliary file for input */ -static long lastpos = -1; /* last flush position */ +static off_t lastpos = -1; /* last flush position */ #define AMBFLUSH (BUFSIZ/AMBVALSIZ) @@ -117,7 +116,7 @@ void setambient(void) /* initialize calculation */ { int readonly = 0; - long flen; + off_t flen; AMBVAL amb; /* make sure we're fresh */ ambdone(); @@ -137,10 +136,9 @@ setambient(void) /* initialize calculation */ readonly = (ambfp = fopen(ambfile, "r")) != NULL; if (ambfp != NULL) { initambfile(0); /* file exists */ - lastpos = ftell(ambfp); + lastpos = ftello(ambfp); while (readambval(&amb, ambfp)) avstore(&amb); - nambshare = nambvals; /* share loaded values */ if (readonly) { sprintf(errmsg, "loaded %u values from read-only ambient file", @@ -151,20 +149,20 @@ setambient(void) /* initialize calculation */ return; /* avoid ambsync() */ } /* align file pointer */ - lastpos += (long)nambvals*AMBVALSIZ; - flen = lseek(fileno(ambfp), (off_t)0, SEEK_END); + lastpos += (off_t)nambvals*AMBVALSIZ; + flen = lseek(fileno(ambfp), 0, SEEK_END); if (flen != lastpos) { sprintf(errmsg, "ignoring last %ld values in ambient file (corrupted)", (flen - lastpos)/AMBVALSIZ); error(WARNING, errmsg); - fseek(ambfp, lastpos, SEEK_SET); - ftruncate(fileno(ambfp), (off_t)lastpos); + fseeko(ambfp, lastpos, SEEK_SET); + ftruncate(fileno(ambfp), lastpos); } } else if ((ambfp = fopen(ambfile, "w+")) != NULL) { initambfile(1); /* else create new file */ fflush(ambfp); - lastpos = ftell(ambfp); + lastpos = ftello(ambfp); } else { sprintf(errmsg, "cannot open ambient file \"%s\"", ambfile); error(SYSTEM, errmsg); @@ -194,7 +192,6 @@ ambdone(void) /* close ambient file and free memory avsum = 0.; navsum = 0; nambvals = 0; - nambshare = 0; } @@ -269,15 +266,17 @@ multambient( /* compute ambient component & multiply ambincl != inset(ambset, r->ro->omod)) goto dumbamb; - if (ambacc <= FTINY) { /* no ambient storage */ - FVECT uvd[2]; + if (ambacc <= FTINY) { /* no ambient storage? */ + double rdot = DOT(nrm,r->ron); + int sgn = 1 - 2*(rdot < 0); float dgrad[2], *dgp = NULL; + FVECT uvd[2]; - if (nrm != r->ron && DOT(nrm,r->ron) < 0.9999) + if (sgn*rdot < 0.9999) dgp = dgrad; /* compute rotational grad. */ copyscolor(acol, aval); rdepth++; - ok = doambient(acol, r, r->rweight, + ok = doambient(acol, r, r->rweight*sgn, uvd, NULL, NULL, dgp, NULL); rdepth--; if (!ok) @@ -287,7 +286,7 @@ multambient( /* compute ambient component & multiply VCROSS(v1, r->ron, nrm); d = 1.0; for (i = 3; i--; ) - d += v1[i] * (dgp[0]*uvd[0][i] + dgp[1]*uvd[1][i]); + d += sgn*v1[i] * (dgp[0]*uvd[0][i] + dgp[1]*uvd[1][i]); if (d >= 0.05) scalescolor(acol, d); } @@ -380,7 +379,7 @@ plugaleak(RAY *r, AMBVAL *ap, FVECT anorm, double ang) rtst.rmax = normalize(rtst.rdir); /* short ray test */ while (localhit(&rtst, &thescene)) { /* check for occluder */ OBJREC *m = findmaterial(rtst.ro); - if (m != NULL && !istransp(m->otype) && !isBSDFproxy(m) && + if (m != NULL && !istransp(m) && !isBSDFproxy(m) && (rtst.clipset == NULL || !inset(rtst.clipset, rtst.ro->omod))) return(1); /* plug light leak */ @@ -404,6 +403,7 @@ sumambient( /* get interpolated ambient value */ ) { /* initial limit is 10 degrees plus ambacc radians */ const double minangle = 10.0 * PI/180.; + const int sgn = 1 - 2*(DOT(r->ron,rn) < 0); double maxangle = minangle + ambacc; double wsum = 0.0; FVECT ck0; @@ -448,7 +448,7 @@ sumambient( /* get interpolated ambient value */ * Direction test using unperturbed normal */ decodedir(uvw[2], av->ndir); - d = DOT(uvw[2], r->ron); + d = sgn * DOT(uvw[2], r->ron); if (d <= 0.0) /* >= 90 degrees */ continue; delta_r2 = 2.0 - 2.0*d; /* approx. radians^2 */ @@ -504,6 +504,7 @@ makeambient( /* make a new ambient value for storage int al ) { + int sgn = 1 - 2*(DOT(r->ron,rn) < 0); AMBVAL amb; FVECT uvw[3]; int i; @@ -515,23 +516,23 @@ makeambient( /* make a new ambient value for storage amb.weight = 1.25*r->rweight; setscolor(acol, AVGREFL, AVGREFL, AVGREFL); /* compute ambient */ - i = doambient(acol, r, amb.weight, + i = doambient(acol, r, amb.weight*sgn, uvw, amb.rad, amb.gpos, amb.gdir, &amb.corral); scalescolor(acol, 1./AVGREFL); /* undo assumed reflectance */ if (i <= 0 || amb.rad[0] <= FTINY) /* no Hessian or zero radius */ return(i); + uvw[2][0] = sgn*r->ron[0]; /* orient unperturbed normal */ + uvw[2][1] = sgn*r->ron[1]; + uvw[2][2] = sgn*r->ron[2]; /* store value */ VCOPY(amb.pos, r->rop); - amb.ndir = encodedir(r->ron); + amb.ndir = encodedir(uvw[2]); amb.udir = encodedir(uvw[0]); amb.lvl = al; copyscolor(amb.val, acol); - /* insert into tree */ - avsave(&amb); /* and save to file */ - if (rn != r->ron) { /* texture */ - VCOPY(uvw[2], r->ron); + avsave(&amb); /* insert and save to file */ + if (DOT(uvw[2],rn) < 0.9999) /* texture? */ extambient(acol, &amb, r->rop, rn, uvw); - } return(1); } @@ -626,7 +627,10 @@ initambfile( /* initialize ambient file */ { extern char *progname, *octname; static char *mybuf = NULL; + int ntries = 3; + if (!AMBFLUSH) + error(INTERNAL, "BUFSIZ too small in initambfile"); #ifdef F_SETLKW aflock(cre8 ? F_WRLCK : F_RDLCK); #endif @@ -634,6 +638,8 @@ initambfile( /* initialize ambient file */ if (mybuf == NULL) mybuf = (char *)bmalloc(BUFSIZ+8); setbuf(ambfp, mybuf); + nunflshed = 0; +retry: if (cre8) { /* new file */ newheader("RADIANCE", ambfp); fprintf(ambfp, "%s -av %g %g %g -aw %d -ab %d -aa %g ", @@ -646,20 +652,34 @@ initambfile( /* initialize ambient file */ srcsizerat, shadthresh, shadcert); fprintf(ambfp, "-ss %g -st %g -lr %d -lw %g ", specjitter, specthresh, maxdepth, minweight); - fprintf(ambfp, "-cw %f %f -cs %d ", WLPART[3], WLPART[0], NCSAMP); + fprintf(ambfp, "-cw %g %g -cs %d ", WLPART[3], WLPART[0], NCSAMP); if (octname != NULL) fputs(octname, ambfp); - fputc('\n', ambfp); + fputc('\n', ambfp); /* end of command line, not header! */ fprintf(ambfp, "SOFTWARE= %s\n", VersionID); fputnow(ambfp); + AMB_CNDX = CNDX; /* use current spectral sampling */ + AMB_WLPART = WLPART; fputwlsplit(WLPART, ambfp); fputncomp(NCSAMP, ambfp); fputformat(AMBFMT, ambfp); fputc('\n', ambfp); putambmagic(ambfp); - } else if (getheader(ambfp, amb_headline, NULL) < 0 || !hasambmagic(ambfp)) + } else if (getheader(ambfp, amb_headline, NULL) < 0 || !hasambmagic(ambfp)) { + if (--ntries > 0 && ftell(ambfp) == 0) { +#ifdef F_SETLKW + aflock(F_UNLCK); + clearerr(ambfp); + sleep(2); + aflock(F_RDLCK); +#else + clearerr(ambfp); + sleep(2); +#endif + goto retry; + } error(USER, "bad/incompatible ambient file"); - + } if ((AMB_CNDX != CNDX) | (AMB_WLPART != WLPART)) { if (setspectrsamp(AMB_CNDX, AMB_WLPART) < 0) error(USER, "bad wavelength sampling in ambient file"); @@ -818,7 +838,7 @@ aflock( /* lock/unlock ambient file */ int ambsync(void) /* synchronize ambient file */ { - long flen; + off_t flen; AMBVAL avs; int n; @@ -827,7 +847,7 @@ ambsync(void) /* synchronize ambient file */ /* 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) + if ((flen = lseek(fileno(ambfp), 0, SEEK_END)) < 0) goto seekerr; if ((n = flen - lastpos) > 0) { /* file has grown */ if (ambinp == NULL) { /* get new file pointer */ @@ -835,7 +855,7 @@ ambsync(void) /* synchronize ambient file */ if (ambinp == NULL) error(SYSTEM, "fopen failed in ambsync"); } - if (fseek(ambinp, lastpos, SEEK_SET) < 0) + if (fseeko(ambinp, lastpos, SEEK_SET) < 0) goto seekerr; while (n >= AMBVALSIZ) { /* load contributed values */ if (!readambval(&avs, ambinp)) { @@ -849,11 +869,11 @@ ambsync(void) /* synchronize ambient file */ n -= AMBVALSIZ; } lastpos = flen - n; /* check alignment */ - if (n && lseek(fileno(ambfp), (off_t)lastpos, SEEK_SET) < 0) + if (n && lseek(fileno(ambfp), lastpos, SEEK_SET) < 0) goto seekerr; } n = fflush(ambfp); /* calls write() at last */ - lastpos += (long)nunflshed*AMBVALSIZ; + lastpos += (off_t)nunflshed*AMBVALSIZ; aflock(F_UNLCK); /* release file */ nunflshed = 0; return(n);