--- ray/src/rt/srcsamp.c 1992/07/21 12:47:12 2.3 +++ ray/src/rt/srcsamp.c 2008/12/06 01:08:53 2.12 @@ -1,13 +1,14 @@ -/* Copyright (c) 1991 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: srcsamp.c,v 2.12 2008/12/06 01:08:53 greg Exp $"; #endif - /* * Source sampling routines + * + * External symbols declared in source.h */ +#include "copyright.h" + #include "ray.h" #include "source.h" @@ -15,6 +16,9 @@ static char SCCSid[] = "$SunId$ LBL"; #include "random.h" +static int cyl_partit(), flt_partit(); + + double nextssamp(r, si) /* compute sample for source, rtn. distance */ register RAY *r; /* origin is read, direction is set */ @@ -53,7 +57,7 @@ nextsample: d = urand(ilhash(dimlist,ndims+2)+samplendx); if (source[si->sn].sflags & SFLAT) { multisamp(vpos, 2, d); - vpos[2] = 0.5; + vpos[SW] = 0.5; } else multisamp(vpos, 3, d); for (i = 0; i < 3; i++) @@ -64,6 +68,30 @@ nextsample: for (i = 0; i < 3; i++) vpos[i] += (double)cent[i]/MAXSPART; + /* avoid circular aiming failures */ + if (source[si->sn].sflags & SCIR) { + FVECT trim; + double d; + if (source[si->sn].sflags & (SFLAT|SDISTANT)) { + d = 1.12837917; /* correct setflatss() */ + trim[SU] = d*sqrt(1.0 - 0.5*vpos[SV]*vpos[SV]); + trim[SV] = d*sqrt(1.0 - 0.5*vpos[SU]*vpos[SU]); + trim[SW] = 0.0; + } else { + trim[SW] = trim[SU] = vpos[SU]*vpos[SU]; + d = vpos[SV]*vpos[SV]; + if (d > trim[SW]) trim[SW] = d; + trim[SU] += d; + d = vpos[SW]*vpos[SW]; + if (d > trim[SW]) trim[SW] = d; + trim[SU] += d; + d = 1.0/0.7236; /* correct sphsetsrc() */ + trim[SW] = trim[SV] = trim[SU] = + d*sqrt(trim[SW]/trim[SU]); + } + for (i = 0; i < 3; i++) + vpos[i] *= trim[i]; + } /* compute direction */ for (i = 0; i < 3; i++) r->rdir[i] = source[si->sn].sloc[i] + @@ -79,26 +107,28 @@ nextsample: goto nextsample; /* at source! */ /* compute sample size */ - si->dom = source[si->sn].ss2; if (source[si->sn].sflags & SFLAT) { - si->dom *= sflatform(si->sn, r->rdir); - si->dom *= (double)(size[SU]*size[SV])/(MAXSPART*MAXSPART); + si->dom = sflatform(si->sn, r->rdir); + si->dom *= size[SU]*size[SV]/(MAXSPART*(double)MAXSPART); } else if (source[si->sn].sflags & SCYL) { - si->dom *= scylform(si->sn, r->rdir); - si->dom *= (double)size[SU]/MAXSPART; + si->dom = scylform(si->sn, r->rdir); + si->dom *= size[SU]/(double)MAXSPART; } else { - si->dom *= (double)(size[SU]*size[SV]*size[SW]) / - (MAXSPART*MAXSPART*MAXSPART) ; + si->dom = size[SU]*size[SV]*(double)size[SW] / + (MAXSPART*MAXSPART*(double)MAXSPART) ; } - if (source[si->sn].sflags & SDISTANT) + if (source[si->sn].sflags & SDISTANT) { + si->dom *= source[si->sn].ss2; return(FHUGE); + } if (si->dom <= 1e-4) goto nextsample; /* behind source? */ - si->dom /= d*d; + si->dom *= source[si->sn].ss2/(d*d); return(d); /* sample OK, return distance */ } +int skipparts(ct, sz, pp, pt) /* skip to requested partition */ int ct[3], sz[3]; /* center and size of partition (returned) */ register int pp[2]; /* current index, number to skip (modified) */ @@ -108,12 +138,13 @@ unsigned char *pt; /* partition array */ /* check this partition */ p = spart(pt, pp[0]); pp[0]++; - if (p == S0) /* leaf partition */ + if (p == S0) { /* leaf partition */ if (pp[1]) { pp[1]--; return(0); /* not there yet */ } else return(1); /* we've arrived */ + } /* else check lower */ sz[p] >>= 1; ct[p] -= sz[p]; @@ -130,6 +161,7 @@ unsigned char *pt; /* partition array */ } +void nopart(si, r) /* single source partition */ register SRCINDEX *si; RAY *r; @@ -140,6 +172,7 @@ RAY *r; } +void cylpart(si, r) /* partition a cylinder */ SRCINDEX *si; register RAY *r; @@ -216,11 +249,12 @@ double d2; } +void flatpart(si, r) /* partition a flat source */ register SRCINDEX *si; register RAY *r; { - register FLOAT *vp; + register RREAL *vp; FVECT v; double du2, dv2; int pi; @@ -231,7 +265,7 @@ register RAY *r; v[1] = r->rorg[1] - vp[1]; v[2] = r->rorg[2] - vp[2]; vp = source[si->sn].snorm; - if (DOT(v,vp) <= FTINY) { /* behind source */ + if (DOT(v,vp) <= 0.) { /* behind source */ si->np = 0; return; } @@ -304,7 +338,7 @@ scylform(sn, dir) /* compute cosine for cylinder's pr int sn; register FVECT dir; /* assume normalized */ { - register FLOAT *dv; + register RREAL *dv; double d; dv = source[sn].ss[SU];