ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/xf.c
Revision: 2.6
Committed: Fri Jun 27 06:53:22 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +4 -5 lines
Log Message:
Broke standard.h into rtio.h, rterror.h, rtmath.h, and rtmisc.h

File Contents

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