ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/xf.c
Revision: 1.9
Committed: Sat Dec 15 15:01:40 1990 UTC (33 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.8: +29 -20 lines
Log Message:
changed handling of matrix transformations with new MAT4 & XF types

File Contents

# Content
1 /* Copyright (c) 1990 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * xf.c - routines to convert transform arguments into 4X4 matrix.
9 *
10 * 1/28/86
11 */
12
13 #include "standard.h"
14
15 #define d2r(a) ((PI/180.)*(a))
16
17 #define checkarg(a,n) if (av[i][a] || i+n >= ac) goto done
18
19
20 int
21 xf(ret, ac, av) /* get transform specification */
22 register XF *ret;
23 int ac;
24 char *av[];
25 {
26 double atof(), sin(), cos();
27 double xfmat[4][4], m4[4][4];
28 double xfsca, dtmp;
29 int i, icnt;
30
31 setident4(ret->xfm);
32 ret->sca = 1.0;
33
34 icnt = 1;
35 setident4(xfmat);
36 xfsca = 1.0;
37
38 for (i = 0; i < ac && av[i][0] == '-'; i++) {
39
40 setident4(m4);
41
42 switch (av[i][1]) {
43
44 case 't': /* translate */
45 checkarg(2,3);
46 m4[3][0] = atof(av[++i]);
47 m4[3][1] = atof(av[++i]);
48 m4[3][2] = atof(av[++i]);
49 break;
50
51 case 'r': /* rotate */
52 switch (av[i][2]) {
53 case 'x':
54 checkarg(3,1);
55 dtmp = d2r(atof(av[++i]));
56 m4[1][1] = m4[2][2] = cos(dtmp);
57 m4[2][1] = -(m4[1][2] = sin(dtmp));
58 break;
59 case 'y':
60 checkarg(3,1);
61 dtmp = d2r(atof(av[++i]));
62 m4[0][0] = m4[2][2] = cos(dtmp);
63 m4[0][2] = -(m4[2][0] = sin(dtmp));
64 break;
65 case 'z':
66 checkarg(3,1);
67 dtmp = d2r(atof(av[++i]));
68 m4[0][0] = m4[1][1] = cos(dtmp);
69 m4[1][0] = -(m4[0][1] = sin(dtmp));
70 break;
71 default:
72 return(i);
73 }
74 break;
75
76 case 's': /* scale */
77 checkarg(2,1);
78 dtmp = atof(av[i+1]);
79 if (dtmp == 0.0) goto done;
80 i++;
81 xfsca *=
82 m4[0][0] =
83 m4[1][1] =
84 m4[2][2] = dtmp;
85 break;
86
87 case 'm': /* mirror */
88 switch (av[i][2]) {
89 case 'x':
90 checkarg(3,0);
91 xfsca *=
92 m4[0][0] = -1.0;
93 break;
94 case 'y':
95 checkarg(3,0);
96 xfsca *=
97 m4[1][1] = -1.0;
98 break;
99 case 'z':
100 checkarg(3,0);
101 xfsca *=
102 m4[2][2] = -1.0;
103 break;
104 default:
105 return(i);
106 }
107 break;
108
109 case 'i': /* iterate */
110 checkarg(2,1);
111 while (icnt-- > 0) {
112 multmat4(ret->xfm, ret->xfm, xfmat);
113 ret->sca *= xfsca;
114 }
115 icnt = atoi(av[++i]);
116 setident4(xfmat);
117 xfsca = 1.0;
118 continue;
119
120 default:
121 return(i);
122
123 }
124 multmat4(xfmat, xfmat, m4);
125 }
126 done:
127 while (icnt-- > 0) {
128 multmat4(ret->xfm, ret->xfm, xfmat);
129 ret->sca *= xfsca;
130 }
131 return(i);
132 }
133
134
135 #ifdef INVXF
136 int
137 invxf(ret, ac, av) /* invert transform specification */
138 register XF *ret;
139 int ac;
140 char *av[];
141 {
142 double atof(), sin(), cos();
143 double xfmat[4][4], m4[4][4];
144 double xfsca, dtmp;
145 int i, icnt;
146
147 setident4(ret->xfm);
148 ret->sca = 1.0;
149
150 icnt = 1;
151 setident4(xfmat);
152 xfsca = 1.0;
153
154 for (i = 0; i < ac && av[i][0] == '-'; i++) {
155
156 setident4(m4);
157
158 switch (av[i][1]) {
159
160 case 't': /* translate */
161 checkarg(2,3);
162 m4[3][0] = -atof(av[++i]);
163 m4[3][1] = -atof(av[++i]);
164 m4[3][2] = -atof(av[++i]);
165 break;
166
167 case 'r': /* rotate */
168 switch (av[i][2]) {
169 case 'x':
170 checkarg(3,1);
171 dtmp = -d2r(atof(av[++i]));
172 m4[1][1] = m4[2][2] = cos(dtmp);
173 m4[2][1] = -(m4[1][2] = sin(dtmp));
174 break;
175 case 'y':
176 checkarg(3,1);
177 dtmp = -d2r(atof(av[++i]));
178 m4[0][0] = m4[2][2] = cos(dtmp);
179 m4[0][2] = -(m4[2][0] = sin(dtmp));
180 break;
181 case 'z':
182 checkarg(3,1);
183 dtmp = -d2r(atof(av[++i]));
184 m4[0][0] = m4[1][1] = cos(dtmp);
185 m4[1][0] = -(m4[0][1] = sin(dtmp));
186 break;
187 default:
188 return(i);
189 }
190 break;
191
192 case 's': /* scale */
193 checkarg(2,1);
194 dtmp = atof(av[i+1]);
195 if (dtmp == 0.0) goto done;
196 i++;
197 xfsca *=
198 m4[0][0] =
199 m4[1][1] =
200 m4[2][2] = 1.0 / dtmp;
201 break;
202
203 case 'm': /* mirror */
204 switch (av[i][2]) {
205 case 'x':
206 checkarg(3,0);
207 xfsca *=
208 m4[0][0] = -1.0;
209 break;
210 case 'y':
211 checkarg(3,0);
212 xfsca *=
213 m4[1][1] = -1.0;
214 break;
215 case 'z':
216 checkarg(3,0);
217 xfsca *=
218 m4[2][2] = -1.0;
219 break;
220 default:
221 return(i);
222 }
223 break;
224
225 case 'i': /* iterate */
226 checkarg(2,1);
227 while (icnt-- > 0) {
228 multmat4(ret->xfm, xfmat, ret->xfm);
229 ret->sca *= xfsca;
230 }
231 icnt = atoi(av[++i]);
232 setident4(xfmat);
233 xfsca = 1.0;
234 break;
235
236 default:
237 return(i);
238
239 }
240 multmat4(xfmat, m4, xfmat); /* left multiply */
241 }
242 done:
243 while (icnt-- > 0) {
244 multmat4(ret->xfm, xfmat, ret->xfm);
245 ret->sca *= xfsca;
246 }
247 return(i);
248 }
249
250
251 int
252 fullxf(fx, ac, av) /* compute both forward and inverse */
253 FULLXF *fx;
254 int ac;
255 char *av[];
256 {
257 xf(&fx->f, ac, av);
258 return(invxf(&fx->b, ac, av));
259 }
260 #endif