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

# Content
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 * 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 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 XF funcxf; /* current transformation */
27 static OBJREC *fobj = NULL; /* current function object */
28 static RAY *fray = NULL; /* current function ray */
29
30
31 setmap(m, r, bx) /* set channels for function call */
32 OBJREC *m;
33 register RAY *r;
34 XF *bx;
35 {
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 /* initialize if first call */
41 if (initfile != NULL) {
42 loadfunc(initfile);
43 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 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 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 copystruct(&funcxf, bx);
70 eclock++; /* notify expression evaluator */
71 }
72
73
74 setfunc(m, r) /* simplified interface to setmap */
75 register OBJREC *m;
76 RAY *r;
77 {
78 register XF *mxf;
79
80 if ((mxf = (XF *)m->os) == NULL) {
81 register int n;
82 register char **sa;
83
84 for (n = m->oargs.nsargs, sa = m->oargs.sarg;
85 n > 0 && **sa != '-'; n--, sa++)
86 ;
87 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 m->os = (char *)mxf;
99 }
100 setmap(m, r, mxf);
101 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 if ((ffname = getpath(fname, libpath, R_OK)) == NULL) {
114 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 double sum;
145 register RAY *r;
146
147 if (--n < 0)
148 goto badchan;
149
150 if (n < 3) /* ray direction */
151
152 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
157 if (n < 6) /* surface normal */
158
159 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
164 if (n < 9) /* intersection */
165
166 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
171 if (n == 9) { /* distance */
172
173 sum = fray->rot;
174 for (r = fray->parent; r != NULL; r = r->parent)
175 sum += r->rot;
176 return(sum * funcxf.sca);
177
178 }
179 if (n == 10) /* dot product */
180 return(fray->rod);
181
182 if (n == 11) /* scale */
183 return(funcxf.sca);
184
185 if (n < 15) /* origin */
186 return(funcxf.xfm[3][n-12]);
187
188 if (n < 18) /* i unit vector */
189 return(funcxf.xfm[0][n-15] / funcxf.sca);
190
191 if (n < 21) /* j unit vector */
192 return(funcxf.xfm[1][n-15] / funcxf.sca);
193
194 if (n < 24) /* k unit vector */
195 return(funcxf.xfm[2][n-21] / funcxf.sca);
196 badchan:
197 error(USER, "illegal channel number");
198 }