ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_direct.c
Revision: 2.7
Committed: Fri Apr 12 16:49:39 1996 UTC (28 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.6: +2 -0 lines
Log Message:
added isflat() macro and computation of effective ray distance

File Contents

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