ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_direct.c
Revision: 1.5
Committed: Thu Aug 8 11:30:05 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +1 -2 lines
Log Message:
added contexts to function files

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 greg 1.4 setmap(m, r, &((FULLXF *)m->os)->b);
70 greg 1.1 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 greg 1.4 if (errno)
83 greg 1.1 goto computerr;
84 greg 1.4 multv3(nr.rdir, nr.rdir, ((FULLXF *)m->os)->f.xfm);
85     if (r->rox != NULL)
86     multv3(nr.rdir, nr.rdir, r->rox->f.xfm);
87     if (normalize(nr.rdir) == 0.0)
88     goto computerr;
89 greg 1.1 /* compute value */
90     if (r->rsrc >= 0)
91     nr.rsrc = source[r->rsrc].sa.sv.sn;
92     rayvalue(&nr);
93     scalecolor(nr.rcol, coef);
94     addcolor(r->rcol, nr.rcol);
95     return(1);
96     computerr:
97     objerror(m, WARNING, "compute error");
98     return(-1);
99     }
100    
101    
102     dir_proj(pm, o, s, n) /* compute a director's projection */
103     MAT4 pm;
104     OBJREC *o;
105     SRCREC *s;
106     int n;
107     {
108     RAY tr;
109     register OBJREC *m;
110     char **sa;
111     FVECT cent, newdir, nv, h;
112     double olddot, newdot, od;
113     register int i, j;
114     /* get material arguments */
115     m = objptr(o->omod);
116 greg 1.3 dir_check(m);
117 greg 1.1 sa = m->oargs.sarg + 4*n;
118     /* initialize test ray */
119     getmaxdisk(cent, o);
120     if (s->sflags & SDISTANT)
121     for (i = 0; i < 3; i++) {
122     tr.rdir[i] = -s->sloc[i];
123     tr.rorg[i] = cent[i] - tr.rdir[i];
124     }
125     else {
126     for (i = 0; i < 3; i++) {
127     tr.rdir[i] = cent[i] - s->sloc[i];
128 greg 1.2 tr.rorg[i] = s->sloc[i];
129 greg 1.1 }
130     if (normalize(tr.rdir) == 0.0)
131     return(0); /* at source! */
132     }
133     od = getplaneq(nv, o);
134     olddot = DOT(tr.rdir, nv);
135     if (olddot <= FTINY && olddot >= -FTINY)
136     return(0); /* old dir parallels plane */
137     rayorigin(&tr, NULL, PRIMARY, 1.0);
138     if (!(*ofun[o->otype].funp)(o, &tr))
139     return(0); /* no intersection! */
140     /* compute redirection */
141 greg 1.4 setmap(m, &tr, &((FULLXF *)m->os)->b);
142 greg 1.1 errno = 0;
143     if (varvalue(sa[0]) <= FTINY)
144     return(0); /* insignificant */
145     if (errno)
146     goto computerr;
147     for (i = 0; i < 3; i++)
148     newdir[i] = varvalue(sa[i+1]);
149     if (errno)
150     goto computerr;
151 greg 1.4 multv3(newdir, newdir, ((FULLXF *)m->os)->f.xfm);
152     /* normalization unnecessary */
153 greg 1.1 newdot = DOT(newdir, nv);
154     if (newdot <= FTINY && newdot >= -FTINY)
155     return(0); /* new dir parallels plane */
156     /* everything OK -- compute shear */
157     for (i = 0; i < 3; i++)
158 greg 1.4 h[i] = newdir[i]/newdot - tr.rdir[i]/olddot;
159 greg 1.1 setident4(pm);
160     for (j = 0; j < 3; j++) {
161     for (i = 0; i < 3; i++)
162     pm[i][j] += nv[i]*h[j];
163     pm[3][j] = -od*h[j];
164     }
165     if (newdot > 0.0 ^ olddot > 0.0) /* add mirroring */
166     for (j = 0; j < 3; j++) {
167     for (i = 0; i < 3; i++)
168     pm[i][j] -= 2.*nv[i]*nv[j];
169     pm[3][j] += 2.*od*nv[j];
170     }
171     return(1);
172     computerr:
173     objerror(m, WARNING, "projection compute error");
174     return(0);
175 greg 1.3 }
176    
177    
178     static
179     dir_check(m) /* check arguments and load function file */
180     register OBJREC *m;
181     {
182 greg 1.4 register FULLXF *mxf;
183 greg 1.3 register int ff;
184    
185 greg 1.4 ff = m->otype == MAT_DIRECT1 ? 5 : 9;
186     if (ff > m->oargs.nsargs)
187 greg 1.3 objerror(m, USER, "too few arguments");
188 greg 1.5 funcfile(m->oargs.sarg[ff-1]);
189 greg 1.4 if (m->os == NULL) {
190     mxf = (FULLXF *)malloc(sizeof(FULLXF));
191     if (mxf == NULL)
192     error(SYSTEM, "out of memory in dir_check");
193     if (fullxf(mxf, m->oargs.nsargs-ff, m->oargs.sarg+ff) !=
194     m->oargs.nsargs-ff)
195     objerror(m, USER, "bad transform");
196     if (mxf->f.sca < 0.0)
197     mxf->f.sca = -mxf->f.sca;
198     if (mxf->b.sca < 0.0)
199     mxf->b.sca = -mxf->b.sca;
200     m->os = (char *)mxf;
201     }
202 greg 1.1 }