ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_direct.c
Revision: 2.11
Committed: Sun Jul 27 22:12:03 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.10: +2 -2 lines
Log Message:
Added grouping parens to reduce ambiguity warnings.

File Contents

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