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.4 by greg, Wed Jun 7 08:35:32 1989 UTC vs.
Revision 1.9 by greg, Thu Jun 8 09:35:43 1989 UTC

# Line 48 | Line 48 | marksources()                  /* find and mark source objects */
48  
49                  if (m->otype != MAT_LIGHT &&
50                                  m->otype != MAT_ILLUM &&
51 <                                m->otype != MAT_GLOW)
51 >                                m->otype != MAT_GLOW &&
52 >                                m->otype != MAT_SPOT)
53                          continue;
54          
55 <                if (m->oargs.nfargs != 3)
55 >                if (m->oargs.nfargs != (m->otype == MAT_GLOW ? 4 :
56 >                                m->otype == MAT_SPOT ? 7 : 3))
57                          objerror(m, USER, "bad # arguments");
58  
59 <                if (m->otype == MAT_GLOW && o->otype != OBJ_SOURCE)
59 >                if (m->otype == MAT_GLOW &&
60 >                                o->otype != OBJ_SOURCE &&
61 >                                m->oargs.farg[3] <= FTINY)
62                          continue;                       /* don't bother */
63  
64                  if (source == NULL)
# Line 67 | Line 71 | marksources()                  /* find and mark source objects */
71  
72                  newsource(&source[nsources], o);
73  
74 <                if (m->otype == MAT_GLOW)
75 <                        source[nsources].sflags |= SSKIP;
76 <
74 >                if (m->otype == MAT_GLOW) {
75 >                        source[nsources].sflags |= SPROX;
76 >                        source[nsources].sl.prox = m->oargs.farg[3];
77 >                        if (o->otype == OBJ_SOURCE)
78 >                                source[nsources].sflags |= SSKIP;
79 >                } else if (m->otype == MAT_SPOT) {
80 >                        source[nsources].sflags |= SSPOT;
81 >                        source[nsources].sl.s = makespot(m);
82 >                }
83                  nsources++;
84          }
85   }
# Line 87 | Line 97 | register OBJREC  *so;
97          register int  i;
98          
99          src->sflags = 0;
100 <        src->nhits = src->ntests = 1;   /* start with hit probability = 1 */
100 >        src->nhits = 1; src->ntests = 2;        /* start probability = 1/2 */
101          src->so = so;
102  
103          switch (so->otype) {
# Line 139 | Line 149 | register OBJREC  *so;
149   }
150  
151  
152 + SPOT *
153 + makespot(m)                     /* make a spotlight */
154 + register OBJREC  *m;
155 + {
156 +        extern double  cos();
157 +        register SPOT  *ns;
158 +
159 +        if ((ns = (SPOT *)malloc(sizeof(SPOT))) == NULL)
160 +                error(SYSTEM, "out of memory in makespot");
161 +        ns->siz = 2.0*PI * (1.0 - cos(PI/180.0/2.0 * m->oargs.farg[3]));
162 +        VCOPY(ns->aim, m->oargs.farg+4);
163 +        if ((ns->flen = normalize(ns->aim)) == 0.0)
164 +                objerror(m, USER, "zero focus vector");
165 +        return(ns);
166 + }
167 +
168 +
169   double
170   srcray(sr, r, sn)               /* send a ray to a source, return domega */
171   register RAY  *sr;              /* returned source ray */
# Line 199 | Line 226 | register int  sn;              /* source number */
226                  return(source[sn].ss2);
227  
228          else {
229 +                                                /* check proximity */
230 +                if (source[sn].sflags & SPROX &&
231 +                                d > source[sn].sl.prox)
232 +                        return(0.0);
233  
234                  if (norm != NULL)
235                          ddot /= d;
236                  else
237                          ddot = 1.0;
238 +                                                /* check angle */
239 +                if (source[sn].sflags & SSPOT) {
240 +                        if (source[sn].sl.s->siz < 2.0*PI *
241 +                                (1.0 + DOT(source[sn].sl.s->aim,sr->rdir)))
242 +                                return(0.0);
243 +                        d += source[sn].sl.s->flen;
244 +                }
245                                                  /* return domega */
246                  return(ddot*source[sn].ss2/(d*d));
247          }
# Line 248 | Line 286 | register RAY  *r;
286  
287   static int
288   cntcmp(sc1, sc2)                        /* contribution compare (descending) */
289 < register CONTRIB  *sc1, *sc2;
289 > register CNTPTR  *sc1, *sc2;
290   {
291          if (sc1->brt > sc2->brt)
292                  return(-1);
# Line 265 | Line 303 | char  *p;                      /* data for f */
303   {
304          register int  sn;
305          register CONTRIB  *srccnt;
306 <        double  dtmp, hwt, test2, hit2;
306 >        register CNTPTR  *cntord;
307 >        int  ncnts;
308 >        double  ourthresh, prob, hwt, test2, hit2;
309          RAY  sr;
310  
311 <        if ((srccnt = (CONTRIB *)malloc(nsources*sizeof(CONTRIB))) == NULL)
311 >        srccnt = (CONTRIB *)malloc(nsources*sizeof(CONTRIB));
312 >        cntord = (CNTPTR *)malloc(nsources*sizeof(CNTPTR));
313 >        if (srccnt == NULL || cntord == NULL)
314                  error(SYSTEM, "out of memory in direct");
315 +                                                /* modify threshold */
316 +        ourthresh = shadthresh / r->rweight;
317                                                  /* potential contributions */
318          for (sn = 0; sn < nsources; sn++) {
319 <                srccnt[sn].sno = sn;
320 <                setcolor(srccnt[sn].val, 0.0, 0.0, 0.0);
319 >                cntord[sn].sno = sn;
320 >                cntord[sn].brt = 0.0;
321                                                  /* get source ray */
322                  if ((srccnt[sn].dom = srcray(&sr, r, sn)) == 0.0)
323                          continue;
324                  VCOPY(srccnt[sn].dir, sr.rdir);
325                                                  /* compute coefficient */
326                  (*f)(srccnt[sn].val, p, srccnt[sn].dir, srccnt[sn].dom);
327 <                srccnt[sn].brt = intens(srccnt[sn].val);
328 <                if (srccnt[sn].brt <= FTINY)
327 >                cntord[sn].brt = bright(srccnt[sn].val);
328 >                if (cntord[sn].brt <= FTINY)
329                          continue;
330                                                  /* compute intersection */
331                  if (!( source[sn].sflags & SDISTANT ?
# Line 292 | Line 336 | char  *p;                      /* data for f */
336                                                  /* compute contribution */
337                  rayshade(&sr, sr.ro->omod);
338                  multcolor(srccnt[sn].val, sr.rcol);
339 <                srccnt[sn].brt = intens(srccnt[sn].val);
339 >                cntord[sn].brt = bright(srccnt[sn].val);
340          }
341                                                  /* sort contributions */
342 <        qsort(srccnt, nsources, sizeof(CONTRIB), cntcmp);
343 <        hit2 = test2 = 0.0;
344 <                                                /* test for shadows */
345 <        for (sn = 0; sn < nsources; sn++) {
346 <                                                /* check threshold */
347 <                if (srccnt[sn].brt <= shadthresh*intens(r->rcol)/r->rweight)
342 >        qsort(cntord, nsources, sizeof(CNTPTR), cntcmp);
343 >        hit2 = 0.0; test2 = FTINY;
344 >                                                /* find last */
345 >        sn = 0; ncnts = nsources;
346 >        while (sn < ncnts-1) {
347 >                register int  m;
348 >                m = (sn + ncnts) >> 1;
349 >                if (cntord[m].brt > 0.0)
350 >                        sn = m;
351 >                else
352 >                        ncnts = m;
353 >        }
354 >                                                /* accumulate tail */
355 >        for (sn = ncnts-1; sn > 0; sn--)
356 >                cntord[sn-1].brt += cntord[sn].brt;
357 >                                                /* shadow testing */
358 >        for (sn = 0; sn < ncnts; sn++) {
359 >                                                /* tail below threshold? */
360 >                if (cntord[sn].brt < ourthresh*bright(r->rcol))
361                          break;
362                                                  /* get statistics */
363 <                hwt = (double)source[srccnt[sn].sno].nhits /
364 <                                (double)source[srccnt[sn].sno].ntests;
363 >                hwt = (double)source[cntord[sn].sno].nhits /
364 >                                (double)source[cntord[sn].sno].ntests;
365                  test2 += hwt;
366 <                source[srccnt[sn].sno].ntests++;
366 >                source[cntord[sn].sno].ntests++;
367                                                  /* test for hit */
368                  rayorigin(&sr, r, SHADOW, 1.0);
369 <                VCOPY(sr.rdir, srccnt[sn].dir);
369 >                VCOPY(sr.rdir, srccnt[cntord[sn].sno].dir);
370                  if (localhit(&sr, &thescene) &&
371 <                                sr.ro != source[srccnt[sn].sno].so) {
371 >                                sr.ro != source[cntord[sn].sno].so) {
372                                                  /* check for transmission */
373                          if (sr.clipset != NULL && inset(sr.clipset,sr.ro->omod))
374                                  raytrans(&sr);          /* object is clipped */
375                          else
376                                  rayshade(&sr, sr.ro->omod);
377 <                        if (intens(sr.rcol) <= FTINY)
377 >                        if (bright(sr.rcol) <= FTINY)
378                                  continue;       /* missed! */
379 <                        (*f)(srccnt[sn].val, p, srccnt[sn].dir, srccnt[sn].dom);
380 <                        multcolor(srccnt[sn].val, sr.rcol);
379 >                        (*f)(srccnt[cntord[sn].sno].val, p,
380 >                                        srccnt[cntord[sn].sno].dir,
381 >                                        srccnt[cntord[sn].sno].dom);
382 >                        multcolor(srccnt[cntord[sn].sno].val, sr.rcol);
383                  }
384                                                  /* add contribution if hit */
385 <                addcolor(r->rcol, srccnt[sn].val);
385 >                addcolor(r->rcol, srccnt[cntord[sn].sno].val);
386                  hit2 += hwt;
387 <                source[srccnt[sn].sno].nhits++;
387 >                source[cntord[sn].sno].nhits++;
388          }
389 <        if (test2 > FTINY)              /* weighted hit rate */
390 <                hwt = hit2 / test2;
332 <        else
333 <                hwt = 0.0;
389 >                                        /* weighted hit rate */
390 >        hwt = hit2 / test2;
391   #ifdef DEBUG
392 <        fprintf(stderr, "%d tested, %f hit rate\n", sn, hwt);
392 >        fprintf(stderr, "%d tested, %d untested, %f hit rate\n",
393 >                        sn, ncnts-sn, hwt);
394   #endif
395                                          /* add in untested sources */
396 <        for ( ; sn < nsources; sn++) {
397 <                if (srccnt[sn].brt <= 0.0)
398 <                        break;
399 <                dtmp = hwt * (double)source[srccnt[sn].sno].nhits /
400 <                                (double)source[srccnt[sn].sno].ntests;
343 <                scalecolor(srccnt[sn].val, dtmp);
344 <                addcolor(r->rcol, srccnt[sn].val);
396 >        for ( ; sn < ncnts; sn++) {
397 >                prob = hwt * (double)source[cntord[sn].sno].nhits /
398 >                                (double)source[cntord[sn].sno].ntests;
399 >                scalecolor(srccnt[cntord[sn].sno].val, prob);
400 >                addcolor(r->rcol, srccnt[cntord[sn].sno].val);
401          }
346                
402          free(srccnt);
403 +        free(cntord);
404   }
405  
406  
# Line 353 | Line 409 | char  *p;                      /* data for f */
409                                  source[r->rsrc].so!=r->ro)
410  
411   #define  badambient(m, r)       ((r->crtype&(AMBIENT|SHADOW))==AMBIENT && \
412 <                                !(r->rtype&REFLECTED))  /* hack! */
412 >                                !(r->rtype&REFLECTED) &&        /* hack! */\
413 >                                !(m->otype==MAT_GLOW&&r->rot>m->oargs.farg[3]))
414  
415   #define  passillum(m, r)        (m->otype==MAT_ILLUM && \
416                                  !(r->rsrc>=0&&source[r->rsrc].so==r->ro))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines