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.5 by greg, Wed Jun 7 08:38:38 1989 UTC vs.
Revision 1.8 by greg, Wed Jun 7 21:00:51 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 265 | Line 303 | char  *p;                      /* data for f */
303   {
304          register int  sn;
305          register CONTRIB  *srccnt;
306 <        double  dtmp, hwt, test2, hit2;
306 >        int  ncnts;
307 >        double  ourthresh, prob, hwt, test2, hit2;
308          RAY  sr;
309  
310          if ((srccnt = (CONTRIB *)malloc(nsources*sizeof(CONTRIB))) == NULL)
311                  error(SYSTEM, "out of memory in direct");
312 +                                                /* modify threshold */
313 +        ourthresh = shadthresh / r->rweight;
314                                                  /* potential contributions */
315          for (sn = 0; sn < nsources; sn++) {
316                  srccnt[sn].sno = sn;
317                  setcolor(srccnt[sn].val, 0.0, 0.0, 0.0);
318 +                srccnt[sn].brt = 0.0;
319                                                  /* get source ray */
320                  if ((srccnt[sn].dom = srcray(&sr, r, sn)) == 0.0)
321                          continue;
# Line 296 | Line 338 | char  *p;                      /* data for f */
338          }
339                                                  /* sort contributions */
340          qsort(srccnt, nsources, sizeof(CONTRIB), cntcmp);
341 <        hit2 = test2 = 0.0;
342 <                                                /* test for shadows */
343 <        for (sn = 0; sn < nsources; sn++) {
344 <                                                /* check threshold */
345 <                if (srccnt[sn].brt <= shadthresh*bright(r->rcol)/r->rweight)
341 >        hit2 = 0.0; test2 = FTINY;
342 >                                                /* find last */
343 >        sn = 0; ncnts = nsources;
344 >        while (sn < ncnts-1) {
345 >                register int  m;
346 >                m = (sn + ncnts) >> 1;
347 >                if (srccnt[m].brt > 0.0)
348 >                        sn = m;
349 >                else
350 >                        ncnts = m;
351 >        }
352 >                                                /* accumulate tail */
353 >        for (sn = ncnts-1; sn > 0; sn--)
354 >                srccnt[sn-1].brt += srccnt[sn].brt;
355 >                                                /* shadow testing */
356 >        for (sn = 0; sn < ncnts; sn++) {
357 >                                                /* tail below threshold? */
358 >                if (srccnt[sn].brt < ourthresh*bright(r->rcol))
359                          break;
360                                                  /* get statistics */
361                  hwt = (double)source[srccnt[sn].sno].nhits /
# Line 327 | Line 382 | char  *p;                      /* data for f */
382                  hit2 += hwt;
383                  source[srccnt[sn].sno].nhits++;
384          }
385 <        if (test2 > FTINY)              /* weighted hit rate */
386 <                hwt = hit2 / test2;
332 <        else
333 <                hwt = 0.0;
385 >                                        /* weighted hit rate */
386 >        hwt = hit2 / test2;
387   #ifdef DEBUG
388 <        fprintf(stderr, "%d tested, %f hit rate\n", sn, hwt);
388 >        fprintf(stderr, "%d tested, %d untested, %f hit rate\n",
389 >                        sn, ncnts-sn, hwt);
390   #endif
391                                          /* add in untested sources */
392 <        for ( ; sn < nsources; sn++) {
393 <                if (srccnt[sn].brt <= 0.0)
340 <                        break;
341 <                dtmp = hwt * (double)source[srccnt[sn].sno].nhits /
392 >        for ( ; sn < ncnts; sn++) {
393 >                prob = hwt * (double)source[srccnt[sn].sno].nhits /
394                                  (double)source[srccnt[sn].sno].ntests;
395 <                scalecolor(srccnt[sn].val, dtmp);
395 >                scalecolor(srccnt[sn].val, prob);
396                  addcolor(r->rcol, srccnt[sn].val);
397          }
346                
398          free(srccnt);
399   }
400  
# Line 353 | Line 404 | char  *p;                      /* data for f */
404                                  source[r->rsrc].so!=r->ro)
405  
406   #define  badambient(m, r)       ((r->crtype&(AMBIENT|SHADOW))==AMBIENT && \
407 <                                !(r->rtype&REFLECTED))  /* hack! */
407 >                                !(r->rtype&REFLECTED) &&        /* hack! */\
408 >                                !(m->otype==MAT_GLOW&&r->rot>m->oargs.farg[3]))
409  
410   #define  passillum(m, r)        (m->otype==MAT_ILLUM && \
411                                  !(r->rsrc>=0&&source[r->rsrc].so==r->ro))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines