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.46 by greg, Wed Sep 8 17:10:16 2004 UTC vs.
Revision 2.59 by greg, Thu Oct 28 09:38:46 2010 UTC

# Line 46 | Line 46 | extern OBJREC *                        /* find an object's actual material
46   findmaterial(register OBJREC *o)
47   {
48          while (!ismaterial(o->otype)) {
49                if (ismixture(o->otype))
50                        return(NULL);   /* reject mixed materials */
49                  if (o->otype == MOD_ALIAS && o->oargs.nsargs) {
50                          OBJECT  aobj;
51                          OBJREC  *ao;
# Line 57 | Line 55 | findmaterial(register OBJREC *o)
55                          ao = objptr(aobj);
56                          if (ismaterial(ao->otype))
57                                  return(ao);
58 +                        if (ao->otype == MOD_ALIAS) {
59 +                                o = ao;
60 +                                continue;
61 +                        }
62                  }
63                  if (o->omod == OVOID)
64                          return(NULL);
65                  o = objptr(o->omod);
66          }
67 <        return(o);
67 >        return(o);              /* mixtures will return NULL */
68   }
69  
70  
# Line 84 | Line 86 | marksources(void)                      /* find and mark source objects */
86                          continue;
87                                          /* find material */
88                  m = findmaterial(objptr(o->omod));
89 <                if (m == NULL || !islight(m->otype))
89 >                if (m == NULL)
90 >                        continue;
91 >                if (m->otype == MAT_CLIP) {
92 >                        markclip(m);    /* special case for antimatter */
93 >                        continue;
94 >                }
95 >                if (!islight(m->otype))
96                          continue;       /* not source modifier */
97          
98                  if (m->oargs.nfargs != (m->otype == MAT_GLOW ? 4 :
# Line 176 | Line 184 | srcray(                                /* send a ray to a source, return domega */
184          SRCINDEX  *si                   /* source sample index */
185   )
186   {
187 <    double  d;                          /* distance to source */
188 <    register SRCREC  *srcp;
187 >        double  d;                              /* distance to source */
188 >        register SRCREC  *srcp;
189  
190 <    rayorigin(sr, r, SHADOW, 1.0);              /* ignore limits */
190 >        rayorigin(sr, SHADOW, r, NULL);         /* ignore limits */
191  
192 <    while ((d = nextssamp(sr, si)) != 0.0) {
193 <        sr->rsrc = si->sn;                      /* remember source */
194 <        srcp = source + si->sn;
195 <        if (srcp->sflags & SDISTANT) {
196 <                if (srcp->sflags & SSPOT && spotout(sr, srcp->sl.s))
197 <                        continue;
198 <                return(1);              /* sample OK */
199 <        }
192 >        if (r == NULL)
193 >                sr->rmax = 0.0;
194 >
195 >        while ((d = nextssamp(sr, si)) != 0.0) {
196 >                sr->rsrc = si->sn;                      /* remember source */
197 >                srcp = source + si->sn;
198 >                if (srcp->sflags & SDISTANT) {
199 >                        if (srcp->sflags & SSPOT && spotout(sr, srcp->sl.s))
200 >                                continue;
201 >                        return(1);              /* sample OK */
202 >                }
203                                  /* local source */
204                                                  /* check proximity */
205 <        if (srcp->sflags & SPROX && d > srcp->sl.prox)
195 <                continue;
196 <                                                /* check angle */
197 <        if (srcp->sflags & SSPOT) {
198 <                if (spotout(sr, srcp->sl.s))
205 >                if (srcp->sflags & SPROX && d > srcp->sl.prox)
206                          continue;
207 +                                                /* check angle */
208 +                if (srcp->sflags & SSPOT) {
209 +                        if (spotout(sr, srcp->sl.s))
210 +                                continue;
211                                          /* adjust solid angle */
212 <                si->dom *= d*d;
213 <                d += srcp->sl.s->flen;
214 <                si->dom /= d*d;
212 >                        si->dom *= d*d;
213 >                        d += srcp->sl.s->flen;
214 >                        si->dom /= d*d;
215 >                }
216 >                return(1);                      /* sample OK */
217          }
218 <        return(1);                      /* sample OK */
206 <    }
207 <    return(0);                  /* no more samples */
218 >        return(0);                      /* no more samples */
219   }
220  
221  
# Line 250 | Line 261 | nomat:
261   }
262  
263  
264 + static int
265 + transillum(                     /* check if material is transparent illum */
266 +        OBJECT  obj
267 + )
268 + {
269 +        OBJREC *m = findmaterial(objptr(obj));
270 +        
271 +        if (m == NULL)
272 +                return(1);
273 +        if (m->otype != MAT_ILLUM)
274 +                return(0);
275 +        return(!m->oargs.nsargs || !strcmp(m->oargs.sarg[0], VOIDID));
276 + }
277 +
278 +
279   extern int
280   sourcehit(                      /* check to see if ray hit distant source */
281          register RAY  *r
282   )
283   {
284 +        int  glowsrc = -1;
285 +        int  transrc = -1;
286          int  first, last;
287          register int  i;
288  
# Line 263 | Line 291 | sourcehit(                     /* check to see if ray hit distant source
291          } else {                        /* otherwise check all */
292                  first = 0; last = nsources-1;
293          }
294 <        for (i = first; i <= last; i++)
295 <                if ((source[i].sflags & (SDISTANT|SVIRTUAL)) == SDISTANT)
296 <                        /*
297 <                         * Check to see if ray is within
298 <                         * solid angle of source.
299 <                         */
300 <                        if (2.0*PI * (1.0 - DOT(source[i].sloc,r->rdir))
301 <                                        <= source[i].ss2) {
302 <                                r->ro = source[i].so;
303 <                                if (!(source[i].sflags & SSKIP))
304 <                                        break;
305 <                        }
306 <
307 <        if (r->ro != NULL) {
308 <                r->robj = objndx(r->ro);
309 <                for (i = 0; i < 3; i++)
310 <                        r->ron[i] = -r->rdir[i];
311 <                r->rod = 1.0;
312 <                r->pert[0] = r->pert[1] = r->pert[2] = 0.0;
313 <                r->uv[0] = r->uv[1] = 0.0;
314 <                r->rox = NULL;
315 <                return(1);
294 >        for (i = first; i <= last; i++) {
295 >                if ((source[i].sflags & (SDISTANT|SVIRTUAL)) != SDISTANT)
296 >                        continue;
297 >                /*
298 >                 * Check to see if ray is within
299 >                 * solid angle of source.
300 >                 */
301 >                if (2.*PI*(1. - DOT(source[i].sloc,r->rdir)) > source[i].ss2)
302 >                        continue;
303 >                                        /* is it the only possibility? */
304 >                if (first == last) {
305 >                        r->ro = source[i].so;
306 >                        break;
307 >                }
308 >                /*
309 >                 * If it's a glow or transparent illum, just remember it.
310 >                 */
311 >                if (source[i].sflags & SSKIP) {
312 >                        if (glowsrc < 0)
313 >                                glowsrc = i;
314 >                        continue;
315 >                }
316 >                if (transillum(source[i].so->omod)) {
317 >                        if (transrc < 0)
318 >                                transrc = i;
319 >                        continue;
320 >                }
321 >                r->ro = source[i].so;   /* otherwise, use first hit */
322 >                break;
323          }
324 <        return(0);
324 >        /*
325 >         * Do we need fallback?
326 >         */
327 >        if (r->ro == NULL) {
328 >                if (transrc >= 0 && r->crtype & (AMBIENT|SPECULAR))
329 >                        return(0);      /* avoid overcounting */
330 >                if (glowsrc >= 0)
331 >                        r->ro = source[glowsrc].so;
332 >                else
333 >                        return(0);      /* nothing usable */
334 >        }
335 >        /*
336 >         * Make assignments.
337 >         */
338 >        r->robj = objndx(r->ro);
339 >        for (i = 0; i < 3; i++)
340 >                r->ron[i] = -r->rdir[i];
341 >        r->rod = 1.0;
342 >        r->pert[0] = r->pert[1] = r->pert[2] = 0.0;
343 >        r->uv[0] = r->uv[1] = 0.0;
344 >        r->rox = NULL;
345 >        return(1);
346   }
347  
348  
# Line 341 | Line 397 | direct(                                        /* add direct component */
397                  scp->sno = sr.rsrc;
398                                                  /* compute coefficient */
399                  (*f)(scp->coef, p, sr.rdir, si.dom);
400 <                cntord[sn].brt = bright(scp->coef);
400 >                cntord[sn].brt = intens(scp->coef);
401                  if (cntord[sn].brt <= 0.0)
402                          continue;
403   #if SHADCACHE
# Line 352 | Line 408 | direct(                                        /* add direct component */
408                  }
409   #endif
410                  VCOPY(scp->dir, sr.rdir);
411 +                copycolor(sr.rcoef, scp->coef);
412                                                  /* compute potential */
413                  sr.revf = srcvalue;
414                  rayvalue(&sr);
415 +                multcolor(sr.rcol, sr.rcoef);
416                  copycolor(scp->val, sr.rcol);
417 <                multcolor(scp->val, scp->coef);
360 <                cntord[sn].brt = bright(scp->val);
417 >                cntord[sn].brt = bright(sr.rcol);
418          }
419                                                  /* sort contributions */
420          qsort(cntord, sn, sizeof(CNTPTR), cntcmp);
# Line 395 | Line 452 | direct(                                        /* add direct component */
452                          break;
453                  scp = srccnt + cntord[sn].sndx;
454                                                  /* test for hit */
455 <                rayorigin(&sr, r, SHADOW, 1.0);
455 >                rayorigin(&sr, SHADOW, r, NULL);
456 >                copycolor(sr.rcoef, scp->coef);
457                  VCOPY(sr.rdir, scp->dir);
458                  sr.rsrc = scp->sno;
459                                                  /* keep statistics */
# Line 408 | Line 466 | direct(                                        /* add direct component */
466                                  source[scp->sno].sflags & SFOLLOW )) {
467                                                  /* follow entire path */
468                          raycont(&sr);
411                        rayparticipate(&sr);
469                          if (trace != NULL)
470                                  (*trace)(&sr);  /* trace execution */
471                          if (bright(sr.rcol) <= FTINY) {
# Line 420 | Line 477 | direct(                                        /* add direct component */
477   #endif
478                                  continue;       /* missed! */
479                          }
480 +                        rayparticipate(&sr);
481 +                        multcolor(sr.rcol, sr.rcoef);
482                          copycolor(scp->val, sr.rcol);
483 <                        multcolor(scp->val, scp->coef);
483 >                } else if (trace != NULL &&
484 >                        (source[scp->sno].sflags & (SDISTANT|SVIRTUAL|SFOLLOW))
485 >                                                == (SDISTANT|SFOLLOW) &&
486 >                                sourcehit(&sr) && rayshade(&sr, sr.ro->omod)) {
487 >                        (*trace)(&sr);          /* trace execution */
488 >                        /* skip call to rayparticipate() & scp->val update */
489                  }
490                                                  /* add contribution if hit */
491                  addcolor(r->rcol, scp->val);
# Line 443 | Line 507 | direct(                                        /* add direct component */
507                  scp = srccnt + cntord[sn].sndx;
508                  prob = hwt * (double)source[scp->sno].nhits /
509                                  (double)source[scp->sno].ntests;
510 <                if (prob > 1.0)
511 <                        prob = 1.0;
448 <                scalecolor(scp->val, prob);
510 >                if (prob < 1.0)
511 >                        scalecolor(scp->val, prob);
512                  addcolor(r->rcol, scp->val);
513          }
514   }
# Line 492 | Line 555 | srcscatter(                    /* compute source scattering into ray */
555                          sr.rorg[0] = r->rorg[0] + r->rdir[0]*t;
556                          sr.rorg[1] = r->rorg[1] + r->rdir[1]*t;
557                          sr.rorg[2] = r->rorg[2] + r->rdir[2]*t;
495                        sr.rmax = 0.;
558                          initsrcindex(&si);      /* sample ray to this source */
559                          si.sn = r->slights[i];
560                          nopart(&si, &sr);
# Line 553 | Line 615 | srcscatter(                    /* compute source scattering into ray */
615   static int
616   weaksrcmat(OBJECT obj)          /* identify material */
617   {
618 <        OBJREC *o = findmaterial(objptr(obj));
618 >        OBJREC *m = findmaterial(objptr(obj));
619          
620 <        if (o == NULL) return 0;
621 <        return((o->otype==MAT_ILLUM)|(o->otype==MAT_GLOW));
620 >        if (m == NULL) return(0);
621 >        return((m->otype==MAT_ILLUM) | (m->otype==MAT_GLOW));
622   }
623  
624   #define  illumblock(m, r)       (!(source[r->rsrc].sflags&SVIRTUAL) && \
# Line 624 | Line 686 | m_light(                               /* ray hit a light source */
686   )
687   {
688                                                  /* check for over-counting */
689 <        if (badcomponent(m, r))
689 >        if (badcomponent(m, r)) {
690 >                setcolor(r->rcoef, 0.0, 0.0, 0.0);
691                  return(1);
692 <        if (wrongsource(m, r))
692 >        }
693 >        if (wrongsource(m, r)) {
694 >                setcolor(r->rcoef, 0.0, 0.0, 0.0);
695                  return(1);
696 +        }
697                                                  /* check for passed illum */
698          if (passillum(m, r)) {
699                  if (m->oargs.nsargs && strcmp(m->oargs.sarg[0], VOIDID))
# Line 635 | Line 701 | m_light(                               /* ray hit a light source */
701                  raytrans(r);
702                  return(1);
703          }
704 +                                                /* check for invisibility */
705 +        if (srcignore(m, r)) {
706 +                setcolor(r->rcoef, 0.0, 0.0, 0.0);
707 +                return(1);
708 +        }
709                                          /* otherwise treat as source */
710                                                  /* check for behind */
711          if (r->rod < 0.0)
641                return(1);
642                                                /* check for invisibility */
643        if (srcignore(m, r))
712                  return(1);
713                                                  /* check for outside spot */
714          if (m->otype==MAT_SPOT && spotout(r, makespot(m)))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines