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

# User Rev Content
1 greg 2.5 /* Copyright (c) 1994 Regents of the University of California */
2 greg 1.1
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 greg 2.2 #include "func.h"
19    
20 greg 1.1 /*
21     * The arguments for MAT_DIRECT1 are:
22     *
23 greg 1.3 * 5+ coef1 dx1 dy1 dz1 funcfile transform..
24 greg 1.1 * 0
25     * n A1 A2 .. An
26     *
27     * The arguments for MAT_DIRECT2 are:
28     *
29 greg 1.3 * 9+ coef1 dx1 dy1 dz1 coef2 dx2 dy2 dz2 funcfile transform..
30 greg 1.1 * 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 greg 2.2 #define getdfunc(m) ( (m)->otype == MAT_DIRECT1 ? \
40     getfunc(m, 4, 0xf, 1) : \
41     getfunc(m, 8, 0xff, 1) )
42 greg 1.1
43 greg 1.6
44 greg 1.1 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 greg 2.4 return(1); /* got the wrong guy */
51 greg 1.1 /* 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 greg 2.4 return(1);
60 greg 1.1 }
61    
62    
63     redirect(m, r, n) /* compute n'th ray redirection */
64     OBJREC *m;
65     RAY *r;
66     int n;
67     {
68 greg 2.2 MFUNC *mf;
69     register EPNODE **va;
70 greg 2.3 FVECT nsdir;
71 greg 1.1 RAY nr;
72     double coef;
73     register int j;
74     /* set up function */
75 greg 2.2 mf = getdfunc(m);
76     setfunc(m, r);
77 greg 2.3 /* 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 greg 2.6 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 greg 1.1 /* compute coefficient */
98     errno = 0;
99 greg 2.2 va = mf->ep + 4*n;
100     coef = evalue(va[0]);
101 greg 1.1 if (errno)
102     goto computerr;
103     if (coef <= FTINY || rayorigin(&nr, r, TRANS, coef) < 0)
104     return(0);
105 greg 2.2 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 greg 1.4 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 greg 1.1 /* 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 greg 2.7 if (r->ro != NULL && isflat(r->ro->otype))
124     r->rt = r->rot + nr.rt;
125 greg 1.1 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 greg 2.2 OBJREC *m;
140     MFUNC *mf;
141     EPNODE **va;
142 greg 1.1 FVECT cent, newdir, nv, h;
143 greg 2.2 double coef, olddot, newdot, od;
144 greg 1.1 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 greg 1.2 tr.rorg[i] = s->sloc[i];
156 greg 1.1 }
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 greg 2.5 tr.rmax = 0.0;
165 greg 1.1 rayorigin(&tr, NULL, PRIMARY, 1.0);
166     if (!(*ofun[o->otype].funp)(o, &tr))
167     return(0); /* no intersection! */
168     /* compute redirection */
169 greg 2.2 m = vsmaterial(o);
170     mf = getdfunc(m);
171     setfunc(m, &tr);
172 greg 2.3 varset("DxA", '=', 0.0);
173     varset("DyA", '=', 0.0);
174     varset("DzA", '=', 0.0);
175 greg 1.1 errno = 0;
176 greg 2.2 va = mf->ep + 4*n;
177     coef = evalue(va[0]);
178 greg 1.1 if (errno)
179     goto computerr;
180 greg 2.2 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 greg 1.4 /* normalization unnecessary */
191 greg 1.1 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 greg 1.4 h[i] = newdir[i]/newdot - tr.rdir[i]/olddot;
197 greg 1.1 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     }