ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_direct.c
Revision: 1.3
Committed: Tue Jul 16 17:16:32 1991 UTC (32 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +18 -6 lines
Log Message:
added missing funcfile argument!

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
40 m_direct(m, r) /* shade redirected ray */
41 register OBJREC *m;
42 register RAY *r;
43 {
44 /* check if source ray */
45 if (r->rsrc >= 0 && source[r->rsrc].so != r->ro)
46 return; /* got the wrong guy */
47 dir_check(m);
48 /* compute first projection */
49 if (m->otype == MAT_DIRECT1 ||
50 (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 0))
51 redirect(m, r, 0);
52 /* compute second projection */
53 if (m->otype == MAT_DIRECT2 &&
54 (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 1))
55 redirect(m, r, 1);
56 }
57
58
59 redirect(m, r, n) /* compute n'th ray redirection */
60 OBJREC *m;
61 RAY *r;
62 int n;
63 {
64 register char **sa;
65 RAY nr;
66 double coef;
67 register int j;
68 /* set up function */
69 setfunc(m, r);
70 sa = m->oargs.sarg + 4*n;
71 /* compute coefficient */
72 errno = 0;
73 coef = varvalue(sa[0]);
74 if (errno)
75 goto computerr;
76 if (coef <= FTINY || rayorigin(&nr, r, TRANS, coef) < 0)
77 return(0);
78 /* compute direction */
79 errno = 0;
80 for (j = 0; j < 3; j++)
81 nr.rdir[j] = varvalue(sa[j+1]);
82 if (errno || normalize(nr.rdir) == 0.0)
83 goto computerr;
84 /* compute value */
85 if (r->rsrc >= 0)
86 nr.rsrc = source[r->rsrc].sa.sv.sn;
87 rayvalue(&nr);
88 scalecolor(nr.rcol, coef);
89 addcolor(r->rcol, nr.rcol);
90 return(1);
91 computerr:
92 objerror(m, WARNING, "compute error");
93 return(-1);
94 }
95
96
97 dir_proj(pm, o, s, n) /* compute a director's projection */
98 MAT4 pm;
99 OBJREC *o;
100 SRCREC *s;
101 int n;
102 {
103 RAY tr;
104 register OBJREC *m;
105 char **sa;
106 FVECT cent, newdir, nv, h;
107 double olddot, newdot, od;
108 register int i, j;
109 /* get material arguments */
110 m = objptr(o->omod);
111 dir_check(m);
112 sa = m->oargs.sarg + 4*n;
113 /* initialize test ray */
114 getmaxdisk(cent, o);
115 if (s->sflags & SDISTANT)
116 for (i = 0; i < 3; i++) {
117 tr.rdir[i] = -s->sloc[i];
118 tr.rorg[i] = cent[i] - tr.rdir[i];
119 }
120 else {
121 for (i = 0; i < 3; i++) {
122 tr.rdir[i] = cent[i] - s->sloc[i];
123 tr.rorg[i] = s->sloc[i];
124 }
125 if (normalize(tr.rdir) == 0.0)
126 return(0); /* at source! */
127 }
128 od = getplaneq(nv, o);
129 olddot = DOT(tr.rdir, nv);
130 if (olddot <= FTINY && olddot >= -FTINY)
131 return(0); /* old dir parallels plane */
132 rayorigin(&tr, NULL, PRIMARY, 1.0);
133 if (!(*ofun[o->otype].funp)(o, &tr))
134 return(0); /* no intersection! */
135 /* compute redirection */
136 setfunc(m, &tr);
137 errno = 0;
138 if (varvalue(sa[0]) <= FTINY)
139 return(0); /* insignificant */
140 if (errno)
141 goto computerr;
142 for (i = 0; i < 3; i++)
143 newdir[i] = varvalue(sa[i+1]);
144 if (errno)
145 goto computerr;
146 newdot = DOT(newdir, nv);
147 if (newdot <= FTINY && newdot >= -FTINY)
148 return(0); /* new dir parallels plane */
149 /* everything OK -- compute shear */
150 for (i = 0; i < 3; i++)
151 h[i] = tr.rdir[i]/olddot + newdir[i]/newdot;
152 setident4(pm);
153 for (j = 0; j < 3; j++) {
154 for (i = 0; i < 3; i++)
155 pm[i][j] += nv[i]*h[j];
156 pm[3][j] = -od*h[j];
157 }
158 if (newdot > 0.0 ^ olddot > 0.0) /* add mirroring */
159 for (j = 0; j < 3; j++) {
160 for (i = 0; i < 3; i++)
161 pm[i][j] -= 2.*nv[i]*nv[j];
162 pm[3][j] += 2.*od*nv[j];
163 }
164 return(1);
165 computerr:
166 objerror(m, WARNING, "projection compute error");
167 return(0);
168 }
169
170
171 static
172 dir_check(m) /* check arguments and load function file */
173 register OBJREC *m;
174 {
175 register int ff;
176
177 ff = m->otype == MAT_DIRECT1 ? 4 : 8;
178 if (ff >= m->oargs.nsargs)
179 objerror(m, USER, "too few arguments");
180 if (!vardefined(m->oargs.sarg[0]))
181 loadfunc(m->oargs.sarg[ff]);
182 }