ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_direct.c
Revision: 2.13
Committed: Tue Apr 19 01:15:06 2005 UTC (19 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad4R1, rad4R0, rad3R8, rad3R9
Changes since 2.12: +6 -5 lines
Log Message:
Extensive changes to enable rtrace -oTW option for tracking ray contributions

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.13 static const char RCSid[] = "$Id: m_direct.c,v 2.12 2004/03/30 16:13:01 schorsch Exp $";
3 greg 1.1 #endif
4     /*
5     * Routines for light-redirecting materials and
6     * their associated virtual light sources
7     */
8    
9 greg 2.9 #include "copyright.h"
10 greg 2.8
11 greg 1.1 #include "ray.h"
12     #include "otypes.h"
13 schorsch 2.12 #include "rtotypes.h"
14 greg 1.1 #include "source.h"
15 greg 2.2 #include "func.h"
16    
17 greg 1.1 /*
18     * The arguments for MAT_DIRECT1 are:
19     *
20 greg 1.3 * 5+ coef1 dx1 dy1 dz1 funcfile transform..
21 greg 1.1 * 0
22     * n A1 A2 .. An
23     *
24     * The arguments for MAT_DIRECT2 are:
25     *
26 greg 1.3 * 9+ coef1 dx1 dy1 dz1 coef2 dx2 dy2 dz2 funcfile transform..
27 greg 1.1 * 0
28     * n A1 A2 .. An
29     */
30    
31 schorsch 2.12 static int redirect(OBJREC *m, RAY *r, int n);
32     static int dir_proj(MAT4 pm, OBJREC *o, SRCREC *s, int n);
33 greg 2.8
34 greg 1.1 VSMATERIAL direct1_vs = {dir_proj, 1};
35     VSMATERIAL direct2_vs = {dir_proj, 2};
36    
37 greg 2.2 #define getdfunc(m) ( (m)->otype == MAT_DIRECT1 ? \
38     getfunc(m, 4, 0xf, 1) : \
39     getfunc(m, 8, 0xff, 1) )
40 greg 1.1
41 greg 1.6
42 schorsch 2.12 extern int
43     m_direct( /* shade redirected ray */
44     register OBJREC *m,
45     register RAY *r
46     )
47 greg 1.1 {
48     /* check if source ray */
49     if (r->rsrc >= 0 && source[r->rsrc].so != r->ro)
50 greg 2.4 return(1); /* got the wrong guy */
51 greg 1.1 /* compute first projection */
52     if (m->otype == MAT_DIRECT1 ||
53     (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 0))
54     redirect(m, r, 0);
55     /* compute second projection */
56     if (m->otype == MAT_DIRECT2 &&
57     (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 1))
58     redirect(m, r, 1);
59 greg 2.4 return(1);
60 greg 1.1 }
61    
62    
63 schorsch 2.12 static int
64     redirect( /* compute n'th ray redirection */
65     OBJREC *m,
66     RAY *r,
67     int n
68     )
69 greg 1.1 {
70 greg 2.2 MFUNC *mf;
71     register EPNODE **va;
72 greg 2.3 FVECT nsdir;
73 greg 1.1 RAY nr;
74     double coef;
75     register int j;
76     /* set up function */
77 greg 2.2 mf = getdfunc(m);
78     setfunc(m, r);
79 greg 2.3 /* 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 greg 2.6 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 greg 1.1 /* compute coefficient */
100     errno = 0;
101 greg 2.2 va = mf->ep + 4*n;
102     coef = evalue(va[0]);
103 greg 2.13 if ((errno == EDOM) | (errno == ERANGE))
104 greg 1.1 goto computerr;
105 greg 2.13 setcolor(nr.rcoef, coef, coef, coef);
106     if (rayorigin(&nr, TRANS, r, nr.rcoef) < 0)
107 greg 1.1 return(0);
108 greg 2.2 va++; /* compute direction */
109     for (j = 0; j < 3; j++) {
110     nr.rdir[j] = evalue(va[j]);
111 greg 2.10 if (errno == EDOM || errno == ERANGE)
112 greg 2.2 goto computerr;
113     }
114     if (mf->f != &unitxf)
115     multv3(nr.rdir, nr.rdir, mf->f->xfm);
116 greg 1.4 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 greg 1.1 /* compute value */
121     if (r->rsrc >= 0)
122     nr.rsrc = source[r->rsrc].sa.sv.sn;
123     rayvalue(&nr);
124 greg 2.13 multcolor(nr.rcol, nr.rcoef);
125 greg 1.1 addcolor(r->rcol, nr.rcol);
126 greg 2.7 if (r->ro != NULL && isflat(r->ro->otype))
127     r->rt = r->rot + nr.rt;
128 greg 1.1 return(1);
129     computerr:
130     objerror(m, WARNING, "compute error");
131     return(-1);
132     }
133    
134    
135 greg 2.8 static int
136 schorsch 2.12 dir_proj( /* compute a director's projection */
137     MAT4 pm,
138     OBJREC *o,
139     SRCREC *s,
140     int n
141     )
142 greg 1.1 {
143     RAY tr;
144 greg 2.2 OBJREC *m;
145     MFUNC *mf;
146     EPNODE **va;
147 greg 1.1 FVECT cent, newdir, nv, h;
148 greg 2.2 double coef, olddot, newdot, od;
149 greg 1.1 register int i, j;
150     /* initialize test ray */
151     getmaxdisk(cent, o);
152     if (s->sflags & SDISTANT)
153     for (i = 0; i < 3; i++) {
154     tr.rdir[i] = -s->sloc[i];
155     tr.rorg[i] = cent[i] - tr.rdir[i];
156     }
157     else {
158     for (i = 0; i < 3; i++) {
159     tr.rdir[i] = cent[i] - s->sloc[i];
160 greg 1.2 tr.rorg[i] = s->sloc[i];
161 greg 1.1 }
162     if (normalize(tr.rdir) == 0.0)
163     return(0); /* at source! */
164     }
165     od = getplaneq(nv, o);
166     olddot = DOT(tr.rdir, nv);
167     if (olddot <= FTINY && olddot >= -FTINY)
168     return(0); /* old dir parallels plane */
169 greg 2.5 tr.rmax = 0.0;
170 greg 2.13 rayorigin(&tr, PRIMARY, NULL, NULL);
171 greg 1.1 if (!(*ofun[o->otype].funp)(o, &tr))
172     return(0); /* no intersection! */
173     /* compute redirection */
174 greg 2.2 m = vsmaterial(o);
175     mf = getdfunc(m);
176     setfunc(m, &tr);
177 greg 2.3 varset("DxA", '=', 0.0);
178     varset("DyA", '=', 0.0);
179     varset("DzA", '=', 0.0);
180 greg 1.1 errno = 0;
181 greg 2.2 va = mf->ep + 4*n;
182     coef = evalue(va[0]);
183 greg 2.10 if (errno == EDOM || errno == ERANGE)
184 greg 1.1 goto computerr;
185 greg 2.2 if (coef <= FTINY)
186     return(0); /* insignificant */
187     va++;
188     for (i = 0; i < 3; i++) {
189     newdir[i] = evalue(va[i]);
190 greg 2.10 if (errno == EDOM || errno == ERANGE)
191 greg 2.2 goto computerr;
192     }
193     if (mf->f != &unitxf)
194     multv3(newdir, newdir, mf->f->xfm);
195 greg 1.4 /* normalization unnecessary */
196 greg 1.1 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 greg 1.4 h[i] = newdir[i]/newdot - tr.rdir[i]/olddot;
202 greg 1.1 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 schorsch 2.11 if ((newdot > 0.0) ^ (olddot > 0.0)) /* add mirroring */
209 greg 1.1 for (j = 0; j < 3; j++) {
210     for (i = 0; i < 3; i++)
211     pm[i][j] -= 2.*nv[i]*nv[j];
212     pm[3][j] += 2.*od*nv[j];
213     }
214     return(1);
215     computerr:
216     objerror(m, WARNING, "projection compute error");
217     return(0);
218     }