--- ray/src/rt/virtuals.c 1991/06/25 15:48:11 1.11 +++ ray/src/rt/virtuals.c 1991/07/11 16:43:38 1.16 @@ -19,7 +19,10 @@ static char SCCSid[] = "$SunId$ LBL"; #include "random.h" +#define MINSAMPLES 5 /* minimum number of pretest samples */ +#define STESTMAX 30 /* maximum seeks per sample */ + double getdisk(); static OBJECT *vobject; /* virtual source objects */ @@ -158,14 +161,24 @@ MAT4 pm; return(-1); /* at source!! */ if (source[sn].sflags & SPROX && d > source[sn].sl.prox) return(-1); /* too far away */ - ourspot.siz = 2.*PI*(1. - d/sqrt(d*d+maxrad2)); ourspot.flen = 0.; + if (d*d > maxrad2) + ourspot.siz = 2.*PI*(1. - sqrt(1.-maxrad2/(d*d))); + else + nsflags &= ~SSPOT; if (source[sn].sflags & SSPOT) { copystruct(&theirspot, source[sn].sl.s); multv3(theirspot.aim, source[sn].sl.s->aim, pm); - d = ourspot.siz; - if (!commonspot(&ourspot, &theirspot, nsloc)) - return(-1); /* no overlap */ + if (nsflags & SSPOT) { + ourspot.flen = theirspot.flen; + d = ourspot.siz; + if (!commonspot(&ourspot, &theirspot, nsloc)) + return(-1); /* no overlap */ + } else { + nsflags |= SSPOT; + copystruct(&ourspot, &theirspot); + d = 2.*ourspot.siz; + } if (ourspot.siz < d-FTINY) { /* it shrunk */ d = spotdisk(v, op, &ourspot, nsloc); if (d <= FTINY) @@ -175,11 +188,10 @@ MAT4 pm; VCOPY(ocent, v); } } - ourspot.flen = theirspot.flen; } if (source[sn].sflags & SFLAT) { /* behind source? */ multv3(nsnorm, source[sn].snorm, pm); - if (checkspot(&ourspot, nsnorm) < 0) + if (!checkspot(&ourspot, nsnorm)) return(-1); } } @@ -195,9 +207,11 @@ MAT4 pm; if (nsflags & SFLAT) VCOPY(source[i].snorm, nsnorm); source[i].ss = source[sn].ss; source[i].ss2 = source[sn].ss2; - if ((source[i].sl.s = (SPOT *)malloc(sizeof(SPOT))) == NULL) - goto memerr; - copystruct(source[i].sl.s, &ourspot); + if (nsflags & SSPOT) { + if ((source[i].sl.s = (SPOT *)malloc(sizeof(SPOT))) == NULL) + goto memerr; + copystruct(source[i].sl.s, &ourspot); + } if (nsflags & SPROX) source[i].sl.prox = source[sn].sl.prox; source[i].sa.svnext = sn; @@ -253,7 +267,7 @@ register int sn; /* target source number */ FVECT offsdir; double or, d; int infront; - int ssn; + int stestlim, ssn; int nhit, nok; register int i, n; /* return if pretesting disabled */ @@ -272,19 +286,20 @@ register int sn; /* target source number */ n = or2/DOT(offsdir,offsdir)*vspretest + .5; infront = DOT(onorm, offsdir) > 0.; } - if (n < 1) n = 1; + if (n < MINSAMPLES) n = MINSAMPLES; #ifdef DEBUG fprintf(stderr, "pretesting source %d in object %s with %d rays\n", sn, o->oname, n); #endif /* sample */ or = sqrt(or2); - ssn = 25*n; + stestlim = n*STESTMAX; + ssn = 0; nhit = nok = 0; while (n-- > 0) { /* get sample point */ do { - if (--ssn < 0) { + if (ssn >= stestlim) { #ifdef DEBUG fprintf(stderr, "\ttoo hard to hit\n"); #endif @@ -292,7 +307,8 @@ register int sn; /* target source number */ } for (i = 0; i < 3; i++) offsdir[i] = or*(1. - - 2.*urand(931*i+5827+ssn)); + 2.*urand(urind(931*i+5827,ssn))); + ssn++; for (i = 0; i < 3; i++) sr.rorg[i] = oc[i] + offsdir[i]; d = DOT(offsdir,onorm);