ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_mist.c
(Generate patch)

Comparing ray/src/rt/m_mist.c (file contents):
Revision 2.1 by greg, Fri Dec 8 21:27:10 1995 UTC vs.
Revision 2.16 by greg, Tue Sep 28 17:54:19 2004 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1995 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Mist volumetric material.
6   */
7  
8 < #include  "ray.h"
8 > #include "copyright.h"
9  
10 + #include <string.h>
11 +
12 + #include  "ray.h"
13   #include  "source.h"
14 + #include  "rtotypes.h"
15  
16   /*
17   *  A mist volume is used to specify a region in the scene where a certain
# Line 33 | Line 34 | static char SCCSid[] = "$SunId$ LBL";
34   *
35   *  Up to five real arguments may be given for MAT_MIST:
36   *
37 < *      [ext_r  ext_g  ext_b  [albedo [gecc]]]
37 > *      [ext_r  ext_g  ext_b  [albedo_r albedo_g albedo_b [gecc]]]
38   *
39   *  The primaries indicate medium extinction per unit length (absorption
40 < *  plus scattering).  The albedo is the ratio of scattering to extinction,
40 > *  plus scattering), which is added to the global extinction coefficient, set
41 > *  by the -me option.  The albedo is the ratio of scattering to extinction,
42   *  and is set globally by the -ma option (salbedo) and overridden here.
43   *  The Heyney-Greenstein eccentricity parameter (-mg seccg) indicates how much
44   *  scattering favors the forward direction.  A value of 0 means isotropic
45   *  scattering.  A value approaching 1 indicates strong forward scattering.
46   */
47  
48 < #define MAXSLIST        32              /* maximum sources to check */
48 > #ifndef  MAXSLIST
49 > #define  MAXSLIST       32      /* maximum sources to check */
50 > #endif
51 >
52   #define RELAYDELIM      '>'             /* relay delimiter character */
53  
54 < extern COLOR  cextinction;              /* global coefficient of extinction */
55 < extern double  salbedo;                 /* global scattering albedo */
56 < extern double  seccg;                   /* global scattering eccentricity */
54 > static int inslist(int  *sl, int  n);
55 > static int srcmatch(SRCREC  *sp, char  *id);
56 > static void add2slist(RAY  *r, int  *sl);
57  
58  
59   static int
60 < inslist(sl, n)          /* return index of source n if it's in list sl */
61 < register int  *sl;
62 < register int  n;
60 > inslist(                /* return index of source n if it's in list sl */
61 >        register int  *sl,
62 >        register int  n
63 > )
64   {
65          register int  i;
66  
# Line 66 | Line 72 | register int  n;
72  
73  
74   static int
75 < srcmatch(sn, id)        /* check for an id match on a light source */
76 < register int  sn;
77 < char  *id;
75 > srcmatch(       /* check for an id match on a light source */
76 >        register SRCREC  *sp,
77 >        register char  *id
78 > )
79   {
73        extern char  *index();
80          register char  *cp;
81 < again:
82 <        if (source[sn].so == NULL)              /* just in case */
83 <                return(0);
78 <        if ((cp = index(id, RELAYDELIM)) != NULL) {     /* relay source */
79 <                if (!(source[sn].sflags & SVIRTUAL))
81 >                                                /* check for relay sources */
82 >        while ((cp = strchr(id, RELAYDELIM)) != NULL) {
83 >                if (!(sp->sflags & SVIRTUAL) || sp->so == NULL)
84                          return(0);
85 <                *cp = '\0';
82 <                if (strcmp(id, source[sn].so->oname)) {
83 <                        *cp = RELAYDELIM;
85 >                if (strncmp(id, sp->so->oname, cp-id) || sp->so->oname[cp-id])
86                          return(0);
87 <                }
88 <                *cp = RELAYDELIM;
87 <                id = cp + 1;                            /* recurse */
88 <                sn = source[sn].sa.sv.sn;
89 <                goto again;
87 >                id = cp + 1;                            /* relay to next */
88 >                sp = source + sp->sa.sv.sn;
89          }
90 <        if (source[sn].sflags & SVIRTUAL)
90 >        if (sp->sflags & SVIRTUAL || sp->so == NULL)
91                  return(0);
92 <        return(!strcmp(id, source[sn].so->oname));
92 >        return(!strcmp(id, sp->so->oname));
93   }
94  
95  
96 < m_mist(m, r)            /* process a ray entering or leaving some mist */
97 < OBJREC  *m;
98 < register RAY  *r;
96 > static void
97 > add2slist(      /* add source list to ray's */
98 >        register RAY  *r,
99 >        register int  *sl
100 > )
101   {
102 +        static int  slspare[MAXSLIST+1];        /* in case of emergence */
103 +        register int  i;
104 +
105 +        if (sl == NULL || sl[0] == 0)           /* nothing to add */
106 +                return;
107 +        if (r->slights == NULL)
108 +                (r->slights = slspare)[0] = 0;  /* just once per ray path */
109 +        for (i = sl[0]; i > 0; i--)
110 +                if (!inslist(r->slights, sl[i])) {
111 +                        if (r->slights[0] >= MAXSLIST)
112 +                                error(INTERNAL,
113 +                                        "scattering source list overflow");
114 +                        r->slights[++r->slights[0]] = sl[i];
115 +                }
116 + }
117 +
118 +
119 + extern int
120 + m_mist(         /* process a ray entering or leaving some mist */
121 +        OBJREC  *m,
122 +        register RAY  *r
123 + )
124 + {
125          RAY  p;
126          int  *myslist = NULL;
127          int  newslist[MAXSLIST+1];
# Line 105 | Line 129 | register RAY  *r;
129          double  re, ge, be;
130          register int  i, j;
131                                          /* check arguments */
132 <        if (m->oargs.nfargs > 5)
132 >        if (m->oargs.nfargs > 7)
133                  objerror(m, USER, "bad arguments");
110        if (m->oargs.nsargs > MAXSLIST)
111                objerror(m, USER, "too many sources in list");
134                                          /* get source indices */
135          if (m->oargs.nsargs > 0 && (myslist = (int *)m->os) == NULL) {
136 +                if (m->oargs.nsargs > MAXSLIST)
137 +                        objerror(m, INTERNAL, "too many sources in list");
138                  myslist = (int *)malloc((m->oargs.nsargs+1)*sizeof(int));
139                  if (myslist == NULL)
140                          goto memerr;
141 <                myslist[0] = m->oargs.nsargs;   /* size is first in set */
142 <                for (j = myslist[0]; j > 0; j--) {
141 >                myslist[0] = 0;                 /* size is first in list */
142 >                for (j = 0; j < m->oargs.nsargs; j++) {
143                          i = nsources;           /* look up each source id */
144                          while (i--)
145 <                                if (srcmatch(i, m->oargs.sarg[j-1]))
145 >                                if (srcmatch(source+i, m->oargs.sarg[j]))
146                                          break;
147                          if (i < 0) {
148                                  sprintf(errmsg, "unknown source \"%s\"",
149 <                                                m->oargs.sarg[j-1]);
149 >                                                m->oargs.sarg[j]);
150                                  objerror(m, WARNING, errmsg);
151 +                        } else if (inslist(myslist, i)) {
152 +                                sprintf(errmsg, "duplicate source \"%s\"",
153 +                                                m->oargs.sarg[j]);
154 +                                objerror(m, WARNING, errmsg);
155                          } else
156 <                                myslist[j] = i;
156 >                                myslist[++myslist[0]] = i;
157                  }
158                  m->os = (char *)myslist;
159          }
# Line 141 | Line 169 | register RAY  *r;
169                  return(1);
170          VCOPY(p.rdir, r->rdir);
171          p.slights = newslist;
172 <        if (r->slights != NULL)
172 >        if (r->slights != NULL)                 /* copy old list if one */
173                  for (j = r->slights[0]; j >= 0; j--)
174                          p.slights[j] = r->slights[j];
175          else
176                  p.slights[0] = 0;
177          if (r->rod > 0.) {                      /* entering ray */
178                  addcolor(p.cext, mext);
179 <                if (m->oargs.nfargs > 3)
180 <                        p.albedo = m->oargs.farg[3];
181 <                if (m->oargs.nfargs > 4)
182 <                        p.gecc = m->oargs.farg[4];
183 <                if (myslist != NULL)                    /* add to list */
184 <                        for (j = myslist[0]; j > 0; j--)
157 <                                if (!inslist(p.slights, myslist[j])) {
158 <                                        if (p.slights[0] >= MAXSLIST)
159 <                                                error(USER,
160 <                                        "scattering source list overflow");
161 <                                        p.slights[++p.slights[0]] = myslist[j];
162 <                                }
179 >                if (m->oargs.nfargs > 5)
180 >                        setcolor(p.albedo, m->oargs.farg[3],
181 >                                        m->oargs.farg[4], m->oargs.farg[5]);
182 >                if (m->oargs.nfargs > 6)
183 >                        p.gecc = m->oargs.farg[6];
184 >                add2slist(&p, myslist);                 /* add to list */
185          } else {                                /* leaving ray */
164                re = colval(r->cext,RED) - colval(mext,RED);
165                ge = colval(r->cext,GRN) - colval(mext,GRN);
166                be = colval(r->cext,BLU) - colval(mext,BLU);
167                setcolor(p.cext, re<0. ? 0. : re,
168                                ge<0. ? 0. : ge,
169                                be<0. ? 0. : be);
170                if (m->oargs.nfargs > 3)
171                        p.albedo = salbedo;
172                if (m->oargs.nfargs > 4)
173                        p.gecc = seccg;
186                  if (myslist != NULL) {                  /* delete from list */
187                          for (j = myslist[0]; j > 0; j--)
188 <                                if (i = inslist(p.slights, myslist[j]))
188 >                                if ( (i = inslist(p.slights, myslist[j])) )
189                                          p.slights[i] = -1;
190                          for (i = 0, j = 1; j <= p.slights[0]; j++)
191                                  if (p.slights[j] != -1)
192                                          p.slights[++i] = p.slights[j];
193 +                        if (p.slights[0] - i < myslist[0]) {    /* fix old */
194 +                                addcolor(r->cext, mext);
195 +                                if (m->oargs.nfargs > 5)
196 +                                        setcolor(r->albedo, m->oargs.farg[3],
197 +                                        m->oargs.farg[4], m->oargs.farg[5]);
198 +                                if (m->oargs.nfargs > 6)
199 +                                        r->gecc = m->oargs.farg[6];
200 +                                add2slist(r, myslist);
201 +                        }
202                          p.slights[0] = i;
203                  }
204 +                if ((re = colval(r->cext,RED) - colval(mext,RED)) <
205 +                                colval(cextinction,RED))
206 +                        re = colval(cextinction,RED);
207 +                if ((ge = colval(r->cext,GRN) - colval(mext,GRN)) <
208 +                                colval(cextinction,GRN))
209 +                        ge = colval(cextinction,GRN);
210 +                if ((be = colval(r->cext,BLU) - colval(mext,BLU)) <
211 +                                colval(cextinction,BLU))
212 +                        be = colval(cextinction,BLU);
213 +                setcolor(p.cext, re, ge, be);
214 +                if (m->oargs.nfargs > 5)
215 +                        copycolor(p.albedo, salbedo);
216 +                if (m->oargs.nfargs > 6)
217 +                        p.gecc = seccg;
218          }
219          rayvalue(&p);                           /* calls rayparticipate() */
220          copycolor(r->rcol, p.rcol);             /* return value */
# Line 187 | Line 222 | register RAY  *r;
222          return(1);
223   memerr:
224          error(SYSTEM, "out of memory in m_mist");
225 +        return 0; /* pro forma return */
226   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines