ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_direct.c
Revision: 1.2
Committed: Tue Jul 16 15:56:54 1991 UTC (32 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
added redirecting materials

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