ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/func.c
Revision: 2.1
Committed: Tue Nov 12 17:08:46 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.23: +0 -0 lines
Log Message:
updated revision number for release 2.0

File Contents

# User Rev Content
1 greg 1.13 /* Copyright (c) 1991 Regents of the University of California */
2 greg 1.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * func.c - interface to calcomp functions.
9     *
10     * 4/7/86
11     */
12    
13     #include "ray.h"
14    
15     #include "otypes.h"
16    
17    
18 greg 1.21 #define INITFILE "rayinit.cal"
19 greg 1.23 #define DEFVNAME "`FILE_LOADED"
20 greg 1.21
21 greg 1.13 XF unitxf = { /* identity transform */
22     1.0, 0.0, 0.0, 0.0,
23     0.0, 1.0, 0.0, 0.0,
24     0.0, 0.0, 1.0, 0.0,
25     0.0, 0.0, 0.0, 1.0,
26     1.0
27     };
28    
29 greg 1.12 XF funcxf; /* current transformation */
30     static OBJREC *fobj = NULL; /* current function object */
31     static RAY *fray = NULL; /* current function ray */
32 greg 1.1
33    
34 greg 1.12 setmap(m, r, bx) /* set channels for function call */
35 greg 1.1 OBJREC *m;
36     register RAY *r;
37 greg 1.12 XF *bx;
38 greg 1.1 {
39     extern long eclock;
40 greg 1.16 static long lastrno = -1;
41     /* check to see if already set */
42     if (m == fobj && r->rno == lastrno)
43 greg 1.17 return(0);
44 greg 1.1 fobj = m;
45     fray = r;
46 greg 1.13 if (r->rox != NULL)
47     if (bx != &unitxf) {
48     funcxf.sca = r->rox->b.sca * bx->sca;
49     multmat4(funcxf.xfm, r->rox->b.xfm, bx->xfm);
50     } else
51     copystruct(&funcxf, &r->rox->b);
52     else
53 greg 1.12 copystruct(&funcxf, bx);
54 greg 1.16 lastrno = r->rno;
55 greg 1.1 eclock++; /* notify expression evaluator */
56 greg 1.17 return(1);
57 greg 1.1 }
58    
59    
60     setfunc(m, r) /* simplified interface to setmap */
61     register OBJREC *m;
62     RAY *r;
63     {
64 greg 1.2 register XF *mxf;
65 greg 1.1
66 greg 1.2 if ((mxf = (XF *)m->os) == NULL) {
67 greg 1.5 register int n;
68     register char **sa;
69 greg 1.1
70 greg 1.5 for (n = m->oargs.nsargs, sa = m->oargs.sarg;
71     n > 0 && **sa != '-'; n--, sa++)
72     ;
73 greg 1.13 if (n == 0)
74     mxf = &unitxf;
75     else {
76     mxf = (XF *)malloc(sizeof(XF));
77     if (mxf == NULL)
78     goto memerr;
79     if (invxf(mxf, n, sa) != n)
80     objerror(m, USER, "bad transform");
81     if (mxf->sca < 0.0)
82     mxf->sca = -mxf->sca;
83     }
84 greg 1.2 m->os = (char *)mxf;
85 greg 1.1 }
86 greg 1.17 return(setmap(m, r, mxf));
87 greg 1.1 memerr:
88     error(SYSTEM, "out of memory in setfunc");
89     }
90    
91    
92     loadfunc(fname) /* load definition file */
93     char *fname;
94     {
95     extern char *libpath; /* library search path */
96     char *ffname;
97    
98 greg 1.6 if ((ffname = getpath(fname, libpath, R_OK)) == NULL) {
99 greg 1.1 sprintf(errmsg, "cannot find function file \"%s\"", fname);
100     error(USER, errmsg);
101     }
102     fcompile(ffname);
103     }
104    
105    
106     double
107     l_arg() /* return nth real argument */
108     {
109     extern double argument();
110     register int n;
111    
112     n = argument(1) + .5; /* round to integer */
113    
114     if (n < 1)
115     return(fobj->oargs.nfargs);
116    
117     if (n > fobj->oargs.nfargs) {
118     sprintf(errmsg, "missing real argument %d", n);
119     objerror(fobj, USER, errmsg);
120     }
121     return(fobj->oargs.farg[n-1]);
122 greg 1.19 }
123    
124    
125     double
126     l_erf() /* error function */
127     {
128     extern double erf();
129    
130     return(erf(argument(1)));
131     }
132    
133    
134     double
135     l_erfc() /* cumulative error function */
136     {
137     extern double erfc();
138    
139     return(erfc(argument(1)));
140 greg 1.21 }
141    
142    
143     funcfile(fname) /* set context, load file if necessary */
144 greg 1.22 register char *fname;
145 greg 1.21 {
146     extern char *setcontext();
147     static char initfile[] = INITFILE;
148    
149     if (initfile[0]) { /* initialize on first call */
150     setcontext("");
151     scompile("Dx=$1;Dy=$2;Dz=$3;", NULL, 0);
152     scompile("Nx=$4;Ny=$5;Nz=$6;", NULL, 0);
153     scompile("Px=$7;Py=$8;Pz=$9;", NULL, 0);
154     scompile("T=$10;Rdot=$11;", NULL, 0);
155     scompile("S=$12;Tx=$13;Ty=$14;Tz=$15;", NULL, 0);
156     scompile("Ix=$16;Iy=$17;Iz=$18;", NULL, 0);
157     scompile("Jx=$19;Jy=$20;Jz=$21;", NULL, 0);
158     scompile("Kx=$22;Ky=$23;Kz=$24;", NULL, 0);
159     funset("arg", 1, '=', l_arg);
160     funset("erf", 1, ':', l_erf);
161     funset("erfc", 1, ':', l_erfc);
162     setnoisefuncs();
163     loadfunc(initfile);
164     initfile[0] = '\0';
165     }
166 greg 1.22 if (fname[0] == '.' && fname[1] == '\0')
167     setcontext(""); /* "." means no file */
168     else {
169     setcontext(fname);
170     if (!vardefined(DEFVNAME)) {
171     loadfunc(fname);
172     varset(DEFVNAME, ':', 1.0);
173     }
174 greg 1.21 }
175 greg 1.1 }
176    
177    
178     double
179     chanvalue(n) /* return channel n to calcomp */
180     register int n;
181     {
182 greg 1.8 double sum;
183 greg 1.1 register RAY *r;
184    
185 greg 1.10 if (--n < 0)
186     goto badchan;
187 greg 1.1
188 greg 1.8 if (n < 3) /* ray direction */
189 greg 1.1
190 greg 1.12 return( ( fray->rdir[0]*funcxf.xfm[0][n] +
191     fray->rdir[1]*funcxf.xfm[1][n] +
192     fray->rdir[2]*funcxf.xfm[2][n] )
193     / funcxf.sca );
194 greg 1.1
195 greg 1.8 if (n < 6) /* surface normal */
196    
197 greg 1.12 return( ( fray->ron[0]*funcxf.xfm[0][n-3] +
198     fray->ron[1]*funcxf.xfm[1][n-3] +
199     fray->ron[2]*funcxf.xfm[2][n-3] )
200     / funcxf.sca );
201 greg 1.8
202     if (n < 9) /* intersection */
203    
204 greg 1.12 return( fray->rop[0]*funcxf.xfm[0][n-6] +
205     fray->rop[1]*funcxf.xfm[1][n-6] +
206     fray->rop[2]*funcxf.xfm[2][n-6] +
207     funcxf.xfm[3][n-6] );
208 greg 1.8
209 greg 1.10 if (n == 9) { /* distance */
210    
211     sum = fray->rot;
212     for (r = fray->parent; r != NULL; r = r->parent)
213     sum += r->rot;
214 greg 1.12 return(sum * funcxf.sca);
215 greg 1.10
216     }
217 greg 1.18 if (n == 10) /* dot product (range [-1,1]) */
218     return( fray->rod <= -1.0 ? -1.0 :
219     fray->rod >= 1.0 ? 1.0 :
220     fray->rod );
221 greg 1.10
222 greg 1.8 if (n == 11) /* scale */
223 greg 1.12 return(funcxf.sca);
224 greg 1.8
225     if (n < 15) /* origin */
226 greg 1.12 return(funcxf.xfm[3][n-12]);
227 greg 1.8
228     if (n < 18) /* i unit vector */
229 greg 1.12 return(funcxf.xfm[0][n-15] / funcxf.sca);
230 greg 1.8
231     if (n < 21) /* j unit vector */
232 greg 1.12 return(funcxf.xfm[1][n-15] / funcxf.sca);
233 greg 1.8
234     if (n < 24) /* k unit vector */
235 greg 1.12 return(funcxf.xfm[2][n-21] / funcxf.sca);
236 greg 1.10 badchan:
237     error(USER, "illegal channel number");
238 greg 1.1 }