ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/xf.c
Revision: 2.5
Committed: Tue Feb 25 02:47:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.4: +1 -56 lines
Log Message:
Replaced inline copyright notice with #include "copyright.h"

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