| 105 |
|
case VDB_xY: return(db2==VDB_x ? VDB_y : VDB_X); |
| 106 |
|
case VDB_Xy: return(db2==VDB_y ? VDB_x : VDB_Y); |
| 107 |
|
} |
| 108 |
< |
error(INTERNAL, "forbidden diagonal in vdb_edge()"); |
| 108 |
> |
error(CONSISTENCY, "forbidden diagonal in vdb_edge()"); |
| 109 |
|
return(-1); |
| 110 |
|
} |
| 111 |
|
|
| 225 |
|
static float * |
| 226 |
|
getambdiffs(AMBHEMI *hp) |
| 227 |
|
{ |
| 228 |
< |
float *earr = (float *)calloc(hp->ns*hp->ns, sizeof(float)); |
| 228 |
> |
float *earr = (float *)malloc(sizeof(float)*hp->ns*hp->ns); |
| 229 |
|
float *ep; |
| 230 |
|
AMBSAMP *ap; |
| 231 |
|
double b, d2; |
| 236 |
|
/* compute squared neighbor diffs */ |
| 237 |
|
for (ap = hp->sa, ep = earr, i = 0; i < hp->ns; i++) |
| 238 |
|
for (j = 0; j < hp->ns; j++, ap++, ep++) { |
| 239 |
+ |
ep[0] = FTINY; |
| 240 |
|
b = bright(ap[0].v); |
| 241 |
|
if (i) { /* from above */ |
| 242 |
|
d2 = b - bright(ap[-hp->ns].v); |
| 273 |
|
ambsupersamp(double acol[3], AMBHEMI *hp, int cnt) |
| 274 |
|
{ |
| 275 |
|
float *earr = getambdiffs(hp); |
| 276 |
< |
double e2sum = 0; |
| 276 |
> |
double e2rem = 0; |
| 277 |
|
AMBSAMP *ap; |
| 278 |
|
RAY ar; |
| 279 |
< |
COLOR asum; |
| 279 |
> |
double asum[3]; |
| 280 |
|
float *ep; |
| 281 |
|
int i, j, n; |
| 282 |
|
|
| 283 |
|
if (earr == NULL) /* just skip calc. if no memory */ |
| 284 |
|
return; |
| 285 |
< |
/* add up estimated variances */ |
| 285 |
> |
/* accumulate estimated variances */ |
| 286 |
|
for (ep = earr + hp->ns*hp->ns; ep-- > earr; ) |
| 287 |
< |
e2sum += *ep; |
| 287 |
> |
e2rem += *ep; |
| 288 |
|
ep = earr; /* perform super-sampling */ |
| 289 |
|
for (ap = hp->sa, i = 0; i < hp->ns; i++) |
| 290 |
|
for (j = 0; j < hp->ns; j++, ap++) { |
| 291 |
< |
int nss = *ep/e2sum*cnt + frandom(); |
| 292 |
< |
setcolor(asum, 0., 0., 0.); |
| 291 |
> |
int nss = *ep/e2rem*cnt + frandom(); |
| 292 |
> |
asum[0] = asum[1] = asum[2] = 0.0; |
| 293 |
|
for (n = 1; n <= nss; n++) { |
| 294 |
|
if (!getambsamp(&ar, hp, i, j, n)) { |
| 295 |
|
nss = n-1; |
| 298 |
|
addcolor(asum, ar.rcol); |
| 299 |
|
} |
| 300 |
|
if (nss) { /* update returned ambient value */ |
| 301 |
< |
const double ssf = 1./(nss + 1); |
| 301 |
> |
const double ssf = 1./(nss + 1.); |
| 302 |
|
for (n = 3; n--; ) |
| 303 |
< |
acol[n] += ssf*colval(asum,n) + |
| 303 |
> |
acol[n] += ssf*asum[n] + |
| 304 |
|
(ssf - 1.)*colval(ap->v,n); |
| 305 |
|
} |
| 306 |
< |
e2sum -= *ep++; /* update remainders */ |
| 306 |
> |
e2rem -= *ep++; /* update remainders */ |
| 307 |
|
cnt -= nss; |
| 308 |
|
} |
| 309 |
|
free(earr); |
| 538 |
|
|
| 539 |
|
|
| 540 |
|
/* Compute anisotropic radii and eigenvector directions */ |
| 541 |
< |
static int |
| 541 |
> |
static void |
| 542 |
|
eigenvectors(FVECT uv[2], float ra[2], FVECT hessian[3]) |
| 543 |
|
{ |
| 544 |
|
double hess2[2][2]; |
| 560 |
|
if (i == 1) /* double-root (circle) */ |
| 561 |
|
evalue[1] = evalue[0]; |
| 562 |
|
if (!i || ((evalue[0] = fabs(evalue[0])) <= FTINY*FTINY) | |
| 563 |
< |
((evalue[1] = fabs(evalue[1])) <= FTINY*FTINY) ) |
| 564 |
< |
error(INTERNAL, "bad eigenvalue calculation"); |
| 565 |
< |
|
| 563 |
> |
((evalue[1] = fabs(evalue[1])) <= FTINY*FTINY) ) { |
| 564 |
> |
ra[0] = ra[1] = maxarad; |
| 565 |
> |
return; |
| 566 |
> |
} |
| 567 |
|
if (evalue[0] > evalue[1]) { |
| 568 |
|
ra[0] = sqrt(sqrt(4.0/evalue[0])); |
| 569 |
|
ra[1] = sqrt(sqrt(4.0/evalue[1])); |
| 724 |
|
static uint32 |
| 725 |
|
ambcorral(AMBHEMI *hp, FVECT uv[2], const double r0, const double r1) |
| 726 |
|
{ |
| 727 |
< |
uint32 flgs = 0; |
| 728 |
< |
int i, j; |
| 729 |
< |
/* circle around perimeter */ |
| 727 |
> |
const double max_d = 1.0/(minarad*ambacc + 0.001); |
| 728 |
> |
const double ang_res = 0.5*PI/(hp->ns-1); |
| 729 |
> |
const double ang_step = ang_res/((int)(16/PI*ang_res) + (1+FTINY)); |
| 730 |
> |
double avg_d = 0; |
| 731 |
> |
uint32 flgs = 0; |
| 732 |
> |
int i, j; |
| 733 |
> |
/* don't bother for a few samples */ |
| 734 |
> |
if (hp->ns < 12) |
| 735 |
> |
return(0); |
| 736 |
> |
/* check distances overhead */ |
| 737 |
> |
for (i = hp->ns*3/4; i-- > hp->ns>>2; ) |
| 738 |
> |
for (j = hp->ns*3/4; j-- > hp->ns>>2; ) |
| 739 |
> |
avg_d += ambsam(hp,i,j).d; |
| 740 |
> |
avg_d *= 4.0/(hp->ns*hp->ns); |
| 741 |
> |
if (avg_d*r0 >= 1.0) /* ceiling too low for corral? */ |
| 742 |
> |
return(0); |
| 743 |
> |
if (avg_d >= max_d) /* insurance */ |
| 744 |
> |
return(0); |
| 745 |
> |
/* else circle around perimeter */ |
| 746 |
|
for (i = 0; i < hp->ns; i++) |
| 747 |
|
for (j = 0; j < hp->ns; j += !i|(i==hp->ns-1) ? 1 : hp->ns-1) { |
| 748 |
|
AMBSAMP *ap = &ambsam(hp,i,j); |
| 749 |
|
FVECT vec; |
| 750 |
|
double u, v; |
| 751 |
< |
double ang; |
| 751 |
> |
double ang, a1; |
| 752 |
|
int abp; |
| 753 |
< |
if (ap->d <= FTINY) |
| 754 |
< |
continue; |
| 753 |
> |
if ((ap->d <= FTINY) | (ap->d >= max_d)) |
| 754 |
> |
continue; /* too far or too near */ |
| 755 |
|
VSUB(vec, ap->p, hp->rp->rop); |
| 756 |
|
u = DOT(vec, uv[0]) * ap->d; |
| 757 |
|
v = DOT(vec, uv[1]) * ap->d; |
| 758 |
|
if ((r0*r0*u*u + r1*r1*v*v) * ap->d*ap->d <= 1.0) |
| 759 |
|
continue; /* occluder outside ellipse */ |
| 760 |
|
ang = atan2a(v, u); /* else set direction flags */ |
| 761 |
< |
ang += 2.0*PI*(ang < 0); |
| 762 |
< |
ang *= 16./PI; |
| 745 |
< |
if ((ang < .5) | (ang >= 31.5)) |
| 746 |
< |
flgs |= 0x80000001; |
| 747 |
< |
else |
| 748 |
< |
flgs |= 3L<<(int)(ang-.5); |
| 761 |
> |
for (a1 = ang-.5*ang_res; a1 <= ang+.5*ang_res; a1 += ang_step) |
| 762 |
> |
flgs |= 1L<<(int)(16/PI*(a1 + 2.*PI*(a1 < 0))); |
| 763 |
|
} |
| 764 |
|
return(flgs); |
| 765 |
|
} |
| 816 |
|
return(-1); /* return value w/o Hessian */ |
| 817 |
|
} |
| 818 |
|
cnt = ambssamp*wt + 0.5; /* perform super-sampling? */ |
| 819 |
< |
if (cnt > 0) |
| 819 |
> |
if (cnt > 8) |
| 820 |
|
ambsupersamp(acol, hp, cnt); |
| 821 |
|
copycolor(rcol, acol); /* final indirect irradiance/PI */ |
| 822 |
|
if ((ra == NULL) & (pg == NULL) & (dg == NULL)) { |
| 830 |
|
K = 1.0; |
| 831 |
|
pg = NULL; |
| 832 |
|
dg = NULL; |
| 833 |
+ |
crlp = NULL; |
| 834 |
|
} |
| 835 |
|
ap = hp->sa; /* relative Y channel from here on... */ |
| 836 |
|
for (i = hp->ns*hp->ns; i--; ap++) |
| 866 |
|
if (ra[0] > maxarad) |
| 867 |
|
ra[0] = maxarad; |
| 868 |
|
} |
| 869 |
< |
if (crlp != NULL) /* flag encroached directions */ |
| 869 |
> |
/* flag encroached directions */ |
| 870 |
> |
if ((wt >= 0.5-FTINY) & (crlp != NULL)) |
| 871 |
|
*crlp = ambcorral(hp, uv, ra[0]*ambacc, ra[1]*ambacc); |
| 872 |
|
if (pg != NULL) { /* cap gradient if necessary */ |
| 873 |
|
d = pg[0]*pg[0]*ra[0]*ra[0] + pg[1]*pg[1]*ra[1]*ra[1]; |