269 |
|
ambincl != inset(ambset, r->ro->omod)) |
270 |
|
goto dumbamb; |
271 |
|
|
272 |
< |
if (ambacc <= FTINY) { /* no ambient storage */ |
273 |
< |
FVECT uvd[2]; |
272 |
> |
if (ambacc <= FTINY) { /* no ambient storage? */ |
273 |
> |
double rdot = DOT(nrm,r->ron); |
274 |
> |
int sgn = 1 - 2*(rdot < 0); |
275 |
|
float dgrad[2], *dgp = NULL; |
276 |
+ |
FVECT uvd[2]; |
277 |
|
|
278 |
< |
if (nrm != r->ron && DOT(nrm,r->ron) < 0.9999) |
278 |
> |
if (sgn*rdot < 0.9999) |
279 |
|
dgp = dgrad; /* compute rotational grad. */ |
280 |
|
copyscolor(acol, aval); |
281 |
|
rdepth++; |
282 |
< |
ok = doambient(acol, r, r->rweight, |
282 |
> |
ok = doambient(acol, r, r->rweight*sgn, |
283 |
|
uvd, NULL, NULL, dgp, NULL); |
284 |
|
rdepth--; |
285 |
|
if (!ok) |
289 |
|
VCROSS(v1, r->ron, nrm); |
290 |
|
d = 1.0; |
291 |
|
for (i = 3; i--; ) |
292 |
< |
d += v1[i] * (dgp[0]*uvd[0][i] + dgp[1]*uvd[1][i]); |
292 |
> |
d += sgn*v1[i] * (dgp[0]*uvd[0][i] + dgp[1]*uvd[1][i]); |
293 |
|
if (d >= 0.05) |
294 |
|
scalescolor(acol, d); |
295 |
|
} |
382 |
|
rtst.rmax = normalize(rtst.rdir); /* short ray test */ |
383 |
|
while (localhit(&rtst, &thescene)) { /* check for occluder */ |
384 |
|
OBJREC *m = findmaterial(rtst.ro); |
385 |
< |
if (m != NULL && !istransp(m->otype) && !isBSDFproxy(m) && |
385 |
> |
if (m != NULL && !istransp(m) && !isBSDFproxy(m) && |
386 |
|
(rtst.clipset == NULL || |
387 |
|
!inset(rtst.clipset, rtst.ro->omod))) |
388 |
|
return(1); /* plug light leak */ |
406 |
|
) |
407 |
|
{ /* initial limit is 10 degrees plus ambacc radians */ |
408 |
|
const double minangle = 10.0 * PI/180.; |
409 |
+ |
const int sgn = 1 - 2*(DOT(r->ron,rn) < 0); |
410 |
|
double maxangle = minangle + ambacc; |
411 |
|
double wsum = 0.0; |
412 |
|
FVECT ck0; |
451 |
|
* Direction test using unperturbed normal |
452 |
|
*/ |
453 |
|
decodedir(uvw[2], av->ndir); |
454 |
< |
d = DOT(uvw[2], r->ron); |
454 |
> |
d = sgn * DOT(uvw[2], r->ron); |
455 |
|
if (d <= 0.0) /* >= 90 degrees */ |
456 |
|
continue; |
457 |
|
delta_r2 = 2.0 - 2.0*d; /* approx. radians^2 */ |
507 |
|
int al |
508 |
|
) |
509 |
|
{ |
510 |
+ |
int sgn = 1 - 2*(DOT(r->ron,rn) < 0); |
511 |
|
AMBVAL amb; |
512 |
|
FVECT uvw[3]; |
513 |
|
int i; |
519 |
|
amb.weight = 1.25*r->rweight; |
520 |
|
setscolor(acol, AVGREFL, AVGREFL, AVGREFL); |
521 |
|
/* compute ambient */ |
522 |
< |
i = doambient(acol, r, amb.weight, |
522 |
> |
i = doambient(acol, r, amb.weight*sgn, |
523 |
|
uvw, amb.rad, amb.gpos, amb.gdir, &amb.corral); |
524 |
|
scalescolor(acol, 1./AVGREFL); /* undo assumed reflectance */ |
525 |
|
if (i <= 0 || amb.rad[0] <= FTINY) /* no Hessian or zero radius */ |
526 |
|
return(i); |
527 |
+ |
uvw[2][0] = sgn*r->ron[0]; /* orient unperturbed normal */ |
528 |
+ |
uvw[2][1] = sgn*r->ron[1]; |
529 |
+ |
uvw[2][2] = sgn*r->ron[2]; |
530 |
|
/* store value */ |
531 |
|
VCOPY(amb.pos, r->rop); |
532 |
< |
amb.ndir = encodedir(r->ron); |
532 |
> |
amb.ndir = encodedir(uvw[2]); |
533 |
|
amb.udir = encodedir(uvw[0]); |
534 |
|
amb.lvl = al; |
535 |
|
copyscolor(amb.val, acol); |
536 |
< |
/* insert into tree */ |
537 |
< |
avsave(&amb); /* and save to file */ |
531 |
< |
if (rn != r->ron) { /* texture */ |
532 |
< |
VCOPY(uvw[2], r->ron); |
536 |
> |
avsave(&amb); /* insert and save to file */ |
537 |
> |
if (DOT(uvw[2],rn) < 0.9999) /* texture? */ |
538 |
|
extambient(acol, &amb, r->rop, rn, uvw); |
534 |
– |
} |
539 |
|
return(1); |
540 |
|
} |
541 |
|
|
638 |
|
if (mybuf == NULL) |
639 |
|
mybuf = (char *)bmalloc(BUFSIZ+8); |
640 |
|
setbuf(ambfp, mybuf); |
641 |
+ |
retry: |
642 |
|
if (cre8) { /* new file */ |
643 |
|
newheader("RADIANCE", ambfp); |
644 |
|
fprintf(ambfp, "%s -av %g %g %g -aw %d -ab %d -aa %g ", |
651 |
|
srcsizerat, shadthresh, shadcert); |
652 |
|
fprintf(ambfp, "-ss %g -st %g -lr %d -lw %g ", specjitter, |
653 |
|
specthresh, maxdepth, minweight); |
654 |
< |
fprintf(ambfp, "-cw %f %f -cs %d ", WLPART[3], WLPART[0], NCSAMP); |
654 |
> |
fprintf(ambfp, "-cw %g %g -cs %d ", WLPART[3], WLPART[0], NCSAMP); |
655 |
|
if (octname != NULL) |
656 |
|
fputs(octname, ambfp); |
657 |
< |
fputc('\n', ambfp); |
657 |
> |
fputc('\n', ambfp); /* end of command line, not header! */ |
658 |
|
fprintf(ambfp, "SOFTWARE= %s\n", VersionID); |
659 |
|
fputnow(ambfp); |
660 |
+ |
AMB_CNDX = CNDX; /* use current spectral sampling */ |
661 |
+ |
AMB_WLPART = WLPART; |
662 |
|
fputwlsplit(WLPART, ambfp); |
663 |
|
fputncomp(NCSAMP, ambfp); |
664 |
|
fputformat(AMBFMT, ambfp); |
665 |
|
fputc('\n', ambfp); |
666 |
|
putambmagic(ambfp); |
667 |
< |
} else if (getheader(ambfp, amb_headline, NULL) < 0 || !hasambmagic(ambfp)) |
667 |
> |
} else if (getheader(ambfp, amb_headline, NULL) < 0 || !hasambmagic(ambfp)) { |
668 |
> |
#ifndef F_SETLKW |
669 |
> |
static int ntries = 3; |
670 |
> |
if (--ntries > 0 && ftell(ambfp) == 0) { |
671 |
> |
clearerr(ambfp); |
672 |
> |
sleep(2); |
673 |
> |
goto retry; |
674 |
> |
} |
675 |
> |
#endif |
676 |
|
error(USER, "bad/incompatible ambient file"); |
677 |
< |
|
677 |
> |
} |
678 |
|
if ((AMB_CNDX != CNDX) | (AMB_WLPART != WLPART)) { |
679 |
|
if (setspectrsamp(AMB_CNDX, AMB_WLPART) < 0) |
680 |
|
error(USER, "bad wavelength sampling in ambient file"); |