ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/func.c
Revision: 1.18
Committed: Tue Jun 18 08:59:52 1991 UTC (32 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.17: +4 -2 lines
Log Message:
put in test to guarantee range of dot product as [-1,1]

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_arg();
37 extern long eclock;
38 static char *initfile = "rayinit.cal";
39 static long lastrno = -1;
40 /* check to see if already set */
41 if (m == fobj && r->rno == lastrno)
42 return(0);
43 /* initialize if first call */
44 if (initfile != NULL) {
45 loadfunc(initfile);
46 scompile("Dx=$1;Dy=$2;Dz=$3;", NULL, 0);
47 scompile("Nx=$4;Ny=$5;Nz=$6;", NULL, 0);
48 scompile("Px=$7;Py=$8;Pz=$9;", NULL, 0);
49 scompile("T=$10;Rdot=$11;", NULL, 0);
50 scompile("S=$12;Tx=$13;Ty=$14;Tz=$15;", NULL, 0);
51 scompile("Ix=$16;Iy=$17;Iz=$18;", NULL, 0);
52 scompile("Jx=$19;Jy=$20;Jz=$21;", NULL, 0);
53 scompile("Kx=$22;Ky=$23;Kz=$24;", NULL, 0);
54 funset("arg", 1, '=', l_arg);
55 setnoisefuncs();
56 initfile = NULL;
57 }
58 fobj = m;
59 fray = r;
60 if (r->rox != NULL)
61 if (bx != &unitxf) {
62 funcxf.sca = r->rox->b.sca * bx->sca;
63 multmat4(funcxf.xfm, r->rox->b.xfm, bx->xfm);
64 } else
65 copystruct(&funcxf, &r->rox->b);
66 else
67 copystruct(&funcxf, bx);
68 lastrno = r->rno;
69 eclock++; /* notify expression evaluator */
70 return(1);
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 return(setmap(m, r, mxf));
101 memerr:
102 error(SYSTEM, "out of memory in setfunc");
103 }
104
105
106 loadfunc(fname) /* load definition file */
107 char *fname;
108 {
109 extern char *libpath; /* library search path */
110 char *ffname;
111
112 if ((ffname = getpath(fname, libpath, R_OK)) == NULL) {
113 sprintf(errmsg, "cannot find function file \"%s\"", fname);
114 error(USER, errmsg);
115 }
116 fcompile(ffname);
117 }
118
119
120 double
121 l_arg() /* return nth real argument */
122 {
123 extern double argument();
124 register int n;
125
126 n = argument(1) + .5; /* round to integer */
127
128 if (n < 1)
129 return(fobj->oargs.nfargs);
130
131 if (n > fobj->oargs.nfargs) {
132 sprintf(errmsg, "missing real argument %d", n);
133 objerror(fobj, USER, errmsg);
134 }
135 return(fobj->oargs.farg[n-1]);
136 }
137
138
139 double
140 chanvalue(n) /* return channel n to calcomp */
141 register int n;
142 {
143 double sum;
144 register RAY *r;
145
146 if (--n < 0)
147 goto badchan;
148
149 if (n < 3) /* ray direction */
150
151 return( ( fray->rdir[0]*funcxf.xfm[0][n] +
152 fray->rdir[1]*funcxf.xfm[1][n] +
153 fray->rdir[2]*funcxf.xfm[2][n] )
154 / funcxf.sca );
155
156 if (n < 6) /* surface normal */
157
158 return( ( fray->ron[0]*funcxf.xfm[0][n-3] +
159 fray->ron[1]*funcxf.xfm[1][n-3] +
160 fray->ron[2]*funcxf.xfm[2][n-3] )
161 / funcxf.sca );
162
163 if (n < 9) /* intersection */
164
165 return( fray->rop[0]*funcxf.xfm[0][n-6] +
166 fray->rop[1]*funcxf.xfm[1][n-6] +
167 fray->rop[2]*funcxf.xfm[2][n-6] +
168 funcxf.xfm[3][n-6] );
169
170 if (n == 9) { /* distance */
171
172 sum = fray->rot;
173 for (r = fray->parent; r != NULL; r = r->parent)
174 sum += r->rot;
175 return(sum * funcxf.sca);
176
177 }
178 if (n == 10) /* dot product (range [-1,1]) */
179 return( fray->rod <= -1.0 ? -1.0 :
180 fray->rod >= 1.0 ? 1.0 :
181 fray->rod );
182
183 if (n == 11) /* scale */
184 return(funcxf.sca);
185
186 if (n < 15) /* origin */
187 return(funcxf.xfm[3][n-12]);
188
189 if (n < 18) /* i unit vector */
190 return(funcxf.xfm[0][n-15] / funcxf.sca);
191
192 if (n < 21) /* j unit vector */
193 return(funcxf.xfm[1][n-15] / funcxf.sca);
194
195 if (n < 24) /* k unit vector */
196 return(funcxf.xfm[2][n-21] / funcxf.sca);
197 badchan:
198 error(USER, "illegal channel number");
199 }