ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/source.c
(Generate patch)

Comparing ray/src/rt/source.c (file contents):
Revision 1.42 by greg, Mon Aug 12 08:20:49 1991 UTC vs.
Revision 2.3 by greg, Sun Apr 12 10:05:32 1992 UTC

# Line 18 | Line 18 | static char SCCSid[] = "$SunId$ LBL";
18  
19   #include  "source.h"
20  
21 #include  "random.h"
22
21   /*
22   * Structures used by direct()
23   */
24  
25   typedef struct {
26 +        int  sno;               /* source number */
27          FVECT  dir;             /* source direction */
28          COLOR  coef;            /* material coefficient */
29          COLOR  val;             /* contribution */
30   }  CONTRIB;             /* direct contribution */
31  
32   typedef struct {
33 <        int  sno;               /* source number */
33 >        int  sndx;              /* source index (to CONTRIB array) */
34          float  brt;             /* brightness (for comparison) */
35   }  CNTPTR;              /* contribution pointer */
36  
37   static CONTRIB  *srccnt;                /* source contributions in direct() */
38   static CNTPTR  *cntord;                 /* source ordering in direct() */
39 + static int  maxcntr = 0;                /* size of contribution arrays */
40  
41  
42   marksources()                   /* find and mark source objects */
43   {
44 +        int  foundsource = 0;
45          int  i;
46          register OBJREC  *o, *m;
47          register int  ns;
# Line 93 | Line 94 | marksources()                  /* find and mark source objects */
94                                  source[ns].sflags |= SSKIP;
95                          }
96                  }
97 +                if (!(source[ns].sflags & SSKIP))
98 +                        foundsource++;
99          }
100 <        if (nsources <= 0) {
100 >        if (!foundsource) {
101                  error(WARNING, "no light sources found");
102                  return;
103          }
104          markvirtuals();                 /* find and add virtual sources */
105 <        srccnt = (CONTRIB *)malloc(nsources*sizeof(CONTRIB));
106 <        cntord = (CNTPTR *)malloc(nsources*sizeof(CNTPTR));
107 <        if (srccnt == NULL || cntord == NULL)
105 >                                /* allocate our contribution arrays */
106 >        maxcntr = nsources + MAXSPART;  /* start with this many */
107 >        srccnt = (CONTRIB *)malloc(maxcntr*sizeof(CONTRIB));
108 >        cntord = (CNTPTR *)malloc(maxcntr*sizeof(CNTPTR));
109 >        if (srccnt == NULL | cntord == NULL)
110                  goto memerr;
111          return;
112   memerr:
# Line 109 | Line 114 | memerr:
114   }
115  
116  
117 < double
113 < srcray(sr, r, sn)               /* send a ray to a source, return domega */
117 > srcray(sr, r, si)               /* send a ray to a source, return domega */
118   register RAY  *sr;              /* returned source ray */
119   RAY  *r;                        /* ray which hit object */
120 < register int  sn;               /* source number */
120 > SRCINDEX  *si;                  /* source sample index */
121   {
122 <        double  ddot;                   /* (distance times) cosine */
123 <        FVECT  vd;
124 <        double  d;
125 <        register int  i;
122 >    double  d;                          /* distance to source */
123 >    FVECT  vd;
124 >    register SRCREC  *srcp;
125 >    register int  i;
126  
127 <        if (source[sn].sflags & SSKIP)
124 <                return(0.0);                    /* skip this source */
127 >    rayorigin(sr, r, SHADOW, 1.0);              /* ignore limits */
128  
129 <        rayorigin(sr, r, SHADOW, 1.0);          /* ignore limits */
130 <
131 <        sr->rsrc = sn;                          /* remember source */
132 <                                                /* get source direction */
133 <        if (source[sn].sflags & SDISTANT) {
131 <                                                /* constant direction */
132 <                VCOPY(sr->rdir, source[sn].sloc);
133 <        } else {                                /* compute direction */
134 <                for (i = 0; i < 3; i++)
135 <                        sr->rdir[i] = source[sn].sloc[i] - sr->rorg[i];
136 <
137 <                if (source[sn].sflags & SFLAT &&
138 <                        (ddot = -DOT(sr->rdir, source[sn].snorm)) <= FTINY)
139 <                        return(0.0);            /* behind surface! */
140 <        }
141 <        if (dstrsrc > FTINY) {
142 <                                        /* distribute source direction */
143 <                dimlist[ndims++] = sn;
144 <                for (i = 0; i < 3; i++) {
145 <                        dimlist[ndims] = i + 8831;
146 <                        vd[i] = dstrsrc * source[sn].ss *
147 <                (1.0 - 2.0*urand(urind(ilhash(dimlist,ndims+1),samplendx)));
148 <                }
149 <                ndims--;
150 <                if (source[sn].sflags & SFLAT) {        /* project offset */
151 <                        d = DOT(vd, source[sn].snorm);
129 >    while ((d = nextssamp(sr, si)) != 0.0) {
130 >        sr->rsrc = si->sn;                      /* remember source */
131 >        srcp = source + si->sn;
132 >        if (srcp->sflags & SDISTANT) {
133 >                if (srcp->sflags & SSPOT) {     /* check location */
134                          for (i = 0; i < 3; i++)
135 <                                vd[i] -= d * source[sn].snorm[i];
154 <                }
155 <                for (i = 0; i < 3; i++)         /* offset source direction */
156 <                        sr->rdir[i] += vd[i];
157 <                                                /* normalize */
158 <                d = normalize(sr->rdir);
159 <
160 <        } else if (!(source[sn].sflags & SDISTANT))
161 <                                                /* normalize direction */
162 <                d = normalize(sr->rdir);
163 <
164 <        if (source[sn].sflags & SDISTANT) {
165 <                if (source[sn].sflags & SSPOT) {        /* check location */
166 <                        for (i = 0; i < 3; i++)
167 <                                vd[i] = source[sn].sl.s->aim[i] - sr->rorg[i];
135 >                            vd[i] = srcp->sl.s->aim[i] - sr->rorg[i];
136                          d = DOT(sr->rdir,vd);
137                          if (d <= FTINY)
138 <                                return(0.0);
138 >                                continue;
139                          d = DOT(vd,vd) - d*d;
140 <                        if (PI*d > source[sn].sl.s->siz)
141 <                                return(0.0);
140 >                        if (PI*d > srcp->sl.s->siz)
141 >                                continue;
142                  }
143 <                return(source[sn].ss2);         /* domega constant */
143 >                return(1);              /* sample OK */
144          }
145 <                                                /* check direction */
178 <        if (d == 0.0)
179 <                return(0.0);
145 >                                /* local source */
146                                                  /* check proximity */
147 <        if (source[sn].sflags & SPROX &&
148 <                        d > source[sn].sl.prox)
183 <                return(0.0);
184 <                                                /* compute dot product */
185 <        if (source[sn].sflags & SFLAT)
186 <                ddot /= d;
187 <        else
188 <                ddot = 1.0;
147 >        if (srcp->sflags & SPROX && d > srcp->sl.prox)
148 >                continue;
149                                                  /* check angle */
150 <        if (source[sn].sflags & SSPOT) {
151 <                if (source[sn].sl.s->siz < 2.0*PI *
152 <                                (1.0 + DOT(source[sn].sl.s->aim,sr->rdir)))
153 <                        return(0.0);
154 <                d += source[sn].sl.s->flen;     /* adjust length */
150 >        if (srcp->sflags & SSPOT) {
151 >                if (srcp->sl.s->siz < 2.0*PI *
152 >                                (1.0 + DOT(srcp->sl.s->aim,sr->rdir)))
153 >                        continue;
154 >                                        /* adjust solid angle */
155 >                si->dom *= d*d;
156 >                d += srcp->sl.s->flen;
157 >                si->dom /= d*d;
158          }
159 <                                                /* compute domega */
160 <        return(ddot*source[sn].ss2/(d*d));
159 >        return(1);                      /* sample OK */
160 >    }
161 >    return(0);                  /* no more samples */
162   }
163  
164  
# Line 250 | Line 214 | char  *p;                      /* data for f */
214          extern int  (*trace)();
215          extern double  pow();
216          register int  sn;
217 +        SRCINDEX  si;
218          int  nshadcheck, ncnts;
219          int  nhits;
220 <        double  dom, prob, ourthresh, hwt;
220 >        double  prob, ourthresh, hwt;
221          RAY  sr;
222                          /* NOTE: srccnt and cntord global so no recursion */
223          if (nsources <= 0)
224                  return;         /* no sources?! */
260                                                /* compute number to check */
261        nshadcheck = pow((double)nsources, shadcert) + .5;
262                                                /* modify threshold */
263        ourthresh = shadthresh / r->rweight;
225                                                  /* potential contributions */
226 <        for (sn = 0; sn < nsources; sn++) {
227 <                cntord[sn].sno = sn;
228 <                cntord[sn].brt = 0.0;
229 <                                                /* get source ray */
230 <                if ((dom = srcray(&sr, r, sn)) == 0.0)
231 <                        continue;
232 <                VCOPY(srccnt[sn].dir, sr.rdir);
226 >        initsrcindex(&si);
227 >        for (sn = 0; srcray(&sr, r, &si); sn++) {
228 >                if (sn >= maxcntr) {
229 >                        maxcntr = sn + MAXSPART;
230 >                        srccnt = (CONTRIB *)realloc((char *)srccnt,
231 >                                        maxcntr*sizeof(CONTRIB));
232 >                        cntord = (CNTPTR *)realloc((char *)cntord,
233 >                                        maxcntr*sizeof(CNTPTR));
234 >                        if (srccnt == NULL | cntord == NULL)
235 >                                error(SYSTEM, "out of memory in direct");
236 >                }
237 >                cntord[sn].sndx = sn;
238 >                srccnt[sn].sno = sr.rsrc;
239                                                  /* compute coefficient */
240 <                (*f)(srccnt[sn].coef, p, srccnt[sn].dir, dom);
240 >                (*f)(srccnt[sn].coef, p, sr.rdir, si.dom);
241                  cntord[sn].brt = bright(srccnt[sn].coef);
242                  if (cntord[sn].brt <= 0.0)
243                          continue;
244 +                VCOPY(srccnt[sn].dir, sr.rdir);
245                                                  /* compute potential */
246                  sr.revf = srcvalue;
247                  rayvalue(&sr);
# Line 282 | Line 250 | char  *p;                      /* data for f */
250                  cntord[sn].brt = bright(srccnt[sn].val);
251          }
252                                                  /* sort contributions */
253 <        qsort(cntord, nsources, sizeof(CNTPTR), cntcmp);
253 >        qsort(cntord, sn, sizeof(CNTPTR), cntcmp);
254          {                                       /* find last */
255                  register int  l, m;
256  
257 <                sn = 0; ncnts = l = nsources;
257 >                ncnts = l = sn;
258 >                sn = 0;
259                  while ((m = (sn + ncnts) >> 1) != l) {
260                          if (cntord[m].brt > 0.0)
261                                  sn = m;
# Line 295 | Line 264 | char  *p;                      /* data for f */
264                          l = m;
265                  }
266          }
267 +        if (ncnts == 0)
268 +                return;         /* no contributions! */
269                                                  /* accumulate tail */
270          for (sn = ncnts-1; sn > 0; sn--)
271                  cntord[sn-1].brt += cntord[sn].brt;
272 +                                                /* compute number to check */
273 +        nshadcheck = pow((double)ncnts, shadcert) + .5;
274 +                                                /* modify threshold */
275 +        ourthresh = shadthresh / r->rweight;
276                                                  /* test for shadows */
277          nhits = 0;
278          for (sn = 0; sn < ncnts; sn++) {
# Line 306 | Line 281 | char  *p;                      /* data for f */
281                                  cntord[sn].brt-cntord[sn+nshadcheck].brt)
282                                  < ourthresh*bright(r->rcol))
283                          break;
309                                                /* get statistics */
310                source[cntord[sn].sno].ntests++;
284                                                  /* test for hit */
285                  rayorigin(&sr, r, SHADOW, 1.0);
286 <                VCOPY(sr.rdir, srccnt[cntord[sn].sno].dir);
287 <                sr.rsrc = cntord[sn].sno;
286 >                VCOPY(sr.rdir, srccnt[cntord[sn].sndx].dir);
287 >                sr.rsrc = srccnt[cntord[sn].sndx].sno;
288 >                source[sr.rsrc].ntests++;       /* keep statistics */
289                  if (localhit(&sr, &thescene) &&
290 <                                ( sr.ro != source[cntord[sn].sno].so ||
291 <                                source[cntord[sn].sno].sflags & SFOLLOW )) {
290 >                                ( sr.ro != source[sr.rsrc].so ||
291 >                                source[sr.rsrc].sflags & SFOLLOW )) {
292                                                  /* follow entire path */
293                          raycont(&sr);
294                          if (trace != NULL)
295                                  (*trace)(&sr);  /* trace execution */
296                          if (bright(sr.rcol) <= FTINY)
297                                  continue;       /* missed! */
298 <                        copycolor(srccnt[cntord[sn].sno].val, sr.rcol);
299 <                        multcolor(srccnt[cntord[sn].sno].val,
300 <                                        srccnt[cntord[sn].sno].coef);
298 >                        copycolor(srccnt[cntord[sn].sndx].val, sr.rcol);
299 >                        multcolor(srccnt[cntord[sn].sndx].val,
300 >                                        srccnt[cntord[sn].sndx].coef);
301                  }
302                                                  /* add contribution if hit */
303 <                addcolor(r->rcol, srccnt[cntord[sn].sno].val);
303 >                addcolor(r->rcol, srccnt[cntord[sn].sndx].val);
304                  nhits++;
305 <                source[cntord[sn].sno].nhits++;
305 >                source[sr.rsrc].nhits++;
306          }
307                                          /* surface hit rate */
308          if (sn > 0)
# Line 342 | Line 316 | char  *p;                      /* data for f */
316   #endif
317                                          /* add in untested sources */
318          for ( ; sn < ncnts; sn++) {
319 <                prob = hwt * (double)source[cntord[sn].sno].nhits /
320 <                                (double)source[cntord[sn].sno].ntests;
321 <                scalecolor(srccnt[cntord[sn].sno].val, prob);
322 <                addcolor(r->rcol, srccnt[cntord[sn].sno].val);
319 >                sr.rsrc = srccnt[cntord[sn].sndx].sno;
320 >                prob = hwt * (double)source[sr.rsrc].nhits /
321 >                                (double)source[sr.rsrc].ntests;
322 >                scalecolor(srccnt[cntord[sn].sndx].val, prob);
323 >                addcolor(r->rcol, srccnt[cntord[sn].sndx].val);
324          }
325   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines