--- ray/src/rt/virtuals.c 1991/06/26 14:26:52 1.15 +++ ray/src/rt/virtuals.c 1991/08/02 10:30:27 1.20 @@ -104,6 +104,7 @@ int n; for (i = 0; i < vsmat->nproj; i++) if ((*vsmat->vproj)(proj, o, &source[sn], i)) if ((ns = makevsrc(o, sn, proj)) >= 0) { + source[ns].sa.sv.pn = i; #ifdef DEBUG virtverb(ns, stderr); #endif @@ -134,12 +135,16 @@ MAT4 pm; if (source[sn].sflags & SPROX) return(-1); /* should never get here! */ multv3(nsloc, source[sn].sloc, pm); + normalize(nsloc); VCOPY(ourspot.aim, ocent); ourspot.siz = PI*maxrad2; ourspot.flen = 0.; if (source[sn].sflags & SSPOT) { - copystruct(&theirspot, source[sn].sl.s); multp3(theirspot.aim, source[sn].sl.s->aim, pm); + d = sqrt(dist2(ourspot.aim, theirspot.aim)); + d = sqrt(source[sn].sl.s->siz/PI) + d*source[sn].ss; + theirspot.siz = PI*d*d; + ourspot.flen = theirspot.flen = source[sn].sl.s->flen; d = ourspot.siz; if (!commonbeam(&ourspot, &theirspot, nsloc)) return(-1); /* no overlap */ @@ -162,13 +167,15 @@ MAT4 pm; if (source[sn].sflags & SPROX && d > source[sn].sl.prox) return(-1); /* too far away */ ourspot.flen = 0.; - if (d*d > maxrad2) - ourspot.siz = 2.*PI*(1. - sqrt(1.-maxrad2/(d*d))); + d = (sqrt(maxrad2) + source[sn].ss) / d; + if (d < 1.-FTINY) + ourspot.siz = 2.*PI*(1. - sqrt(1.-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); + normalize(theirspot.aim); if (nsflags & SSPOT) { ourspot.flen = theirspot.flen; d = ourspot.siz; @@ -191,7 +198,8 @@ MAT4 pm; } if (source[sn].sflags & SFLAT) { /* behind source? */ multv3(nsnorm, source[sn].snorm, pm); - if (!checkspot(&ourspot, nsnorm)) + normalize(nsnorm); + if (nsflags & SSPOT && !checkspot(&ourspot, nsnorm)) return(-1); } } @@ -214,7 +222,7 @@ MAT4 pm; } if (nsflags & SPROX) source[i].sl.prox = source[sn].sl.prox; - source[i].sa.svnext = sn; + source[i].sa.sv.sn = sn; source[i].so = op; return(i); memerr: @@ -267,7 +275,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 */ @@ -283,7 +291,11 @@ register int sn; /* target source number */ } else { for (i = 0; i < 3; i++) offsdir[i] = source[sn].sloc[i] - oc[i]; - n = or2/DOT(offsdir,offsdir)*vspretest + .5; + d = DOT(offsdir,offsdir); + if (d <= FTINY) + n = 2.*PI * vspretest + .5; + else + n = 2.*PI * (1.-sqrt(1./(1.+or2/d)))*vspretest + .5; infront = DOT(onorm, offsdir) > 0.; } if (n < MINSAMPLES) n = MINSAMPLES; @@ -293,12 +305,13 @@ register int sn; /* target source number */ #endif /* sample */ or = sqrt(or2); - ssn = STESTMAX*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 @@ -306,7 +319,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); @@ -332,7 +346,8 @@ register int sn; /* target source number */ continue; nok++; /* check against obstructions */ - srcray(&sr, NULL, sn); + rayclear(&sr); + sr.revf = raytrace; rayvalue(&sr); if (bright(sr.rcol) > FTINY) nhit++; @@ -370,7 +385,7 @@ FILE *fp; fprintf(fp, "\tat (%f,%f,%f)\n", source[sn].sloc[0], source[sn].sloc[1], source[sn].sloc[2]); fprintf(fp, "\tlinked to source %d (%s)\n", - source[sn].sa.svnext, source[source[sn].sa.svnext].so->oname); + source[sn].sa.sv.sn, source[source[sn].sa.sv.sn].so->oname); if (source[sn].sflags & SFOLLOW) fprintf(fp, "\talways followed\n"); else