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

Comparing ray/src/rt/m_direct.c (file contents):
Revision 1.2 by greg, Tue Jul 16 15:56:54 1991 UTC vs.
Revision 2.13 by greg, Tue Apr 19 01:15:06 2005 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1991 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   * Routines for light-redirecting materials and
6   *   their associated virtual light sources
7   */
8  
9 < #include  "ray.h"
9 > #include "copyright.h"
10  
11 + #include  "ray.h"
12   #include  "otypes.h"
13 <
13 > #include  "rtotypes.h"
14   #include  "source.h"
15 + #include  "func.h"
16  
17   /*
18   * The arguments for MAT_DIRECT1 are:
19   *
20 < *      4+ coef1 dx1 dy1 dz1 transform..
20 > *      5+ coef1 dx1 dy1 dz1 funcfile transform..
21   *      0
22   *      n A1 A2 .. An
23   *
24   * The arguments for MAT_DIRECT2 are:
25   *
26 < *      8+ coef1 dx1 dy1 dz1 coef2 dx2 dy2 dz2 transform..
26 > *      9+ coef1 dx1 dy1 dz1 coef2 dx2 dy2 dz2 funcfile transform..
27   *      0
28   *      n A1 A2 .. An
29   */
30  
31 + static int redirect(OBJREC  *m, RAY  *r, int  n);
32 + static int dir_proj(MAT4  pm, OBJREC  *o, SRCREC  *s, int  n);
33  
33 extern double  varvalue();
34
35 int  dir_proj();
34   VSMATERIAL  direct1_vs = {dir_proj, 1};
35   VSMATERIAL  direct2_vs = {dir_proj, 2};
36  
37 + #define getdfunc(m)     ( (m)->otype == MAT_DIRECT1 ? \
38 +                                getfunc(m, 4, 0xf, 1) : \
39 +                                getfunc(m, 8, 0xff, 1) )
40  
41 < m_direct(m, r)                  /* shade redirected ray */
42 < register OBJREC  *m;
43 < register RAY  *r;
41 >
42 > extern int
43 > m_direct(                       /* shade redirected ray */
44 >        register OBJREC  *m,
45 >        register RAY  *r
46 > )
47   {
48                                          /* check if source ray */
49          if (r->rsrc >= 0 && source[r->rsrc].so != r->ro)
50 <                return;                         /* got the wrong guy */
50 >                return(1);                      /* got the wrong guy */
51                                          /* compute first projection */
52          if (m->otype == MAT_DIRECT1 ||
53                          (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 0))
# Line 52 | Line 56 | register RAY  *r;
56          if (m->otype == MAT_DIRECT2 &&
57                          (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 1))
58                  redirect(m, r, 1);
59 +        return(1);
60   }
61  
62  
63 < redirect(m, r, n)               /* compute n'th ray redirection */
64 < OBJREC  *m;
65 < RAY  *r;
66 < int  n;
63 > static int
64 > redirect(               /* compute n'th ray redirection */
65 >        OBJREC  *m,
66 >        RAY  *r,
67 >        int  n
68 > )
69   {
70 <        register char  **sa;
70 >        MFUNC  *mf;
71 >        register EPNODE  **va;
72 >        FVECT  nsdir;
73          RAY  nr;
74          double  coef;
75          register int  j;
76                                          /* set up function */
77 +        mf = getdfunc(m);
78          setfunc(m, r);
79 <        if (m->oargs.nsargs < 4+4*n)
80 <                objerror(m, USER, "too few arguments");
81 <        sa = m->oargs.sarg + 4*n;
79 >                                        /* assign direction variable */
80 >        if (r->rsrc >= 0) {
81 >                register SRCREC  *sp = source + source[r->rsrc].sa.sv.sn;
82 >
83 >                if (sp->sflags & SDISTANT)
84 >                        VCOPY(nsdir, sp->sloc);
85 >                else {
86 >                        for (j = 0; j < 3; j++)
87 >                                nsdir[j] = sp->sloc[j] - r->rop[j];
88 >                        normalize(nsdir);
89 >                }
90 >                multv3(nsdir, nsdir, funcxf.xfm);
91 >                varset("DxA", '=', nsdir[0]/funcxf.sca);
92 >                varset("DyA", '=', nsdir[1]/funcxf.sca);
93 >                varset("DzA", '=', nsdir[2]/funcxf.sca);
94 >        } else {
95 >                varset("DxA", '=', 0.0);
96 >                varset("DyA", '=', 0.0);
97 >                varset("DzA", '=', 0.0);
98 >        }
99                                          /* compute coefficient */
100          errno = 0;
101 <        coef = varvalue(sa[0]);
102 <        if (errno)
101 >        va = mf->ep + 4*n;
102 >        coef = evalue(va[0]);
103 >        if ((errno == EDOM) | (errno == ERANGE))
104                  goto computerr;
105 <        if (coef <= FTINY || rayorigin(&nr, r, TRANS, coef) < 0)
105 >        setcolor(nr.rcoef, coef, coef, coef);
106 >        if (rayorigin(&nr, TRANS, r, nr.rcoef) < 0)
107                  return(0);
108 <                                        /* compute direction */
109 <        errno = 0;
110 <        for (j = 0; j < 3; j++)
111 <                nr.rdir[j] = varvalue(sa[j+1]);
112 <        if (errno || normalize(nr.rdir) == 0.0)
108 >        va++;                           /* compute direction */
109 >        for (j = 0; j < 3; j++) {
110 >                nr.rdir[j] = evalue(va[j]);
111 >                if (errno == EDOM || errno == ERANGE)
112 >                        goto computerr;
113 >        }
114 >        if (mf->f != &unitxf)
115 >                multv3(nr.rdir, nr.rdir, mf->f->xfm);
116 >        if (r->rox != NULL)
117 >                multv3(nr.rdir, nr.rdir, r->rox->f.xfm);
118 >        if (normalize(nr.rdir) == 0.0)
119                  goto computerr;
120                                          /* compute value */
121          if (r->rsrc >= 0)
122                  nr.rsrc = source[r->rsrc].sa.sv.sn;
123          rayvalue(&nr);
124 <        scalecolor(nr.rcol, coef);
124 >        multcolor(nr.rcol, nr.rcoef);
125          addcolor(r->rcol, nr.rcol);
126 +        if (r->ro != NULL && isflat(r->ro->otype))
127 +                r->rt = r->rot + nr.rt;
128          return(1);
129   computerr:
130          objerror(m, WARNING, "compute error");
# Line 95 | Line 132 | computerr:
132   }
133  
134  
135 < dir_proj(pm, o, s, n)           /* compute a director's projection */
136 < MAT4  pm;
137 < OBJREC  *o;
138 < SRCREC  *s;
139 < int  n;
135 > static int
136 > dir_proj(               /* compute a director's projection */
137 >        MAT4  pm,
138 >        OBJREC  *o,
139 >        SRCREC  *s,
140 >        int  n
141 > )
142   {
143          RAY  tr;
144 <        register OBJREC  *m;
145 <        char  **sa;
144 >        OBJREC  *m;
145 >        MFUNC  *mf;
146 >        EPNODE  **va;
147          FVECT  cent, newdir, nv, h;
148 <        double  olddot, newdot, od;
148 >        double  coef, olddot, newdot, od;
149          register int  i, j;
110                                /* get material arguments */
111        m = objptr(o->omod);
112        if (m->oargs.nsargs < 4+4*n)
113                objerror(m, USER, "too few arguments");
114        sa = m->oargs.sarg + 4*n;
150                                  /* initialize test ray */
151          getmaxdisk(cent, o);
152          if (s->sflags & SDISTANT)
# Line 131 | Line 166 | int  n;
166          olddot = DOT(tr.rdir, nv);
167          if (olddot <= FTINY && olddot >= -FTINY)
168                  return(0);              /* old dir parallels plane */
169 <        rayorigin(&tr, NULL, PRIMARY, 1.0);
169 >        tr.rmax = 0.0;
170 >        rayorigin(&tr, PRIMARY, NULL, NULL);
171          if (!(*ofun[o->otype].funp)(o, &tr))
172                  return(0);              /* no intersection! */
173                                  /* compute redirection */
174 +        m = vsmaterial(o);
175 +        mf = getdfunc(m);
176          setfunc(m, &tr);
177 +        varset("DxA", '=', 0.0);
178 +        varset("DyA", '=', 0.0);
179 +        varset("DzA", '=', 0.0);
180          errno = 0;
181 <        if (varvalue(sa[0]) <= FTINY)
182 <                return(0);              /* insignificant */
183 <        if (errno)
181 >        va = mf->ep + 4*n;
182 >        coef = evalue(va[0]);
183 >        if (errno == EDOM || errno == ERANGE)
184                  goto computerr;
185 <        for (i = 0; i < 3; i++)
186 <                newdir[i] = varvalue(sa[i+1]);
187 <        if (errno)
188 <                goto computerr;
185 >        if (coef <= FTINY)
186 >                return(0);              /* insignificant */
187 >        va++;
188 >        for (i = 0; i < 3; i++) {
189 >                newdir[i] = evalue(va[i]);
190 >                if (errno == EDOM || errno == ERANGE)
191 >                        goto computerr;
192 >        }
193 >        if (mf->f != &unitxf)
194 >                multv3(newdir, newdir, mf->f->xfm);
195 >                                        /* normalization unnecessary */
196          newdot = DOT(newdir, nv);
197          if (newdot <= FTINY && newdot >= -FTINY)
198                  return(0);              /* new dir parallels plane */
199                                  /* everything OK -- compute shear */
200          for (i = 0; i < 3; i++)
201 <                h[i] = tr.rdir[i]/olddot + newdir[i]/newdot;
201 >                h[i] = newdir[i]/newdot - tr.rdir[i]/olddot;
202          setident4(pm);
203          for (j = 0; j < 3; j++) {
204                  for (i = 0; i < 3; i++)
205                          pm[i][j] += nv[i]*h[j];
206                  pm[3][j] = -od*h[j];
207          }
208 <        if (newdot > 0.0 ^ olddot > 0.0)        /* add mirroring */
208 >        if ((newdot > 0.0) ^ (olddot > 0.0))    /* add mirroring */
209                  for (j = 0; j < 3; j++) {
210                          for (i = 0; i < 3; i++)
211                                  pm[i][j] -= 2.*nv[i]*nv[j];

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines