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.10 by greg, Thu Jun 8 17:04: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 >        double  prob, ourthresh, hwt, test2, hit2;
308          RAY  sr;
309  
310 <        if ((srccnt = (CONTRIB *)malloc(nsources*sizeof(CONTRIB))) == NULL)
310 >        srccnt = (CONTRIB *)malloc(nsources*sizeof(CONTRIB));
311 >        cntord = (CNTPTR *)malloc(nsources*sizeof(CNTPTR));
312 >        if (srccnt == NULL || cntord == NULL)
313                  error(SYSTEM, "out of memory in direct");
314 +                                                /* modify threshold */
315 +        ourthresh = shadthresh / r->rweight;
316                                                  /* potential contributions */
317          for (sn = 0; sn < nsources; sn++) {
318 <                srccnt[sn].sno = sn;
319 <                setcolor(srccnt[sn].val, 0.0, 0.0, 0.0);
318 >                cntord[sn].sno = sn;
319 >                cntord[sn].brt = 0.0;
320                                                  /* get source ray */
321                  if ((srccnt[sn].dom = srcray(&sr, r, sn)) == 0.0)
322                          continue;
323                  VCOPY(srccnt[sn].dir, sr.rdir);
324                                                  /* compute coefficient */
325                  (*f)(srccnt[sn].val, p, srccnt[sn].dir, srccnt[sn].dom);
326 <                srccnt[sn].brt = intens(srccnt[sn].val);
327 <                if (srccnt[sn].brt <= FTINY)
326 >                cntord[sn].brt = bright(srccnt[sn].val);
327 >                if (cntord[sn].brt <= FTINY)
328                          continue;
329                                                  /* compute intersection */
330                  if (!( source[sn].sflags & SDISTANT ?
# Line 292 | Line 335 | char  *p;                      /* data for f */
335                                                  /* compute contribution */
336                  rayshade(&sr, sr.ro->omod);
337                  multcolor(srccnt[sn].val, sr.rcol);
338 <                srccnt[sn].brt = intens(srccnt[sn].val);
338 >                cntord[sn].brt = bright(srccnt[sn].val);
339          }
340                                                  /* sort contributions */
341 <        qsort(srccnt, nsources, sizeof(CONTRIB), cntcmp);
342 <        hit2 = test2 = 0.0;
341 >        qsort(cntord, nsources, sizeof(CNTPTR), cntcmp);
342 >        hit2 = 0.0; test2 = FTINY;
343                                                  /* test for shadows */
344          for (sn = 0; sn < nsources; sn++) {
345                                                  /* check threshold */
346 <                if (srccnt[sn].brt <= shadthresh*intens(r->rcol)/r->rweight)
346 >                if (cntord[sn].brt <= ourthresh*bright(r->rcol))
347                          break;
348                                                  /* get statistics */
349 <                hwt = (double)source[srccnt[sn].sno].nhits /
350 <                                (double)source[srccnt[sn].sno].ntests;
349 >                hwt = (double)source[cntord[sn].sno].nhits /
350 >                                (double)source[cntord[sn].sno].ntests;
351                  test2 += hwt;
352 <                source[srccnt[sn].sno].ntests++;
352 >                source[cntord[sn].sno].ntests++;
353                                                  /* test for hit */
354                  rayorigin(&sr, r, SHADOW, 1.0);
355 <                VCOPY(sr.rdir, srccnt[sn].dir);
355 >                VCOPY(sr.rdir, srccnt[cntord[sn].sno].dir);
356                  if (localhit(&sr, &thescene) &&
357 <                                sr.ro != source[srccnt[sn].sno].so) {
357 >                                sr.ro != source[cntord[sn].sno].so) {
358                                                  /* check for transmission */
359                          if (sr.clipset != NULL && inset(sr.clipset,sr.ro->omod))
360                                  raytrans(&sr);          /* object is clipped */
361                          else
362                                  rayshade(&sr, sr.ro->omod);
363 <                        if (intens(sr.rcol) <= FTINY)
363 >                        if (bright(sr.rcol) <= FTINY)
364                                  continue;       /* missed! */
365 <                        (*f)(srccnt[sn].val, p, srccnt[sn].dir, srccnt[sn].dom);
366 <                        multcolor(srccnt[sn].val, sr.rcol);
365 >                        (*f)(srccnt[cntord[sn].sno].val, p,
366 >                                        srccnt[cntord[sn].sno].dir,
367 >                                        srccnt[cntord[sn].sno].dom);
368 >                        multcolor(srccnt[cntord[sn].sno].val, sr.rcol);
369                  }
370                                                  /* add contribution if hit */
371 <                addcolor(r->rcol, srccnt[sn].val);
371 >                addcolor(r->rcol, srccnt[cntord[sn].sno].val);
372                  hit2 += hwt;
373 <                source[srccnt[sn].sno].nhits++;
373 >                source[cntord[sn].sno].nhits++;
374          }
375 <        if (test2 > FTINY)              /* weighted hit rate */
376 <                hwt = hit2 / test2;
332 <        else
333 <                hwt = 0.0;
375 >                                        /* weighted hit rate */
376 >        hwt = hit2 / test2;
377   #ifdef DEBUG
378 <        fprintf(stderr, "%d tested, %f hit rate\n", sn, hwt);
378 >        {
379 >                int  ntested = sn;
380   #endif
381                                          /* add in untested sources */
382          for ( ; sn < nsources; sn++) {
383 <                if (srccnt[sn].brt <= 0.0)
383 >                if (cntord[sn].brt <= 0.0)
384                          break;
385 <                dtmp = hwt * (double)source[srccnt[sn].sno].nhits /
386 <                                (double)source[srccnt[sn].sno].ntests;
387 <                scalecolor(srccnt[sn].val, dtmp);
388 <                addcolor(r->rcol, srccnt[sn].val);
385 >                prob = hwt * (double)source[cntord[sn].sno].nhits /
386 >                                (double)source[cntord[sn].sno].ntests;
387 >                scalecolor(srccnt[cntord[sn].sno].val, prob);
388 >                addcolor(r->rcol, srccnt[cntord[sn].sno].val);
389          }
390 + #ifdef DEBUG
391 +        fprintf(stderr, "%d tested, %d untested, %f hit rate\n",
392 +                        ntested, sn-ntested, hwt);
393 +        }
394 + #endif
395                  
396          free(srccnt);
397 +        free(cntord);
398   }
399  
400  
# Line 353 | Line 403 | char  *p;                      /* data for f */
403                                  source[r->rsrc].so!=r->ro)
404  
405   #define  badambient(m, r)       ((r->crtype&(AMBIENT|SHADOW))==AMBIENT && \
406 <                                !(r->rtype&REFLECTED))  /* hack! */
406 >                                !(r->rtype&REFLECTED) &&        /* hack! */\
407 >                                !(m->otype==MAT_GLOW&&r->rot>m->oargs.farg[3]))
408  
409   #define  passillum(m, r)        (m->otype==MAT_ILLUM && \
410                                  !(r->rsrc>=0&&source[r->rsrc].so==r->ro))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines