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.3 by greg, Thu Apr 27 12:44:13 1989 UTC vs.
Revision 1.4 by greg, Wed Jun 7 08:35:32 1989 UTC

# Line 12 | Line 12 | static char SCCSid[] = "$SunId$ LBL";
12  
13   #include  "ray.h"
14  
15 + #include  "octree.h"
16 +
17   #include  "source.h"
18  
19   #include  "otypes.h"
# Line 24 | Line 26 | static char SCCSid[] = "$SunId$ LBL";
26  
27  
28   extern double  dstrsrc;                 /* source distribution amount */
29 + extern double  shadthresh;              /* relative shadow threshold */
30  
31 < SOURCE  srcval[MAXSOURCE];              /* our array of sources */
31 > SRCREC  *source = NULL;                 /* our list of sources */
32   int  nsources = 0;                      /* the number of sources */
33  
34  
# Line 45 | 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 &&
49 <                                m->otype != MAT_SPOT)
51 >                                m->otype != MAT_GLOW)
52                          continue;
53          
54 <                if (m->oargs.nfargs != (m->otype == MAT_GLOW ? 4 :
53 <                                m->otype == MAT_SPOT ? 7 : 3))
54 >                if (m->oargs.nfargs != 3)
55                          objerror(m, USER, "bad # arguments");
56  
57 <                if (m->otype == MAT_GLOW &&
57 <                                o->otype != OBJ_SOURCE &&
58 <                                m->oargs.farg[3] <= FTINY)
57 >                if (m->otype == MAT_GLOW && o->otype != OBJ_SOURCE)
58                          continue;                       /* don't bother */
59  
60 <                if (nsources >= MAXSOURCE)
61 <                        error(INTERNAL, "too many sources in marksources");
60 >                if (source == NULL)
61 >                        source = (SRCREC *)malloc(sizeof(SRCREC));
62 >                else
63 >                        source = (SRCREC *)realloc((char *)source,
64 >                                        (unsigned)(nsources+1)*sizeof(SRCREC));
65 >                if (source == NULL)
66 >                        error(SYSTEM, "out of memory in marksources");
67  
68 <                newsource(&srcval[nsources], o);
68 >                newsource(&source[nsources], o);
69  
70 <                if (m->otype == MAT_GLOW) {
71 <                        srcval[nsources].sflags |= SPROX;
72 <                        srcval[nsources].sl.prox = m->oargs.farg[3];
69 <                        if (o->otype == OBJ_SOURCE)
70 <                                srcval[nsources].sflags |= SSKIP;
71 <                } else if (m->otype == MAT_SPOT) {
72 <                        srcval[nsources].sflags |= SSPOT;
73 <                        srcval[nsources].sl.s = makespot(m);
74 <                }
70 >                if (m->otype == MAT_GLOW)
71 >                        source[nsources].sflags |= SSKIP;
72 >
73                  nsources++;
74          }
75   }
76  
77  
78   newsource(src, so)                      /* add a source to the array */
79 < register SOURCE  *src;
79 > register SRCREC  *src;
80   register OBJREC  *so;
81   {
82          double  cos(), tan(), sqrt();
# Line 89 | Line 87 | register OBJREC  *so;
87          register int  i;
88          
89          src->sflags = 0;
90 +        src->nhits = src->ntests = 1;   /* start with hit probability = 1 */
91          src->so = so;
92  
93          switch (so->otype) {
# Line 140 | Line 139 | register OBJREC  *so;
139   }
140  
141  
143 SPOT *
144 makespot(m)                     /* make a spotlight */
145 register OBJREC  *m;
146 {
147        extern double  cos();
148        register SPOT  *ns;
149
150        if ((ns = (SPOT *)malloc(sizeof(SPOT))) == NULL)
151                error(SYSTEM, "out of memory in makespot");
152        ns->siz = 2.0*PI * (1.0 - cos(PI/180.0/2.0 * m->oargs.farg[3]));
153        VCOPY(ns->aim, m->oargs.farg+4);
154        if ((ns->flen = normalize(ns->aim)) == 0.0)
155                objerror(m, USER, "zero focus vector");
156        return(ns);
157 }
158
159
142   double
143   srcray(sr, r, sn)               /* send a ray to a source, return domega */
144   register RAY  *sr;              /* returned source ray */
# Line 169 | Line 151 | register int  sn;              /* source number */
151          double  d;
152          register int  i;
153  
154 <        if (srcval[sn].sflags & SSKIP)
154 >        if (source[sn].sflags & SSKIP)
155                  return(0.0);                    /* skip this source */
156  
157          rayorigin(sr, r, SHADOW, 1.0);          /* ignore limits */
158  
159          sr->rsrc = sn;                          /* remember source */
160                                                  /* get source direction */
161 <        if (srcval[sn].sflags & SDISTANT)
161 >        if (source[sn].sflags & SDISTANT)
162                                                  /* constant direction */
163 <                VCOPY(sr->rdir, srcval[sn].sloc);
163 >                VCOPY(sr->rdir, source[sn].sloc);
164          else {                                  /* compute direction */
165                  for (i = 0; i < 3; i++)
166 <                        sr->rdir[i] = srcval[sn].sloc[i] - sr->rorg[i];
166 >                        sr->rdir[i] = source[sn].sloc[i] - sr->rorg[i];
167  
168 <                if (srcval[sn].so->otype == OBJ_FACE)
169 <                        norm = getface(srcval[sn].so)->norm;
170 <                else if (srcval[sn].so->otype == OBJ_RING)
171 <                        norm = getcone(srcval[sn].so,0)->ad;
168 >                if (source[sn].so->otype == OBJ_FACE)
169 >                        norm = getface(source[sn].so)->norm;
170 >                else if (source[sn].so->otype == OBJ_RING)
171 >                        norm = getcone(source[sn].so,0)->ad;
172  
173                  if (norm != NULL && (ddot = -DOT(sr->rdir, norm)) <= FTINY)
174                          return(0.0);            /* behind surface! */
# Line 194 | Line 176 | register int  sn;              /* source number */
176          if (dstrsrc > FTINY) {
177                                          /* distribute source direction */
178                  for (i = 0; i < 3; i++)
179 <                        vd[i] = dstrsrc * srcval[sn].ss * (1.0 - 2.0*frandom());
179 >                        vd[i] = dstrsrc * source[sn].ss * (1.0 - 2.0*frandom());
180  
181                  if (norm != NULL) {             /* project offset */
182                          d = DOT(vd, norm);
# Line 204 | Line 186 | register int  sn;              /* source number */
186                  for (i = 0; i < 3; i++)         /* offset source direction */
187                          sr->rdir[i] += vd[i];
188  
189 <        } else if (srcval[sn].sflags & SDISTANT)
189 >        } else if (source[sn].sflags & SDISTANT)
190                                                  /* already normalized */
191 <                return(srcval[sn].ss2);
191 >                return(source[sn].ss2);
192  
193          if ((d = normalize(sr->rdir)) == 0.0)
194                                                  /* at source! */
195                  return(0.0);
196          
197 <        if (srcval[sn].sflags & SDISTANT)
197 >        if (source[sn].sflags & SDISTANT)
198                                                  /* domega constant */
199 <                return(srcval[sn].ss2);
199 >                return(source[sn].ss2);
200  
201          else {
220                                                /* check proximity */
221                if (srcval[sn].sflags & SPROX &&
222                                d > srcval[sn].sl.prox)
223                        return(0.0);
202  
203                  if (norm != NULL)
204                          ddot /= d;
205                  else
206                          ddot = 1.0;
229                                                /* check angle */
230                if (srcval[sn].sflags & SSPOT) {
231                        if (srcval[sn].sl.s->siz < 2.0*PI *
232                                (1.0 + DOT(srcval[sn].sl.s->aim,sr->rdir)))
233                                return(0.0);
234                        d += srcval[sn].sl.s->flen;
235                }
207                                                  /* return domega */
208 <                return(ddot*srcval[sn].ss2/(d*d));
208 >                return(ddot*source[sn].ss2/(d*d));
209          }
210   }
211  
# Line 251 | Line 222 | register RAY  *r;
222                  first = 0; last = nsources-1;
223          }
224          for (i = first; i <= last; i++)
225 <                if (srcval[i].sflags & SDISTANT)
225 >                if (source[i].sflags & SDISTANT)
226                          /*
227                           * Check to see if ray is within
228                           * solid angle of source.
229                           */
230 <                        if (2.0*PI * (1.0 - DOT(srcval[i].sloc,r->rdir))
231 <                                        <= srcval[i].ss2) {
232 <                                r->ro = srcval[i].so;
233 <                                if (!(srcval[i].sflags & SSKIP))
230 >                        if (2.0*PI * (1.0 - DOT(source[i].sloc,r->rdir))
231 >                                        <= source[i].ss2) {
232 >                                r->ro = source[i].so;
233 >                                if (!(source[i].sflags & SSKIP))
234                                          break;
235                          }
236  
# Line 275 | Line 246 | register RAY  *r;
246   }
247  
248  
249 + static int
250 + cntcmp(sc1, sc2)                        /* contribution compare (descending) */
251 + register CONTRIB  *sc1, *sc2;
252 + {
253 +        if (sc1->brt > sc2->brt)
254 +                return(-1);
255 +        if (sc1->brt < sc2->brt)
256 +                return(1);
257 +        return(0);
258 + }
259 +
260 +
261 + direct(r, f, p)                         /* add direct component */
262 + RAY  *r;                        /* ray that hit surface */
263 + int  (*f)();                    /* direct component coefficient function */
264 + char  *p;                       /* data for f */
265 + {
266 +        register int  sn;
267 +        register CONTRIB  *srccnt;
268 +        double  dtmp, hwt, test2, hit2;
269 +        RAY  sr;
270 +
271 +        if ((srccnt = (CONTRIB *)malloc(nsources*sizeof(CONTRIB))) == NULL)
272 +                error(SYSTEM, "out of memory in direct");
273 +                                                /* potential contributions */
274 +        for (sn = 0; sn < nsources; sn++) {
275 +                srccnt[sn].sno = sn;
276 +                setcolor(srccnt[sn].val, 0.0, 0.0, 0.0);
277 +                                                /* get source ray */
278 +                if ((srccnt[sn].dom = srcray(&sr, r, sn)) == 0.0)
279 +                        continue;
280 +                VCOPY(srccnt[sn].dir, sr.rdir);
281 +                                                /* compute coefficient */
282 +                (*f)(srccnt[sn].val, p, srccnt[sn].dir, srccnt[sn].dom);
283 +                srccnt[sn].brt = intens(srccnt[sn].val);
284 +                if (srccnt[sn].brt <= FTINY)
285 +                        continue;
286 +                                                /* compute intersection */
287 +                if (!( source[sn].sflags & SDISTANT ?
288 +                                sourcehit(&sr) :
289 +                                (*ofun[source[sn].so->otype].funp)
290 +                                (source[sn].so, &sr) ))
291 +                        continue;
292 +                                                /* compute contribution */
293 +                rayshade(&sr, sr.ro->omod);
294 +                multcolor(srccnt[sn].val, sr.rcol);
295 +                srccnt[sn].brt = intens(srccnt[sn].val);
296 +        }
297 +                                                /* sort contributions */
298 +        qsort(srccnt, nsources, sizeof(CONTRIB), cntcmp);
299 +        hit2 = test2 = 0.0;
300 +                                                /* test for shadows */
301 +        for (sn = 0; sn < nsources; sn++) {
302 +                                                /* check threshold */
303 +                if (srccnt[sn].brt <= shadthresh*intens(r->rcol)/r->rweight)
304 +                        break;
305 +                                                /* get statistics */
306 +                hwt = (double)source[srccnt[sn].sno].nhits /
307 +                                (double)source[srccnt[sn].sno].ntests;
308 +                test2 += hwt;
309 +                source[srccnt[sn].sno].ntests++;
310 +                                                /* test for hit */
311 +                rayorigin(&sr, r, SHADOW, 1.0);
312 +                VCOPY(sr.rdir, srccnt[sn].dir);
313 +                if (localhit(&sr, &thescene) &&
314 +                                sr.ro != source[srccnt[sn].sno].so) {
315 +                                                /* check for transmission */
316 +                        if (sr.clipset != NULL && inset(sr.clipset,sr.ro->omod))
317 +                                raytrans(&sr);          /* object is clipped */
318 +                        else
319 +                                rayshade(&sr, sr.ro->omod);
320 +                        if (intens(sr.rcol) <= FTINY)
321 +                                continue;       /* missed! */
322 +                        (*f)(srccnt[sn].val, p, srccnt[sn].dir, srccnt[sn].dom);
323 +                        multcolor(srccnt[sn].val, sr.rcol);
324 +                }
325 +                                                /* add contribution if hit */
326 +                addcolor(r->rcol, srccnt[sn].val);
327 +                hit2 += hwt;
328 +                source[srccnt[sn].sno].nhits++;
329 +        }
330 +        if (test2 > FTINY)              /* weighted hit rate */
331 +                hwt = hit2 / test2;
332 +        else
333 +                hwt = 0.0;
334 + #ifdef DEBUG
335 +        fprintf(stderr, "%d tested, %f hit rate\n", sn, hwt);
336 + #endif
337 +                                        /* add in untested sources */
338 +        for ( ; sn < nsources; sn++) {
339 +                if (srccnt[sn].brt <= 0.0)
340 +                        break;
341 +                dtmp = hwt * (double)source[srccnt[sn].sno].nhits /
342 +                                (double)source[srccnt[sn].sno].ntests;
343 +                scalecolor(srccnt[sn].val, dtmp);
344 +                addcolor(r->rcol, srccnt[sn].val);
345 +        }
346 +                
347 +        free(srccnt);
348 + }
349 +
350 +
351   #define  wrongsource(m, r)      (m->otype!=MAT_ILLUM && \
352                                  r->rsrc>=0 && \
353 <                                srcval[r->rsrc].so!=r->ro)
353 >                                source[r->rsrc].so!=r->ro)
354  
355   #define  badambient(m, r)       ((r->crtype&(AMBIENT|SHADOW))==AMBIENT && \
356 <                                !(r->rtype&REFLECTED) &&        /* hack! */\
284 <                                !(m->otype==MAT_GLOW&&r->rot>m->oargs.farg[3]))
356 >                                !(r->rtype&REFLECTED))  /* hack! */
357  
358   #define  passillum(m, r)        (m->otype==MAT_ILLUM && \
359 <                                !(r->rsrc>=0&&srcval[r->rsrc].so==r->ro))
359 >                                !(r->rsrc>=0&&source[r->rsrc].so==r->ro))
360  
361  
362   m_light(m, r)                   /* ray hit a light source */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines