272 |
|
ambsupersamp(double acol[3], AMBHEMI *hp, int cnt) |
273 |
|
{ |
274 |
|
float *earr = getambdiffs(hp); |
275 |
< |
double e2sum = 0; |
275 |
> |
double e2sum = 0.0; |
276 |
|
AMBSAMP *ap; |
277 |
|
RAY ar; |
278 |
< |
COLOR asum; |
278 |
> |
double asum[3]; |
279 |
|
float *ep; |
280 |
|
int i, j, n; |
281 |
|
|
288 |
|
for (ap = hp->sa, i = 0; i < hp->ns; i++) |
289 |
|
for (j = 0; j < hp->ns; j++, ap++) { |
290 |
|
int nss = *ep/e2sum*cnt + frandom(); |
291 |
< |
setcolor(asum, 0., 0., 0.); |
291 |
> |
asum[0] = asum[1] = asum[2] = 0.0; |
292 |
|
for (n = 1; n <= nss; n++) { |
293 |
|
if (!getambsamp(&ar, hp, i, j, n)) { |
294 |
|
nss = n-1; |
299 |
|
if (nss) { /* update returned ambient value */ |
300 |
|
const double ssf = 1./(nss + 1); |
301 |
|
for (n = 3; n--; ) |
302 |
< |
acol[n] += ssf*colval(asum,n) + |
302 |
> |
acol[n] += ssf*asum[n] + |
303 |
|
(ssf - 1.)*colval(ap->v,n); |
304 |
|
} |
305 |
|
e2sum -= *ep++; /* update remainders */ |
722 |
|
static uint32 |
723 |
|
ambcorral(AMBHEMI *hp, FVECT uv[2], const double r0, const double r1) |
724 |
|
{ |
725 |
< |
uint32 flgs = 0; |
726 |
< |
int i, j; |
727 |
< |
/* circle around perimeter */ |
725 |
> |
const double max_d = 1.0/(minarad*ambacc + 0.001); |
726 |
> |
const double ang_res = 0.5*PI/(hp->ns-1); |
727 |
> |
const double ang_step = ang_res/((int)(16/PI*ang_res) + (1+FTINY)); |
728 |
> |
double avg_d = 0; |
729 |
> |
uint32 flgs = 0; |
730 |
> |
int i, j; |
731 |
> |
/* check distances above us */ |
732 |
> |
for (i = hp->ns*3/4; i-- > hp->ns>>2; ) |
733 |
> |
for (j = hp->ns*3/4; j-- > hp->ns>>2; ) |
734 |
> |
avg_d += ambsam(hp,i,j).d; |
735 |
> |
avg_d *= 4.0/(hp->ns*hp->ns); |
736 |
> |
if (avg_d >= max_d) /* too close to corral? */ |
737 |
> |
return(0); |
738 |
> |
/* else circle around perimeter */ |
739 |
|
for (i = 0; i < hp->ns; i++) |
740 |
|
for (j = 0; j < hp->ns; j += !i|(i==hp->ns-1) ? 1 : hp->ns-1) { |
741 |
|
AMBSAMP *ap = &ambsam(hp,i,j); |
742 |
|
FVECT vec; |
743 |
|
double u, v; |
744 |
< |
double ang; |
744 |
> |
double ang, a1; |
745 |
|
int abp; |
746 |
< |
if (ap->d <= FTINY) |
747 |
< |
continue; |
746 |
> |
if ((ap->d <= FTINY) | (ap->d >= max_d)) |
747 |
> |
continue; /* too far or too near */ |
748 |
|
VSUB(vec, ap->p, hp->rp->rop); |
749 |
|
u = DOT(vec, uv[0]) * ap->d; |
750 |
|
v = DOT(vec, uv[1]) * ap->d; |
751 |
|
if ((r0*r0*u*u + r1*r1*v*v) * ap->d*ap->d <= 1.0) |
752 |
|
continue; /* occluder outside ellipse */ |
753 |
|
ang = atan2a(v, u); /* else set direction flags */ |
754 |
< |
ang += 2.0*PI*(ang < 0); |
755 |
< |
ang *= 16./PI; |
745 |
< |
if ((ang < .5) | (ang >= 31.5)) |
746 |
< |
flgs |= 0x80000001; |
747 |
< |
else |
748 |
< |
flgs |= 3L<<(int)(ang-.5); |
754 |
> |
for (a1 = ang-.5*ang_res; a1 <= ang+.5*ang_res; a1 += ang_step) |
755 |
> |
flgs |= 1L<<(int)(16/PI*(a1 + 2.*PI*(a1 < 0))); |
756 |
|
} |
757 |
|
return(flgs); |
758 |
|
} |
809 |
|
return(-1); /* return value w/o Hessian */ |
810 |
|
} |
811 |
|
cnt = ambssamp*wt + 0.5; /* perform super-sampling? */ |
812 |
< |
if (cnt > 0) |
812 |
> |
if (cnt > 8) |
813 |
|
ambsupersamp(acol, hp, cnt); |
814 |
|
copycolor(rcol, acol); /* final indirect irradiance/PI */ |
815 |
|
if ((ra == NULL) & (pg == NULL) & (dg == NULL)) { |