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 2.2 by greg, Thu Jan 9 09:53:00 1992 UTC vs.
Revision 2.5 by greg, Fri Aug 28 15:10:50 1992 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1991 Regents of the University of California */
1 > /* Copyright (c) 1992 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 41 | Line 41 | static int  maxcntr = 0;               /* size of contribution arra
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          }
# Line 117 | Line 120 | RAY  *r;                       /* ray which hit object */
120   SRCINDEX  *si;                  /* source sample index */
121   {
122      double  d;                          /* distance to source */
120    FVECT  vd;
123      register SRCREC  *srcp;
122    register int  i;
124  
125      rayorigin(sr, r, SHADOW, 1.0);              /* ignore limits */
126  
# Line 127 | Line 128 | SRCINDEX  *si;                 /* source sample index */
128          sr->rsrc = si->sn;                      /* remember source */
129          srcp = source + si->sn;
130          if (srcp->sflags & SDISTANT) {
131 <                if (srcp->sflags & SSPOT) {     /* check location */
132 <                        for (i = 0; i < 3; i++)
132 <                            vd[i] = srcp->sl.s->aim[i] - sr->rorg[i];
133 <                        d = DOT(sr->rdir,vd);
134 <                        if (d <= FTINY)
135 <                                continue;
136 <                        d = DOT(vd,vd) - d*d;
137 <                        if (PI*d > srcp->sl.s->siz)
138 <                                continue;
139 <                }
131 >                if (srcp->sflags & SSPOT && spotout(sr, srcp->sl.s, 1))
132 >                        continue;
133                  return(1);              /* sample OK */
134          }
135                                  /* local source */
# Line 145 | Line 138 | SRCINDEX  *si;                 /* source sample index */
138                  continue;
139                                                  /* check angle */
140          if (srcp->sflags & SSPOT) {
141 <                if (srcp->sl.s->siz < 2.0*PI *
149 <                                (1.0 + DOT(srcp->sl.s->aim,sr->rdir)))
141 >                if (spotout(sr, srcp->sl.s, 0))
142                          continue;
143                                          /* adjust solid angle */
144                  si->dom *= d*d;
# Line 191 | Line 183 | RAY  *r;
183   }
184  
185  
186 + sourcehit(r)                    /* check to see if ray hit distant source */
187 + register RAY  *r;
188 + {
189 +        int  first, last;
190 +        register int  i;
191 +
192 +        if (r->rsrc >= 0) {             /* check only one if aimed */
193 +                first = last = r->rsrc;
194 +        } else {                        /* otherwise check all */
195 +                first = 0; last = nsources-1;
196 +        }
197 +        for (i = first; i <= last; i++)
198 +                if ((source[i].sflags & (SDISTANT|SVIRTUAL)) == SDISTANT)
199 +                        /*
200 +                         * Check to see if ray is within
201 +                         * solid angle of source.
202 +                         */
203 +                        if (2.0*PI * (1.0 - DOT(source[i].sloc,r->rdir))
204 +                                        <= source[i].ss2) {
205 +                                r->ro = source[i].so;
206 +                                if (!(source[i].sflags & SSKIP))
207 +                                        break;
208 +                        }
209 +
210 +        if (r->ro != NULL) {
211 +                for (i = 0; i < 3; i++)
212 +                        r->ron[i] = -r->rdir[i];
213 +                r->rod = 1.0;
214 +                r->rox = NULL;
215 +                return(1);
216 +        }
217 +        return(0);
218 + }
219 +
220 +
221   static int
222   cntcmp(sc1, sc2)                        /* contribution compare (descending) */
223   register CNTPTR  *sc1, *sc2;
# Line 319 | Line 346 | char  *p;                      /* data for f */
346                  scalecolor(srccnt[cntord[sn].sndx].val, prob);
347                  addcolor(r->rcol, srccnt[cntord[sn].sndx].val);
348          }
349 + }
350 +
351 +
352 + /****************************************************************
353 + * The following macros were separated from the m_light() routine
354 + * because they are very nasty and difficult to understand.
355 + */
356 +
357 + /* wrongillum *
358 + *
359 + * We cannot allow an illum to pass to another illum, because that
360 + * would almost certainly constitute overcounting.
361 + * However, we do allow an illum to pass to another illum
362 + * that is actually going to relay to a virtual light source.
363 + */
364 +
365 + #define  wrongillum(m, r)       (!(source[r->rsrc].sflags&SVIRTUAL) && \
366 +                        objptr(source[r->rsrc].so->omod)->otype==MAT_ILLUM)
367 +
368 + /* wrongsource *
369 + *
370 + * This source is the wrong source (ie. overcounted) if we are
371 + * aimed to a different source than the one we hit and the one
372 + * we hit is not an illum which should be passed.
373 + */
374 +
375 + #define  wrongsource(m, r)      (r->rsrc>=0 && source[r->rsrc].so!=r->ro && \
376 +                                (m->otype!=MAT_ILLUM || wrongillum(m,r)))
377 +
378 + /* distglow *
379 + *
380 + * A distant glow is an object that sometimes acts as a light source,
381 + * but is too far away from the test point to be one in this case.
382 + */
383 +
384 + #define  distglow(m, r)         (m->otype==MAT_GLOW && \
385 +                                r->rot > m->oargs.farg[3])
386 +
387 + /* badcomponent *
388 + *
389 + * We must avoid counting light sources in the ambient calculation,
390 + * since the direct component is handled separately.  Therefore, any
391 + * ambient ray which hits an active light source must be discarded.
392 + * The same is true for stray specular samples, since the specular
393 + * contribution from light sources is calculated separately.
394 + */
395 +
396 + #define  badcomponent(m, r)     (r->crtype&(AMBIENT|SPECULAR) && \
397 +                                !(r->crtype&SHADOW || r->rod < 0.0 || \
398 +                                        distglow(m, r)))
399 +
400 + /* overcount *
401 + *
402 + * All overcounting possibilities are contained here.
403 + */
404 +
405 + #define  overcount(m, r)        (badcomponent(m,r) || wrongsource(m,r))
406 +
407 + /* passillum *
408 + *
409 + * An illum passes to another material type when we didn't hit it
410 + * on purpose (as part of a direct calculation), or it is relaying
411 + * a virtual light source.
412 + */
413 +
414 + #define  passillum(m, r)        (m->otype==MAT_ILLUM && \
415 +                                (r->rsrc<0 || source[r->rsrc].so!=r->ro || \
416 +                                source[r->rsrc].sflags&SVIRTUAL))
417 +
418 + /* srcignore *
419 + *
420 + * The -di flag renders light sources invisible, and here is the test.
421 + */
422 +
423 + #define  srcignore(m, r)        (directinvis && !(r->crtype&SHADOW) && \
424 +                                !distglow(m, r))
425 +
426 +
427 + m_light(m, r)                   /* ray hit a light source */
428 + register OBJREC  *m;
429 + register RAY  *r;
430 + {
431 +                                                /* check for over-counting */
432 +        if (overcount(m, r))
433 +                return;
434 +                                                /* check for passed illum */
435 +        if (passillum(m, r)) {
436 +                if (m->oargs.nsargs < 1 || !strcmp(m->oargs.sarg[0], VOIDID))
437 +                        raytrans(r);
438 +                else
439 +                        rayshade(r, modifier(m->oargs.sarg[0]));
440 +                return;
441 +        }
442 +                                        /* otherwise treat as source */
443 +                                                /* check for behind */
444 +        if (r->rod < 0.0)
445 +                return;
446 +                                                /* check for invisibility */
447 +        if (srcignore(m, r))
448 +                return;
449 +                                                /* check for outside spot */
450 +        if (m->otype==MAT_SPOT && spotout(r, (SPOT *)m->os, r->rot>=FHUGE))
451 +                return;
452 +                                                /* get distribution pattern */
453 +        raytexture(r, m->omod);
454 +                                                /* get source color */
455 +        setcolor(r->rcol, m->oargs.farg[0],
456 +                          m->oargs.farg[1],
457 +                          m->oargs.farg[2]);
458 +                                                /* modify value */
459 +        multcolor(r->rcol, r->pcol);
460   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines