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.1 by greg, Tue Nov 12 17:08:57 1991 UTC vs.
Revision 2.6 by greg, Fri Oct 2 16:20:09 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 209 | Line 236 | int  (*f)();                   /* direct component coefficient functio
236   char  *p;                       /* data for f */
237   {
238          extern int  (*trace)();
212        extern double  pow();
239          register int  sn;
240          SRCINDEX  si;
241          int  nshadcheck, ncnts;
# Line 261 | Line 287 | char  *p;                      /* data for f */
287                          l = m;
288                  }
289          }
290 +        if (ncnts == 0)
291 +                return;         /* no contributions! */
292                                                  /* accumulate tail */
293          for (sn = ncnts-1; sn > 0; sn--)
294                  cntord[sn-1].brt += cntord[sn].brt;
# Line 317 | Line 345 | char  *p;                      /* data for f */
345                  scalecolor(srccnt[cntord[sn].sndx].val, prob);
346                  addcolor(r->rcol, srccnt[cntord[sn].sndx].val);
347          }
348 + }
349 +
350 +
351 + /****************************************************************
352 + * The following macros were separated from the m_light() routine
353 + * because they are very nasty and difficult to understand.
354 + */
355 +
356 + /* wrongillum *
357 + *
358 + * We cannot allow an illum to pass to another illum, because that
359 + * would almost certainly constitute overcounting.
360 + * However, we do allow an illum to pass to another illum
361 + * that is actually going to relay to a virtual light source.
362 + */
363 +
364 + #define  wrongillum(m, r)       (!(source[r->rsrc].sflags&SVIRTUAL) && \
365 +                        objptr(source[r->rsrc].so->omod)->otype==MAT_ILLUM)
366 +
367 + /* wrongsource *
368 + *
369 + * This source is the wrong source (ie. overcounted) if we are
370 + * aimed to a different source than the one we hit and the one
371 + * we hit is not an illum which should be passed.
372 + */
373 +
374 + #define  wrongsource(m, r)      (r->rsrc>=0 && source[r->rsrc].so!=r->ro && \
375 +                                (m->otype!=MAT_ILLUM || wrongillum(m,r)))
376 +
377 + /* distglow *
378 + *
379 + * A distant glow is an object that sometimes acts as a light source,
380 + * but is too far away from the test point to be one in this case.
381 + */
382 +
383 + #define  distglow(m, r)         (m->otype==MAT_GLOW && \
384 +                                r->rot > m->oargs.farg[3])
385 +
386 + /* badcomponent *
387 + *
388 + * We must avoid counting light sources in the ambient calculation,
389 + * since the direct component is handled separately.  Therefore, any
390 + * ambient ray which hits an active light source must be discarded.
391 + * The same is true for stray specular samples, since the specular
392 + * contribution from light sources is calculated separately.
393 + */
394 +
395 + #define  badcomponent(m, r)     (r->crtype&(AMBIENT|SPECULAR) && \
396 +                                !(r->crtype&SHADOW || r->rod < 0.0 || \
397 +                                        distglow(m, r)))
398 +
399 + /* overcount *
400 + *
401 + * All overcounting possibilities are contained here.
402 + */
403 +
404 + #define  overcount(m, r)        (badcomponent(m,r) || wrongsource(m,r))
405 +
406 + /* passillum *
407 + *
408 + * An illum passes to another material type when we didn't hit it
409 + * on purpose (as part of a direct calculation), or it is relaying
410 + * a virtual light source.
411 + */
412 +
413 + #define  passillum(m, r)        (m->otype==MAT_ILLUM && \
414 +                                (r->rsrc<0 || source[r->rsrc].so!=r->ro || \
415 +                                source[r->rsrc].sflags&SVIRTUAL))
416 +
417 + /* srcignore *
418 + *
419 + * The -di flag renders light sources invisible, and here is the test.
420 + */
421 +
422 + #define  srcignore(m, r)        (directinvis && !(r->crtype&SHADOW) && \
423 +                                !distglow(m, r))
424 +
425 +
426 + m_light(m, r)                   /* ray hit a light source */
427 + register OBJREC  *m;
428 + register RAY  *r;
429 + {
430 +                                                /* check for over-counting */
431 +        if (overcount(m, r))
432 +                return;
433 +                                                /* check for passed illum */
434 +        if (passillum(m, r)) {
435 +                if (m->oargs.nsargs < 1 || !strcmp(m->oargs.sarg[0], VOIDID))
436 +                        raytrans(r);
437 +                else
438 +                        rayshade(r, modifier(m->oargs.sarg[0]));
439 +                return;
440 +        }
441 +                                        /* otherwise treat as source */
442 +                                                /* check for behind */
443 +        if (r->rod < 0.0)
444 +                return;
445 +                                                /* check for invisibility */
446 +        if (srcignore(m, r))
447 +                return;
448 +                                                /* check for outside spot */
449 +        if (m->otype==MAT_SPOT && spotout(r, (SPOT *)m->os, r->rot>=FHUGE))
450 +                return;
451 +                                                /* get distribution pattern */
452 +        raytexture(r, m->omod);
453 +                                                /* get source color */
454 +        setcolor(r->rcol, m->oargs.farg[0],
455 +                          m->oargs.farg[1],
456 +                          m->oargs.farg[2]);
457 +                                                /* modify value */
458 +        multcolor(r->rcol, r->pcol);
459   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines