--- ray/src/rt/ambient.c 1990/06/26 09:00:07 1.10 +++ ray/src/rt/ambient.c 1991/06/06 10:48:50 1.13 @@ -34,14 +34,19 @@ extern int ambounce; /* number of ambient bounces */ extern char *amblist[]; /* ambient include/exclude list */ extern int ambincl; /* include == 1, exclude == 0 */ -OBJECT ambset[256]={0}; /* ambient include/exclude set */ +#define MAXASET 511 /* maximum number of elements in ambient set */ +OBJECT ambset[MAXASET+1]={0}; /* ambient include/exclude set */ double maxarad; /* maximum ambient radius */ double minarad; /* minimum ambient radius */ +/* + * Since we've defined our vectors as float below to save space, + * watch out for changes in the definitions of VCOPY() and DOT(). + */ typedef struct ambval { - FVECT pos; /* position in space */ - FVECT dir; /* normal direction */ + float pos[3]; /* position in space */ + float dir[3]; /* normal direction */ int lvl; /* recursion level of parent ray */ float weight; /* weight of parent ray */ COLOR val; /* computed ambient value */ @@ -101,13 +106,19 @@ char *afile; ambnotify(obj) /* record new modifier */ OBJECT obj; { + static int hitlimit = 0; register OBJREC *o = objptr(obj); register char **amblp; - if (!ismodifier(o->otype)) + if (hitlimit || !ismodifier(o->otype)) return; for (amblp = amblist; *amblp != NULL; amblp++) if (!strcmp(o->oname, *amblp)) { + if (ambset[0] >= MAXASET) { + error(WARNING, "too many modifiers in ambient list"); + hitlimit++; + return; /* should this be fatal? */ + } insertelem(ambset, obj); return; } @@ -202,7 +213,7 @@ double s; for (j = 0; j < 3; j++) d += (r->rop[j] - av->pos[j]) * (av->dir[j] + r->ron[j]); - if (d < -minarad) + if (d*0.5 < -minarad*ambacc) continue; /* * Jittering final test reduces image artifacts. @@ -271,6 +282,7 @@ register RAY *r; { extern int ambcmp(); extern double sin(), cos(), sqrt(); + int hlist[4]; double phi, xd, yd, zd; double b, b2; register AMBSAMP *div; @@ -295,7 +307,8 @@ register RAY *r; div = (AMBSAMP *)malloc(ndivs*sizeof(AMBSAMP)); if (div == NULL) error(SYSTEM, "out of memory in doambient"); - } + } else + div = NULL; /* make axes */ uy[0] = uy[1] = uy[2] = 0.0; for (k = 0; k < 3; k++) @@ -305,23 +318,31 @@ register RAY *r; fcross(ux, r->ron, uy); normalize(ux); fcross(uy, ux, r->ron); + /* set up urand */ + hlist[0] = r->rno; /* sample divisions */ arad = 0.0; ne = 0; - for (i = 0; i < nt; i++) + for (i = 0; i < nt; i++) { + hlist[1] = i; for (j = 0; j < np; j++) { rayorigin(&ar, r, AMBIENT, 0.5); /* pretested */ - zd = sqrt((i+frandom())/nt); - phi = 2.0*PI * (j+frandom())/np; + hlist[2] = j; + hlist[3] = 0; + zd = sqrt((i+urand(ilhash(hlist,4)))/nt); + hlist[3] = 1; + phi = 2.0*PI * (j+urand(ilhash(hlist,4)))/np; xd = cos(phi) * zd; yd = sin(phi) * zd; zd = sqrt(1.0 - zd*zd); for (k = 0; k < 3; k++) ar.rdir[k] = xd*ux[k]+yd*uy[k]+zd*r->ron[k]; + dimlist[ndims++] = i*np + j + 38813; rayvalue(&ar); + ndims--; if (ar.rot < FHUGE) arad += 1.0 / ar.rot; - if (ns > 0) { /* save division */ + if (div != NULL) { /* save division */ div[ne].k = 0.0; copycolor(div[ne].v, ar.rcol); div[ne].n = 0; @@ -356,6 +377,7 @@ register RAY *r; } else addcolor(acol, ar.rcol); } + } for (k = 0; k < ne; k++) { /* compute errors */ if (div[k].n > 1) div[k].k /= div[k].n; @@ -371,14 +393,21 @@ register RAY *r; /* super-sample */ for (i = ns; i > 0; i--) { rayorigin(&ar, r, AMBIENT, 0.5); /* pretested */ - zd = sqrt((div[0].t+frandom())/nt); - phi = 2.0*PI * (div[0].p+frandom())/np; + hlist[1] = div[0].t; + hlist[2] = div[0].p; + hlist[3] = 0; + zd = sqrt((div[0].t+urand(ilhash(hlist,4)+div[0].n))/nt); + hlist[3] = 1; + phi = 2.0*PI * (div[0].p+urand(ilhash(hlist,4)+div[0].n))/np; xd = cos(phi) * zd; yd = sin(phi) * zd; zd = sqrt(1.0 - zd*zd); for (k = 0; k < 3; k++) ar.rdir[k] = xd*ux[k]+yd*uy[k]+zd*r->ron[k]; + dimlist[ndims++] = div[0].t*np + div[0].p + 38813; rayvalue(&ar); + ndims--; + rayvalue(&ar); if (ar.rot < FHUGE) arad += 1.0 / ar.rot; /* recompute error */ @@ -396,8 +425,11 @@ register RAY *r; if (ne >= i) { /* extract darkest division */ ne--; - if (div[ne].n > 1) - scalecolor(div[ne].v, 1.0/div[ne].n); + if (div[ne].n > 1) { + b = 1.0/div[ne].n; + scalecolor(div[ne].v, b); + div[ne].n = 1; + } addcolor(acol, div[ne].v); } } @@ -410,7 +442,7 @@ register RAY *r; arad = maxarad; else if (arad < minarad) arad = minarad; - if (ns > 0) + if (div != NULL) free((char *)div); return(arad); }