--- ray/src/rt/ambcomp.c 2014/05/07 16:02:26 2.50 +++ ray/src/rt/ambcomp.c 2014/05/09 04:55:19 2.54 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: ambcomp.c,v 2.50 2014/05/07 16:02:26 greg Exp $"; +static const char RCSid[] = "$Id: ambcomp.c,v 2.54 2014/05/09 04:55:19 greg Exp $"; #endif /* * Routines to compute "ambient" values using Monte Carlo @@ -105,7 +105,7 @@ vdb_edge(int db1, int db2) case VDB_xY: return(db2==VDB_x ? VDB_y : VDB_X); case VDB_Xy: return(db2==VDB_y ? VDB_x : VDB_Y); } - error(INTERNAL, "forbidden diagonal in vdb_edge()"); + error(CONSISTENCY, "forbidden diagonal in vdb_edge()"); return(-1); } @@ -225,7 +225,7 @@ ambsample( /* initial ambient division sample */ static float * getambdiffs(AMBHEMI *hp) { - float *earr = (float *)calloc(hp->ns*hp->ns, sizeof(float)); + float *earr = (float *)malloc(sizeof(float)*hp->ns*hp->ns); float *ep; AMBSAMP *ap; double b, d2; @@ -236,6 +236,7 @@ getambdiffs(AMBHEMI *hp) /* compute squared neighbor diffs */ for (ap = hp->sa, ep = earr, i = 0; i < hp->ns; i++) for (j = 0; j < hp->ns; j++, ap++, ep++) { + ep[0] = FTINY; b = bright(ap[0].v); if (i) { /* from above */ d2 = b - bright(ap[-hp->ns].v); @@ -272,7 +273,7 @@ static void ambsupersamp(double acol[3], AMBHEMI *hp, int cnt) { float *earr = getambdiffs(hp); - double e2sum = 0.0; + double e2rem = 0; AMBSAMP *ap; RAY ar; double asum[3]; @@ -281,13 +282,13 @@ ambsupersamp(double acol[3], AMBHEMI *hp, int cnt) if (earr == NULL) /* just skip calc. if no memory */ return; - /* add up estimated variances */ + /* accumulate estimated variances */ for (ep = earr + hp->ns*hp->ns; ep-- > earr; ) - e2sum += *ep; + e2rem += *ep; ep = earr; /* perform super-sampling */ for (ap = hp->sa, i = 0; i < hp->ns; i++) for (j = 0; j < hp->ns; j++, ap++) { - int nss = *ep/e2sum*cnt + frandom(); + int nss = *ep/e2rem*cnt + frandom(); asum[0] = asum[1] = asum[2] = 0.0; for (n = 1; n <= nss; n++) { if (!getambsamp(&ar, hp, i, j, n)) { @@ -297,12 +298,12 @@ ambsupersamp(double acol[3], AMBHEMI *hp, int cnt) addcolor(asum, ar.rcol); } if (nss) { /* update returned ambient value */ - const double ssf = 1./(nss + 1); + const double ssf = 1./(nss + 1.); for (n = 3; n--; ) acol[n] += ssf*asum[n] + (ssf - 1.)*colval(ap->v,n); } - e2sum -= *ep++; /* update remainders */ + e2rem -= *ep++; /* update remainders */ cnt -= nss; } free(earr); @@ -537,7 +538,7 @@ add2gradient(FVECT grad, FVECT egrad1, FVECT egrad2, F /* Compute anisotropic radii and eigenvector directions */ -static int +static void eigenvectors(FVECT uv[2], float ra[2], FVECT hessian[3]) { double hess2[2][2]; @@ -559,9 +560,10 @@ eigenvectors(FVECT uv[2], float ra[2], FVECT hessian[3 if (i == 1) /* double-root (circle) */ evalue[1] = evalue[0]; if (!i || ((evalue[0] = fabs(evalue[0])) <= FTINY*FTINY) | - ((evalue[1] = fabs(evalue[1])) <= FTINY*FTINY) ) - error(INTERNAL, "bad eigenvalue calculation"); - + ((evalue[1] = fabs(evalue[1])) <= FTINY*FTINY) ) { + ra[0] = ra[1] = maxarad; + return; + } if (evalue[0] > evalue[1]) { ra[0] = sqrt(sqrt(4.0/evalue[0])); ra[1] = sqrt(sqrt(4.0/evalue[1])); @@ -725,9 +727,22 @@ ambcorral(AMBHEMI *hp, FVECT uv[2], const double r0, c const double max_d = 1.0/(minarad*ambacc + 0.001); const double ang_res = 0.5*PI/(hp->ns-1); const double ang_step = ang_res/((int)(16/PI*ang_res) + (1+FTINY)); + double avg_d = 0; uint32 flgs = 0; int i, j; - /* circle around perimeter */ + /* don't bother for a few samples */ + if (hp->ns < 12) + return(0); + /* check distances overhead */ + for (i = hp->ns*3/4; i-- > hp->ns>>2; ) + for (j = hp->ns*3/4; j-- > hp->ns>>2; ) + avg_d += ambsam(hp,i,j).d; + avg_d *= 4.0/(hp->ns*hp->ns); + if (avg_d*r0 >= 1.0) /* ceiling too low for corral? */ + return(0); + if (avg_d >= max_d) /* insurance */ + return(0); + /* else circle around perimeter */ for (i = 0; i < hp->ns; i++) for (j = 0; j < hp->ns; j += !i|(i==hp->ns-1) ? 1 : hp->ns-1) { AMBSAMP *ap = &ambsam(hp,i,j); @@ -815,6 +830,7 @@ doambient( /* compute ambient component */ K = 1.0; pg = NULL; dg = NULL; + crlp = NULL; } ap = hp->sa; /* relative Y channel from here on... */ for (i = hp->ns*hp->ns; i--; ap++) @@ -850,7 +866,8 @@ doambient( /* compute ambient component */ if (ra[0] > maxarad) ra[0] = maxarad; } - if (crlp != NULL) /* flag encroached directions */ + /* flag encroached directions */ + if ((wt >= 0.5-FTINY) & (crlp != NULL)) *crlp = ambcorral(hp, uv, ra[0]*ambacc, ra[1]*ambacc); if (pg != NULL) { /* cap gradient if necessary */ d = pg[0]*pg[0]*ra[0]*ra[0] + pg[1]*pg[1]*ra[1]*ra[1];