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

# User Rev Content
1 greg 1.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 greg 1.3 * 5+ coef1 dx1 dy1 dz1 funcfile transform..
22 greg 1.1 * 0
23     * n A1 A2 .. An
24     *
25     * The arguments for MAT_DIRECT2 are:
26     *
27 greg 1.3 * 9+ coef1 dx1 dy1 dz1 coef2 dx2 dy2 dz2 funcfile transform..
28 greg 1.1 * 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 greg 1.3 dir_check(m);
48 greg 1.1 /* 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 greg 1.3 dir_check(m);
112 greg 1.1 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 greg 1.2 tr.rorg[i] = s->sloc[i];
124 greg 1.1 }
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 greg 1.3 }
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 greg 1.1 }