ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/xf.c
Revision: 2.4
Committed: Sat Feb 22 02:07:23 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.3: +59 -5 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * xf.c - routines to convert transform arguments into 4X4 matrix.
6 *
7 * External symbols declared in standard.h
8 */
9
10 /* ====================================================================
11 * The Radiance Software License, Version 1.0
12 *
13 * Copyright (c) 1990 - 2002 The Regents of the University of California,
14 * through Lawrence Berkeley National Laboratory. All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 *
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 *
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 *
28 * 3. The end-user documentation included with the redistribution,
29 * if any, must include the following acknowledgment:
30 * "This product includes Radiance software
31 * (http://radsite.lbl.gov/)
32 * developed by the Lawrence Berkeley National Laboratory
33 * (http://www.lbl.gov/)."
34 * Alternately, this acknowledgment may appear in the software itself,
35 * if and wherever such third-party acknowledgments normally appear.
36 *
37 * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
38 * and "The Regents of the University of California" must
39 * not be used to endorse or promote products derived from this
40 * software without prior written permission. For written
41 * permission, please contact [email protected].
42 *
43 * 5. Products derived from this software may not be called "Radiance",
44 * nor may "Radiance" appear in their name, without prior written
45 * permission of Lawrence Berkeley National Laboratory.
46 *
47 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
48 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50 * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
51 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
53 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
54 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
56 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 * ====================================================================
60 *
61 * This software consists of voluntary contributions made by many
62 * individuals on behalf of Lawrence Berkeley National Laboratory. For more
63 * information on Lawrence Berkeley National Laboratory, please see
64 * <http://www.lbl.gov/>.
65 */
66
67 #include "standard.h"
68
69 #define d2r(a) ((PI/180.)*(a))
70
71 #define checkarg(a,l) if (av[i][a] || badarg(ac-i-1,av+i+1,l)) goto done
72
73
74 int
75 xf(ret, ac, av) /* get transform specification */
76 register XF *ret;
77 int ac;
78 char *av[];
79 {
80 MAT4 xfmat, m4;
81 double xfsca, dtmp;
82 int i, icnt;
83
84 setident4(ret->xfm);
85 ret->sca = 1.0;
86
87 icnt = 1;
88 setident4(xfmat);
89 xfsca = 1.0;
90
91 for (i = 0; i < ac && av[i][0] == '-'; i++) {
92
93 setident4(m4);
94
95 switch (av[i][1]) {
96
97 case 't': /* translate */
98 checkarg(2,"fff");
99 m4[3][0] = atof(av[++i]);
100 m4[3][1] = atof(av[++i]);
101 m4[3][2] = atof(av[++i]);
102 break;
103
104 case 'r': /* rotate */
105 switch (av[i][2]) {
106 case 'x':
107 checkarg(3,"f");
108 dtmp = d2r(atof(av[++i]));
109 m4[1][1] = m4[2][2] = cos(dtmp);
110 m4[2][1] = -(m4[1][2] = sin(dtmp));
111 break;
112 case 'y':
113 checkarg(3,"f");
114 dtmp = d2r(atof(av[++i]));
115 m4[0][0] = m4[2][2] = cos(dtmp);
116 m4[0][2] = -(m4[2][0] = sin(dtmp));
117 break;
118 case 'z':
119 checkarg(3,"f");
120 dtmp = d2r(atof(av[++i]));
121 m4[0][0] = m4[1][1] = cos(dtmp);
122 m4[1][0] = -(m4[0][1] = sin(dtmp));
123 break;
124 default:
125 goto done;
126 }
127 break;
128
129 case 's': /* scale */
130 checkarg(2,"f");
131 dtmp = atof(av[i+1]);
132 if (dtmp == 0.0) goto done;
133 i++;
134 xfsca *=
135 m4[0][0] =
136 m4[1][1] =
137 m4[2][2] = dtmp;
138 break;
139
140 case 'm': /* mirror */
141 switch (av[i][2]) {
142 case 'x':
143 checkarg(3,"");
144 xfsca *=
145 m4[0][0] = -1.0;
146 break;
147 case 'y':
148 checkarg(3,"");
149 xfsca *=
150 m4[1][1] = -1.0;
151 break;
152 case 'z':
153 checkarg(3,"");
154 xfsca *=
155 m4[2][2] = -1.0;
156 break;
157 default:
158 goto done;
159 }
160 break;
161
162 case 'i': /* iterate */
163 checkarg(2,"i");
164 while (icnt-- > 0) {
165 multmat4(ret->xfm, ret->xfm, xfmat);
166 ret->sca *= xfsca;
167 }
168 icnt = atoi(av[++i]);
169 setident4(xfmat);
170 xfsca = 1.0;
171 continue;
172
173 default:
174 goto done;
175
176 }
177 multmat4(xfmat, xfmat, m4);
178 }
179 done:
180 while (icnt-- > 0) {
181 multmat4(ret->xfm, ret->xfm, xfmat);
182 ret->sca *= xfsca;
183 }
184 return(i);
185 }
186
187
188 int
189 invxf(ret, ac, av) /* invert transform specification */
190 register XF *ret;
191 int ac;
192 char *av[];
193 {
194 MAT4 xfmat, m4;
195 double xfsca, dtmp;
196 int i, icnt;
197
198 setident4(ret->xfm);
199 ret->sca = 1.0;
200
201 icnt = 1;
202 setident4(xfmat);
203 xfsca = 1.0;
204
205 for (i = 0; i < ac && av[i][0] == '-'; i++) {
206
207 setident4(m4);
208
209 switch (av[i][1]) {
210
211 case 't': /* translate */
212 checkarg(2,"fff");
213 m4[3][0] = -atof(av[++i]);
214 m4[3][1] = -atof(av[++i]);
215 m4[3][2] = -atof(av[++i]);
216 break;
217
218 case 'r': /* rotate */
219 switch (av[i][2]) {
220 case 'x':
221 checkarg(3,"f");
222 dtmp = -d2r(atof(av[++i]));
223 m4[1][1] = m4[2][2] = cos(dtmp);
224 m4[2][1] = -(m4[1][2] = sin(dtmp));
225 break;
226 case 'y':
227 checkarg(3,"f");
228 dtmp = -d2r(atof(av[++i]));
229 m4[0][0] = m4[2][2] = cos(dtmp);
230 m4[0][2] = -(m4[2][0] = sin(dtmp));
231 break;
232 case 'z':
233 checkarg(3,"f");
234 dtmp = -d2r(atof(av[++i]));
235 m4[0][0] = m4[1][1] = cos(dtmp);
236 m4[1][0] = -(m4[0][1] = sin(dtmp));
237 break;
238 default:
239 goto done;
240 }
241 break;
242
243 case 's': /* scale */
244 checkarg(2,"f");
245 dtmp = atof(av[i+1]);
246 if (dtmp == 0.0) goto done;
247 i++;
248 xfsca *=
249 m4[0][0] =
250 m4[1][1] =
251 m4[2][2] = 1.0 / dtmp;
252 break;
253
254 case 'm': /* mirror */
255 switch (av[i][2]) {
256 case 'x':
257 checkarg(3,"");
258 xfsca *=
259 m4[0][0] = -1.0;
260 break;
261 case 'y':
262 checkarg(3,"");
263 xfsca *=
264 m4[1][1] = -1.0;
265 break;
266 case 'z':
267 checkarg(3,"");
268 xfsca *=
269 m4[2][2] = -1.0;
270 break;
271 default:
272 goto done;
273 }
274 break;
275
276 case 'i': /* iterate */
277 checkarg(2,"i");
278 while (icnt-- > 0) {
279 multmat4(ret->xfm, xfmat, ret->xfm);
280 ret->sca *= xfsca;
281 }
282 icnt = atoi(av[++i]);
283 setident4(xfmat);
284 xfsca = 1.0;
285 break;
286
287 default:
288 goto done;
289
290 }
291 multmat4(xfmat, m4, xfmat); /* left multiply */
292 }
293 done:
294 while (icnt-- > 0) {
295 multmat4(ret->xfm, xfmat, ret->xfm);
296 ret->sca *= xfsca;
297 }
298 return(i);
299 }
300
301
302 int
303 fullxf(fx, ac, av) /* compute both forward and inverse */
304 FULLXF *fx;
305 int ac;
306 char *av[];
307 {
308 xf(&fx->f, ac, av);
309 return(invxf(&fx->b, ac, av));
310 }