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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.4 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * xf.c - routines to convert transform arguments into 4X4 matrix.
6     *
7 greg 2.4 * 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 greg 1.1 */
66    
67 greg 1.9 #include "standard.h"
68 greg 1.1
69 greg 1.6 #define d2r(a) ((PI/180.)*(a))
70 greg 1.1
71 greg 1.12 #define checkarg(a,l) if (av[i][a] || badarg(ac-i-1,av+i+1,l)) goto done
72 greg 1.1
73 greg 1.2
74 greg 1.1 int
75 greg 1.9 xf(ret, ac, av) /* get transform specification */
76     register XF *ret;
77 greg 1.1 int ac;
78     char *av[];
79     {
80 greg 1.11 MAT4 xfmat, m4;
81 greg 1.7 double xfsca, dtmp;
82 greg 1.5 int i, icnt;
83 greg 1.1
84 greg 1.9 setident4(ret->xfm);
85     ret->sca = 1.0;
86 greg 1.4
87 greg 1.8 icnt = 1;
88 greg 1.4 setident4(xfmat);
89     xfsca = 1.0;
90    
91 greg 1.1 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 greg 1.12 checkarg(2,"fff");
99 greg 1.1 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 greg 1.12 checkarg(3,"f");
108 greg 1.7 dtmp = d2r(atof(av[++i]));
109     m4[1][1] = m4[2][2] = cos(dtmp);
110     m4[2][1] = -(m4[1][2] = sin(dtmp));
111 greg 1.1 break;
112     case 'y':
113 greg 1.12 checkarg(3,"f");
114 greg 1.7 dtmp = d2r(atof(av[++i]));
115     m4[0][0] = m4[2][2] = cos(dtmp);
116     m4[0][2] = -(m4[2][0] = sin(dtmp));
117 greg 1.1 break;
118     case 'z':
119 greg 1.12 checkarg(3,"f");
120 greg 1.7 dtmp = d2r(atof(av[++i]));
121     m4[0][0] = m4[1][1] = cos(dtmp);
122     m4[1][0] = -(m4[0][1] = sin(dtmp));
123 greg 1.1 break;
124     default:
125 greg 2.3 goto done;
126 greg 1.1 }
127     break;
128    
129     case 's': /* scale */
130 greg 1.12 checkarg(2,"f");
131 greg 1.7 dtmp = atof(av[i+1]);
132     if (dtmp == 0.0) goto done;
133     i++;
134 greg 1.4 xfsca *=
135 greg 1.1 m4[0][0] =
136     m4[1][1] =
137 greg 1.7 m4[2][2] = dtmp;
138 greg 1.1 break;
139    
140     case 'm': /* mirror */
141     switch (av[i][2]) {
142     case 'x':
143 greg 1.12 checkarg(3,"");
144 greg 1.4 xfsca *=
145 greg 1.1 m4[0][0] = -1.0;
146     break;
147     case 'y':
148 greg 1.12 checkarg(3,"");
149 greg 1.4 xfsca *=
150 greg 1.1 m4[1][1] = -1.0;
151     break;
152     case 'z':
153 greg 1.12 checkarg(3,"");
154 greg 1.4 xfsca *=
155 greg 1.1 m4[2][2] = -1.0;
156     break;
157     default:
158 greg 2.3 goto done;
159 greg 1.1 }
160     break;
161    
162 greg 1.4 case 'i': /* iterate */
163 greg 1.12 checkarg(2,"i");
164 greg 1.5 while (icnt-- > 0) {
165 greg 1.9 multmat4(ret->xfm, ret->xfm, xfmat);
166     ret->sca *= xfsca;
167 greg 1.4 }
168 greg 1.8 icnt = atoi(av[++i]);
169 greg 1.4 setident4(xfmat);
170     xfsca = 1.0;
171 greg 1.8 continue;
172 greg 1.4
173 greg 1.1 default:
174 greg 2.3 goto done;
175 greg 1.1
176     }
177     multmat4(xfmat, xfmat, m4);
178     }
179 greg 1.4 done:
180 greg 1.8 while (icnt-- > 0) {
181 greg 1.9 multmat4(ret->xfm, ret->xfm, xfmat);
182     ret->sca *= xfsca;
183 greg 1.8 }
184 greg 1.1 return(i);
185     }
186    
187    
188     int
189 greg 1.9 invxf(ret, ac, av) /* invert transform specification */
190     register XF *ret;
191 greg 1.1 int ac;
192     char *av[];
193     {
194 greg 1.11 MAT4 xfmat, m4;
195 greg 1.7 double xfsca, dtmp;
196 greg 1.5 int i, icnt;
197 greg 1.1
198 greg 1.9 setident4(ret->xfm);
199     ret->sca = 1.0;
200 greg 1.4
201 greg 1.8 icnt = 1;
202 greg 1.4 setident4(xfmat);
203     xfsca = 1.0;
204    
205 greg 1.1 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 greg 1.12 checkarg(2,"fff");
213 greg 1.1 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 greg 1.12 checkarg(3,"f");
222 greg 1.7 dtmp = -d2r(atof(av[++i]));
223     m4[1][1] = m4[2][2] = cos(dtmp);
224     m4[2][1] = -(m4[1][2] = sin(dtmp));
225 greg 1.1 break;
226     case 'y':
227 greg 1.12 checkarg(3,"f");
228 greg 1.7 dtmp = -d2r(atof(av[++i]));
229     m4[0][0] = m4[2][2] = cos(dtmp);
230     m4[0][2] = -(m4[2][0] = sin(dtmp));
231 greg 1.1 break;
232     case 'z':
233 greg 1.12 checkarg(3,"f");
234 greg 1.7 dtmp = -d2r(atof(av[++i]));
235     m4[0][0] = m4[1][1] = cos(dtmp);
236     m4[1][0] = -(m4[0][1] = sin(dtmp));
237 greg 1.1 break;
238     default:
239 greg 2.3 goto done;
240 greg 1.1 }
241     break;
242    
243     case 's': /* scale */
244 greg 1.12 checkarg(2,"f");
245 greg 1.7 dtmp = atof(av[i+1]);
246     if (dtmp == 0.0) goto done;
247     i++;
248 greg 1.5 xfsca *=
249 greg 1.1 m4[0][0] =
250     m4[1][1] =
251 greg 1.7 m4[2][2] = 1.0 / dtmp;
252 greg 1.1 break;
253    
254     case 'm': /* mirror */
255     switch (av[i][2]) {
256     case 'x':
257 greg 1.12 checkarg(3,"");
258 greg 1.5 xfsca *=
259 greg 1.1 m4[0][0] = -1.0;
260     break;
261     case 'y':
262 greg 1.12 checkarg(3,"");
263 greg 1.5 xfsca *=
264 greg 1.1 m4[1][1] = -1.0;
265     break;
266     case 'z':
267 greg 1.12 checkarg(3,"");
268 greg 1.5 xfsca *=
269 greg 1.1 m4[2][2] = -1.0;
270     break;
271     default:
272 greg 2.3 goto done;
273 greg 1.1 }
274     break;
275    
276 greg 1.4 case 'i': /* iterate */
277 greg 1.12 checkarg(2,"i");
278 greg 1.5 while (icnt-- > 0) {
279 greg 1.9 multmat4(ret->xfm, xfmat, ret->xfm);
280     ret->sca *= xfsca;
281 greg 1.4 }
282 greg 1.8 icnt = atoi(av[++i]);
283 greg 1.4 setident4(xfmat);
284     xfsca = 1.0;
285     break;
286    
287 greg 1.1 default:
288 greg 2.3 goto done;
289 greg 1.1
290     }
291     multmat4(xfmat, m4, xfmat); /* left multiply */
292 greg 1.4 }
293     done:
294 greg 1.8 while (icnt-- > 0) {
295 greg 1.9 multmat4(ret->xfm, xfmat, ret->xfm);
296     ret->sca *= xfsca;
297 greg 1.8 }
298 greg 1.1 return(i);
299 greg 1.9 }
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 greg 1.1 }