ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_direct.c
Revision: 1.6
Committed: Fri Nov 8 14:30:17 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +30 -27 lines
Log Message:
fixed bug in call to funcfile()

File Contents

# Content
1 /* Copyright (c) 1991 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 /*
19 * The arguments for MAT_DIRECT1 are:
20 *
21 * 5+ coef1 dx1 dy1 dz1 funcfile transform..
22 * 0
23 * n A1 A2 .. An
24 *
25 * The arguments for MAT_DIRECT2 are:
26 *
27 * 9+ coef1 dx1 dy1 dz1 coef2 dx2 dy2 dz2 funcfile transform..
28 * 0
29 * n A1 A2 .. An
30 */
31
32
33 extern double varvalue();
34
35 int dir_proj();
36 VSMATERIAL direct1_vs = {dir_proj, 1};
37 VSMATERIAL direct2_vs = {dir_proj, 2};
38
39 #define fndx(m) ((m)->otype == MAT_DIRECT1 ? 4 : 8)
40
41
42 static
43 dir_check(m) /* check arguments and load function file */
44 register OBJREC *m;
45 {
46 register FULLXF *mxf;
47 register int ff;
48
49 ff = fndx(m)+1;
50 if (ff > m->oargs.nsargs)
51 objerror(m, USER, "too few arguments");
52 if (m->os == NULL) {
53 mxf = (FULLXF *)malloc(sizeof(FULLXF));
54 if (mxf == NULL)
55 error(SYSTEM, "out of memory in dir_check");
56 if (fullxf(mxf, m->oargs.nsargs-ff, m->oargs.sarg+ff) !=
57 m->oargs.nsargs-ff)
58 objerror(m, USER, "bad transform");
59 if (mxf->f.sca < 0.0)
60 mxf->f.sca = -mxf->f.sca;
61 if (mxf->b.sca < 0.0)
62 mxf->b.sca = -mxf->b.sca;
63 m->os = (char *)mxf;
64 }
65 }
66
67
68 m_direct(m, r) /* shade redirected ray */
69 register OBJREC *m;
70 register RAY *r;
71 {
72 /* check if source ray */
73 if (r->rsrc >= 0 && source[r->rsrc].so != r->ro)
74 return; /* got the wrong guy */
75 dir_check(m);
76 /* compute first projection */
77 if (m->otype == MAT_DIRECT1 ||
78 (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 0))
79 redirect(m, r, 0);
80 /* compute second projection */
81 if (m->otype == MAT_DIRECT2 &&
82 (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 1))
83 redirect(m, r, 1);
84 }
85
86
87 redirect(m, r, n) /* compute n'th ray redirection */
88 OBJREC *m;
89 RAY *r;
90 int n;
91 {
92 register char **sa;
93 RAY nr;
94 double coef;
95 register int j;
96 /* set up function */
97 setmap(m, r, &((FULLXF *)m->os)->b);
98 funcfile(m->oargs.sarg[fndx(m)]);
99 sa = m->oargs.sarg + 4*n;
100 /* compute coefficient */
101 errno = 0;
102 coef = varvalue(sa[0]);
103 if (errno)
104 goto computerr;
105 if (coef <= FTINY || rayorigin(&nr, r, TRANS, coef) < 0)
106 return(0);
107 /* compute direction */
108 errno = 0;
109 for (j = 0; j < 3; j++)
110 nr.rdir[j] = varvalue(sa[j+1]);
111 if (errno)
112 goto computerr;
113 multv3(nr.rdir, nr.rdir, ((FULLXF *)m->os)->f.xfm);
114 if (r->rox != NULL)
115 multv3(nr.rdir, nr.rdir, r->rox->f.xfm);
116 if (normalize(nr.rdir) == 0.0)
117 goto computerr;
118 /* compute value */
119 if (r->rsrc >= 0)
120 nr.rsrc = source[r->rsrc].sa.sv.sn;
121 rayvalue(&nr);
122 scalecolor(nr.rcol, coef);
123 addcolor(r->rcol, nr.rcol);
124 return(1);
125 computerr:
126 objerror(m, WARNING, "compute error");
127 return(-1);
128 }
129
130
131 dir_proj(pm, o, s, n) /* compute a director's projection */
132 MAT4 pm;
133 OBJREC *o;
134 SRCREC *s;
135 int n;
136 {
137 RAY tr;
138 register OBJREC *m;
139 char **sa;
140 FVECT cent, newdir, nv, h;
141 double olddot, newdot, od;
142 register int i, j;
143 /* get material arguments */
144 m = objptr(o->omod);
145 dir_check(m);
146 sa = m->oargs.sarg + 4*n;
147 /* initialize test ray */
148 getmaxdisk(cent, o);
149 if (s->sflags & SDISTANT)
150 for (i = 0; i < 3; i++) {
151 tr.rdir[i] = -s->sloc[i];
152 tr.rorg[i] = cent[i] - tr.rdir[i];
153 }
154 else {
155 for (i = 0; i < 3; i++) {
156 tr.rdir[i] = cent[i] - s->sloc[i];
157 tr.rorg[i] = s->sloc[i];
158 }
159 if (normalize(tr.rdir) == 0.0)
160 return(0); /* at source! */
161 }
162 od = getplaneq(nv, o);
163 olddot = DOT(tr.rdir, nv);
164 if (olddot <= FTINY && olddot >= -FTINY)
165 return(0); /* old dir parallels plane */
166 rayorigin(&tr, NULL, PRIMARY, 1.0);
167 if (!(*ofun[o->otype].funp)(o, &tr))
168 return(0); /* no intersection! */
169 /* compute redirection */
170 setmap(m, &tr, &((FULLXF *)m->os)->b);
171 funcfile(m->oargs.sarg[fndx(m)]);
172 errno = 0;
173 if (varvalue(sa[0]) <= FTINY)
174 return(0); /* insignificant */
175 if (errno)
176 goto computerr;
177 for (i = 0; i < 3; i++)
178 newdir[i] = varvalue(sa[i+1]);
179 if (errno)
180 goto computerr;
181 multv3(newdir, newdir, ((FULLXF *)m->os)->f.xfm);
182 /* normalization unnecessary */
183 newdot = DOT(newdir, nv);
184 if (newdot <= FTINY && newdot >= -FTINY)
185 return(0); /* new dir parallels plane */
186 /* everything OK -- compute shear */
187 for (i = 0; i < 3; i++)
188 h[i] = newdir[i]/newdot - tr.rdir[i]/olddot;
189 setident4(pm);
190 for (j = 0; j < 3; j++) {
191 for (i = 0; i < 3; i++)
192 pm[i][j] += nv[i]*h[j];
193 pm[3][j] = -od*h[j];
194 }
195 if (newdot > 0.0 ^ olddot > 0.0) /* add mirroring */
196 for (j = 0; j < 3; j++) {
197 for (i = 0; i < 3; i++)
198 pm[i][j] -= 2.*nv[i]*nv[j];
199 pm[3][j] += 2.*od*nv[j];
200 }
201 return(1);
202 computerr:
203 objerror(m, WARNING, "projection compute error");
204 return(0);
205 }