ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/func.c
Revision: 1.13
Committed: Sat Jan 12 18:01:19 1991 UTC (33 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.12: +27 -17 lines
Log Message:
fixed incorrect test for repeat call
added identity transform special case

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.13 XF unitxf = { /* identity transform */
19     1.0, 0.0, 0.0, 0.0,
20     0.0, 1.0, 0.0, 0.0,
21     0.0, 0.0, 1.0, 0.0,
22     0.0, 0.0, 0.0, 1.0,
23     1.0
24     };
25    
26 greg 1.12 XF funcxf; /* current transformation */
27     static OBJREC *fobj = NULL; /* current function object */
28     static RAY *fray = NULL; /* current function ray */
29 greg 1.1
30    
31 greg 1.12 setmap(m, r, bx) /* set channels for function call */
32 greg 1.1 OBJREC *m;
33     register RAY *r;
34 greg 1.12 XF *bx;
35 greg 1.1 {
36     extern double l_noise3(), l_noise3a(), l_noise3b(), l_noise3c();
37     extern double l_hermite(), l_fnoise3(), l_arg();
38     extern long eclock;
39     static char *initfile = "rayinit.cal";
40 greg 1.12 /* initialize if first call */
41 greg 1.1 if (initfile != NULL) {
42     loadfunc(initfile);
43 greg 1.9 scompile("Dx=$1;Dy=$2;Dz=$3;", NULL, 0);
44     scompile("Nx=$4;Ny=$5;Nz=$6;", NULL, 0);
45     scompile("Px=$7;Py=$8;Pz=$9;", NULL, 0);
46     scompile("T=$10;Rdot=$11;", NULL, 0);
47     scompile("S=$12;Tx=$13;Ty=$14;Tz=$15;", NULL, 0);
48     scompile("Ix=$16;Iy=$17;Iz=$18;", NULL, 0);
49     scompile("Jx=$19;Jy=$20;Jz=$21;", NULL, 0);
50     scompile("Kx=$22;Ky=$23;Kz=$24;", NULL, 0);
51 greg 1.1 funset("arg", 1, l_arg);
52     funset("noise3", 3, l_noise3);
53     funset("noise3a", 3, l_noise3a);
54     funset("noise3b", 3, l_noise3b);
55     funset("noise3c", 3, l_noise3c);
56     funset("hermite", 5, l_hermite);
57     funset("fnoise3", 3, l_fnoise3);
58     initfile = NULL;
59     }
60     fobj = m;
61     fray = r;
62 greg 1.13 if (r->rox != NULL)
63     if (bx != &unitxf) {
64     funcxf.sca = r->rox->b.sca * bx->sca;
65     multmat4(funcxf.xfm, r->rox->b.xfm, bx->xfm);
66     } else
67     copystruct(&funcxf, &r->rox->b);
68     else
69 greg 1.12 copystruct(&funcxf, bx);
70 greg 1.1 eclock++; /* notify expression evaluator */
71     }
72    
73    
74     setfunc(m, r) /* simplified interface to setmap */
75     register OBJREC *m;
76     RAY *r;
77     {
78 greg 1.2 register XF *mxf;
79 greg 1.1
80 greg 1.2 if ((mxf = (XF *)m->os) == NULL) {
81 greg 1.5 register int n;
82     register char **sa;
83 greg 1.1
84 greg 1.5 for (n = m->oargs.nsargs, sa = m->oargs.sarg;
85     n > 0 && **sa != '-'; n--, sa++)
86     ;
87 greg 1.13 if (n == 0)
88     mxf = &unitxf;
89     else {
90     mxf = (XF *)malloc(sizeof(XF));
91     if (mxf == NULL)
92     goto memerr;
93     if (invxf(mxf, n, sa) != n)
94     objerror(m, USER, "bad transform");
95     if (mxf->sca < 0.0)
96     mxf->sca = -mxf->sca;
97     }
98 greg 1.2 m->os = (char *)mxf;
99 greg 1.1 }
100 greg 1.12 setmap(m, r, mxf);
101 greg 1.1 return;
102     memerr:
103     error(SYSTEM, "out of memory in setfunc");
104     }
105    
106    
107     loadfunc(fname) /* load definition file */
108     char *fname;
109     {
110     extern char *libpath; /* library search path */
111     char *ffname;
112    
113 greg 1.6 if ((ffname = getpath(fname, libpath, R_OK)) == NULL) {
114 greg 1.1 sprintf(errmsg, "cannot find function file \"%s\"", fname);
115     error(USER, errmsg);
116     }
117     fcompile(ffname);
118     }
119    
120    
121     double
122     l_arg() /* return nth real argument */
123     {
124     extern double argument();
125     register int n;
126    
127     n = argument(1) + .5; /* round to integer */
128    
129     if (n < 1)
130     return(fobj->oargs.nfargs);
131    
132     if (n > fobj->oargs.nfargs) {
133     sprintf(errmsg, "missing real argument %d", n);
134     objerror(fobj, USER, errmsg);
135     }
136     return(fobj->oargs.farg[n-1]);
137     }
138    
139    
140     double
141     chanvalue(n) /* return channel n to calcomp */
142     register int n;
143     {
144 greg 1.8 double sum;
145 greg 1.1 register RAY *r;
146    
147 greg 1.10 if (--n < 0)
148     goto badchan;
149 greg 1.1
150 greg 1.8 if (n < 3) /* ray direction */
151 greg 1.1
152 greg 1.12 return( ( fray->rdir[0]*funcxf.xfm[0][n] +
153     fray->rdir[1]*funcxf.xfm[1][n] +
154     fray->rdir[2]*funcxf.xfm[2][n] )
155     / funcxf.sca );
156 greg 1.1
157 greg 1.8 if (n < 6) /* surface normal */
158    
159 greg 1.12 return( ( fray->ron[0]*funcxf.xfm[0][n-3] +
160     fray->ron[1]*funcxf.xfm[1][n-3] +
161     fray->ron[2]*funcxf.xfm[2][n-3] )
162     / funcxf.sca );
163 greg 1.8
164     if (n < 9) /* intersection */
165    
166 greg 1.12 return( fray->rop[0]*funcxf.xfm[0][n-6] +
167     fray->rop[1]*funcxf.xfm[1][n-6] +
168     fray->rop[2]*funcxf.xfm[2][n-6] +
169     funcxf.xfm[3][n-6] );
170 greg 1.8
171 greg 1.10 if (n == 9) { /* distance */
172    
173     sum = fray->rot;
174     for (r = fray->parent; r != NULL; r = r->parent)
175     sum += r->rot;
176 greg 1.12 return(sum * funcxf.sca);
177 greg 1.10
178     }
179     if (n == 10) /* dot product */
180     return(fray->rod);
181    
182 greg 1.8 if (n == 11) /* scale */
183 greg 1.12 return(funcxf.sca);
184 greg 1.8
185     if (n < 15) /* origin */
186 greg 1.12 return(funcxf.xfm[3][n-12]);
187 greg 1.8
188     if (n < 18) /* i unit vector */
189 greg 1.12 return(funcxf.xfm[0][n-15] / funcxf.sca);
190 greg 1.8
191     if (n < 21) /* j unit vector */
192 greg 1.12 return(funcxf.xfm[1][n-15] / funcxf.sca);
193 greg 1.8
194     if (n < 24) /* k unit vector */
195 greg 1.12 return(funcxf.xfm[2][n-21] / funcxf.sca);
196 greg 1.10 badchan:
197     error(USER, "illegal channel number");
198 greg 1.1 }