ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/xf.c
Revision: 1.3
Committed: Fri Jun 24 15:32:40 1994 UTC (29 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +1 -1 lines
Log Message:
fix in prototype declaration

File Contents

# Content
1 /* Copyright (c) 1994 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Routines for 4x4 homogeneous, rigid-body transformations
9 */
10
11 #include <stdio.h>
12 #include <math.h>
13 #include <string.h>
14 #include "parser.h"
15
16 #define d2r(a) ((PI/180.)*(a))
17
18 #define checkarg(a,l) if (av[i][a] || badarg(ac-i-1,av+i+1,l)) goto done
19
20 MAT4 m4ident = MAT4IDENT;
21
22 static MAT4 m4tmp; /* for efficiency */
23
24 int xf_argc; /* total # transform args. */
25 char **xf_argv; /* transform arguments */
26 XF_SPEC *xf_context; /* current context */
27
28 static int xf_maxarg; /* # allocated arguments */
29
30
31 int
32 xf_handler(ac, av) /* handle xf entity */
33 int ac;
34 char **av;
35 {
36 register int i;
37 register XF_SPEC *spec;
38 XF thisxf;
39
40 if (ac == 1) { /* pop top transform */
41 if ((spec = xf_context) == NULL)
42 return(MG_OK); /* should be error? */
43 while (xf_argc > spec->xav0)
44 free((MEM_PTR)xf_argv[--xf_argc]);
45 xf_argv[xf_argc] = NULL;
46 xf_context = spec->prev;
47 free((MEM_PTR)spec);
48 return(MG_OK);
49 }
50 /* translate new specification */
51 if (xf(&thisxf, ac-1, av+1) != ac-1)
52 return(MG_ETYPE);
53 /* allocate space for new transform */
54 spec = (XF_SPEC *)malloc(sizeof(XF_SPEC));
55 if (spec == NULL)
56 return(MG_EMEM);
57 spec->xav0 = xf_argc;
58 spec->xac = ac-1;
59 /* and store new xf arguments */
60 if (xf_argc+ac > xf_maxarg) {
61 if (!xf_maxarg)
62 xf_argv = (char **)malloc(
63 (xf_maxarg=ac)*sizeof(char *));
64 else
65 xf_argv = (char **)realloc((MEM_PTR)xf_argv,
66 (xf_maxarg+=ac)*sizeof(char *));
67 if (xf_argv == NULL)
68 return(MG_EMEM);
69 }
70 for (i = 0; i < ac-1; i++) {
71 xf_argv[xf_argc] = (char *)malloc(strlen(av[i+1])+1);
72 if (xf_argv[xf_argc] == NULL)
73 return(MG_EMEM);
74 strcpy(xf_argv[xf_argc++], av[i+1]);
75 }
76 xf_argv[xf_argc] = NULL;
77 /* compute total transformation */
78 if (xf_context != NULL) {
79 multmat4(spec->xf.xfm, xf_context->xf.xfm, thisxf.xfm);
80 spec->xf.sca = xf_context->xf.sca * thisxf.sca;
81 } else
82 spec->xf = thisxf;
83 spec->prev = xf_context; /* push new transform onto stack */
84 xf_context = spec;
85 return(MG_OK);
86 }
87
88
89 void
90 xf_clear() /* clear transform stack */
91 {
92 register XF_SPEC *spec;
93
94 while (xf_argc)
95 free((MEM_PTR)xf_argv[--xf_argc]);
96 if (xf_maxarg) {
97 free((MEM_PTR)xf_argv);
98 xf_argv = NULL;
99 xf_maxarg = 0;
100 }
101 while ((spec = xf_context) != NULL) {
102 xf_context = spec->prev;
103 free((MEM_PTR)spec);
104 }
105 }
106
107
108 void
109 xf_xfmpoint(v1, v2) /* transform a point by the current matrix */
110 FVECT v1, v2;
111 {
112 if (xf_context == NULL) {
113 v1[0] = v2[0];
114 v1[1] = v2[1];
115 v1[2] = v2[2];
116 return;
117 }
118 multp3(v1, v2, xf_context->xf.xfm);
119 }
120
121
122 void
123 xf_xfmvect(v1, v2) /* transform a vector using current matrix */
124 FVECT v1, v2;
125 {
126 if (xf_context == NULL) {
127 v1[0] = v2[0];
128 v1[1] = v2[1];
129 v1[2] = v2[2];
130 return;
131 }
132 multv3(v1, v2, xf_context->xf.xfm);
133 }
134
135
136 void
137 xf_rotvect(v1, v2) /* rotate a vector using current matrix */
138 FVECT v1, v2;
139 {
140 xf_xfmvect(v1, v2);
141 if (xf_context == NULL)
142 return;
143 v1[0] /= xf_context->xf.sca;
144 v1[1] /= xf_context->xf.sca;
145 v1[2] /= xf_context->xf.sca;
146 }
147
148
149 double
150 xf_scale(d) /* scale a number by the current transform */
151 double d;
152 {
153 if (xf_context == NULL)
154 return(d);
155 return(d*xf_context->xf.sca);
156 }
157
158
159 void
160 multmat4(m4a, m4b, m4c) /* multiply m4b X m4c and put into m4a */
161 MAT4 m4a;
162 register MAT4 m4b, m4c;
163 {
164 register int i, j;
165
166 for (i = 4; i--; )
167 for (j = 4; j--; )
168 m4tmp[i][j] = m4b[i][0]*m4c[0][j] +
169 m4b[i][1]*m4c[1][j] +
170 m4b[i][2]*m4c[2][j] +
171 m4b[i][3]*m4c[3][j];
172
173 copymat4(m4a, m4tmp);
174 }
175
176
177 void
178 multv3(v3a, v3b, m4) /* transform vector v3b by m4 and put into v3a */
179 FVECT v3a;
180 register FVECT v3b;
181 register MAT4 m4;
182 {
183 m4tmp[0][0] = v3b[0]*m4[0][0] + v3b[1]*m4[1][0] + v3b[2]*m4[2][0];
184 m4tmp[0][1] = v3b[0]*m4[0][1] + v3b[1]*m4[1][1] + v3b[2]*m4[2][1];
185 m4tmp[0][2] = v3b[0]*m4[0][2] + v3b[1]*m4[1][2] + v3b[2]*m4[2][2];
186
187 v3a[0] = m4tmp[0][0];
188 v3a[1] = m4tmp[0][1];
189 v3a[2] = m4tmp[0][2];
190 }
191
192
193 void
194 multp3(p3a, p3b, m4) /* transform p3b by m4 and put into p3a */
195 register FVECT p3a;
196 FVECT p3b;
197 register MAT4 m4;
198 {
199 multv3(p3a, p3b, m4); /* transform as vector */
200 p3a[0] += m4[3][0]; /* translate */
201 p3a[1] += m4[3][1];
202 p3a[2] += m4[3][2];
203 }
204
205
206 int
207 xf(ret, ac, av) /* get transform specification */
208 register XF *ret;
209 int ac;
210 char **av;
211 {
212 MAT4 xfmat, m4;
213 double xfsca, dtmp;
214 int i, icnt;
215
216 setident4(ret->xfm);
217 ret->sca = 1.0;
218
219 icnt = 1;
220 setident4(xfmat);
221 xfsca = 1.0;
222
223 for (i = 0; i < ac && av[i][0] == '-'; i++) {
224
225 setident4(m4);
226
227 switch (av[i][1]) {
228
229 case 't': /* translate */
230 checkarg(2,"fff");
231 m4[3][0] = atof(av[++i]);
232 m4[3][1] = atof(av[++i]);
233 m4[3][2] = atof(av[++i]);
234 break;
235
236 case 'r': /* rotate */
237 switch (av[i][2]) {
238 case 'x':
239 checkarg(3,"f");
240 dtmp = d2r(atof(av[++i]));
241 m4[1][1] = m4[2][2] = cos(dtmp);
242 m4[2][1] = -(m4[1][2] = sin(dtmp));
243 break;
244 case 'y':
245 checkarg(3,"f");
246 dtmp = d2r(atof(av[++i]));
247 m4[0][0] = m4[2][2] = cos(dtmp);
248 m4[0][2] = -(m4[2][0] = sin(dtmp));
249 break;
250 case 'z':
251 checkarg(3,"f");
252 dtmp = d2r(atof(av[++i]));
253 m4[0][0] = m4[1][1] = cos(dtmp);
254 m4[1][0] = -(m4[0][1] = sin(dtmp));
255 break;
256 default:
257 goto done;
258 }
259 break;
260
261 case 's': /* scale */
262 checkarg(2,"f");
263 dtmp = atof(av[i+1]);
264 if (dtmp == 0.0) goto done;
265 i++;
266 xfsca *=
267 m4[0][0] =
268 m4[1][1] =
269 m4[2][2] = dtmp;
270 break;
271
272 case 'm': /* mirror */
273 switch (av[i][2]) {
274 case 'x':
275 checkarg(3,"");
276 xfsca *=
277 m4[0][0] = -1.0;
278 break;
279 case 'y':
280 checkarg(3,"");
281 xfsca *=
282 m4[1][1] = -1.0;
283 break;
284 case 'z':
285 checkarg(3,"");
286 xfsca *=
287 m4[2][2] = -1.0;
288 break;
289 default:
290 goto done;
291 }
292 break;
293
294 case 'i': /* iterate */
295 checkarg(2,"i");
296 while (icnt-- > 0) {
297 multmat4(ret->xfm, ret->xfm, xfmat);
298 ret->sca *= xfsca;
299 }
300 icnt = atoi(av[++i]);
301 setident4(xfmat);
302 xfsca = 1.0;
303 continue;
304
305 default:
306 goto done;
307
308 }
309 multmat4(xfmat, xfmat, m4);
310 }
311 done:
312 while (icnt-- > 0) {
313 multmat4(ret->xfm, ret->xfm, xfmat);
314 ret->sca *= xfsca;
315 }
316 return(i);
317 }