--- ray/src/rt/virtuals.c 1991/07/17 12:38:52 1.18 +++ ray/src/rt/virtuals.c 1991/10/23 08:49:40 1.30 @@ -19,8 +19,8 @@ static char SCCSid[] = "$SunId$ LBL"; #include "random.h" -#define MINSAMPLES 5 /* minimum number of pretest samples */ -#define STESTMAX 30 /* maximum seeks per sample */ +#define MINSAMPLES 16 /* minimum number of pretest samples */ +#define STESTMAX 32 /* maximum seeks per sample */ double getdisk(); @@ -44,8 +44,10 @@ markvirtuals() /* find and mark virtual sources */ if (!isvlight(objptr(o->omod)->otype)) continue; if (sfun[o->otype].of == NULL || - sfun[o->otype].of->getpleq == NULL) - objerror(o, USER, "illegal material"); + sfun[o->otype].of->getpleq == NULL) { + objerror(o,WARNING,"secondary sources not supported"); + continue; + } if (nvobjects == 0) vobject = (OBJECT *)malloc(sizeof(OBJECT)); else @@ -140,8 +142,12 @@ MAT4 pm; 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); + /* adjust for source size */ + d = sqrt(dist2(ourspot.aim, theirspot.aim)); + d = sqrt(source[sn].sl.s->siz/PI) + d*source[sn].srad; + 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 */ @@ -164,8 +170,10 @@ 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))); + /* adjust for source size */ + d = (sqrt(maxrad2) + source[sn].srad) / d; + if (d < 1.-FTINY) + ourspot.siz = 2.*PI*(1. - sqrt(1.-d*d)); else nsflags &= ~SSPOT; if (source[sn].sflags & SSPOT) { @@ -195,7 +203,7 @@ MAT4 pm; if (source[sn].sflags & SFLAT) { /* behind source? */ multv3(nsnorm, source[sn].snorm, pm); normalize(nsnorm); - if (!checkspot(&ourspot, nsnorm)) + if (nsflags & SSPOT && !checkspot(&ourspot, nsnorm)) return(-1); } } @@ -208,9 +216,14 @@ MAT4 pm; goto memerr; source[i].sflags = nsflags; VCOPY(source[i].sloc, nsloc); + multv3(source[i].ss[SU], source[sn].ss[SU], pm); + multv3(source[i].ss[SV], source[sn].ss[SV], pm); if (nsflags & SFLAT) VCOPY(source[i].snorm, nsnorm); - source[i].ss = source[sn].ss; source[i].ss2 = source[sn].ss2; + else + multv3(source[i].ss[SW], source[sn].ss[SW], pm); + source[i].srad = source[sn].srad; + source[i].ss2 = source[sn].ss2; if (nsflags & SSPOT) { if ((source[i].sl.s = (SPOT *)malloc(sizeof(SPOT))) == NULL) goto memerr; @@ -269,6 +282,7 @@ register int sn; /* target source number */ RAY sr; FVECT onorm; FVECT offsdir; + SRCINDEX si; double or, d; int infront; int stestlim, ssn; @@ -281,13 +295,17 @@ register int sn; /* target source number */ getplaneq(onorm, o); /* set number of rays to sample */ if (source[sn].sflags & SDISTANT) { - n = (2./3.*PI*PI)*or2/(thescene.cusize*thescene.cusize)* - vspretest + .5; + /* 32. == heuristic constant */ + n = 32.*or2/(thescene.cusize*thescene.cusize)*vspretest + .5; infront = DOT(onorm, source[sn].sloc) > 0.; } 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; @@ -309,9 +327,9 @@ register int sn; /* target source number */ #endif return(f); /* too small a target! */ } + multisamp(offsdir, 3, urand(sn*931+5827+ssn)); for (i = 0; i < 3; i++) - offsdir[i] = or*(1. - - 2.*urand(urind(931*i+5827,ssn))); + offsdir[i] = or*(1. - 2.*offsdir[i]); ssn++; for (i = 0; i < 3; i++) sr.rorg[i] = oc[i] + offsdir[i]; @@ -329,8 +347,11 @@ register int sn; /* target source number */ rayorigin(&sr, NULL, PRIMARY, 1.0); } while (!(*ofun[o->otype].funp)(o, &sr)); /* check against source */ + initsrcindex(&si); + si.sn = sn; + nopart(&si, &sr); samplendx++; - if (srcray(&sr, NULL, sn) == 0.) + if (!srcray(&sr, NULL, &si) || sr.rsrc != sn) continue; sr.revf = srcvalue; rayvalue(&sr);