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

# User Rev Content
1 greg 1.9 /* Copyright (c) 1990 Regents of the University of California */
2 greg 1.1
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 greg 1.9 #include "standard.h"
14 greg 1.1
15 greg 1.6 #define d2r(a) ((PI/180.)*(a))
16 greg 1.1
17 greg 1.6 #define checkarg(a,n) if (av[i][a] || i+n >= ac) goto done
18 greg 1.1
19 greg 1.2
20 greg 1.1 int
21 greg 1.9 xf(ret, ac, av) /* get transform specification */
22     register XF *ret;
23 greg 1.1 int ac;
24     char *av[];
25     {
26     double atof(), sin(), cos();
27 greg 1.4 double xfmat[4][4], m4[4][4];
28 greg 1.7 double xfsca, dtmp;
29 greg 1.5 int i, icnt;
30 greg 1.1
31 greg 1.9 setident4(ret->xfm);
32     ret->sca = 1.0;
33 greg 1.4
34 greg 1.8 icnt = 1;
35 greg 1.4 setident4(xfmat);
36     xfsca = 1.0;
37    
38 greg 1.1 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 greg 1.6 checkarg(2,3);
46 greg 1.1 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 greg 1.6 checkarg(3,1);
55 greg 1.7 dtmp = d2r(atof(av[++i]));
56     m4[1][1] = m4[2][2] = cos(dtmp);
57     m4[2][1] = -(m4[1][2] = sin(dtmp));
58 greg 1.1 break;
59     case 'y':
60 greg 1.6 checkarg(3,1);
61 greg 1.7 dtmp = d2r(atof(av[++i]));
62     m4[0][0] = m4[2][2] = cos(dtmp);
63     m4[0][2] = -(m4[2][0] = sin(dtmp));
64 greg 1.1 break;
65     case 'z':
66 greg 1.6 checkarg(3,1);
67 greg 1.7 dtmp = d2r(atof(av[++i]));
68     m4[0][0] = m4[1][1] = cos(dtmp);
69     m4[1][0] = -(m4[0][1] = sin(dtmp));
70 greg 1.1 break;
71     default:
72     return(i);
73     }
74     break;
75    
76     case 's': /* scale */
77 greg 1.6 checkarg(2,1);
78 greg 1.7 dtmp = atof(av[i+1]);
79     if (dtmp == 0.0) goto done;
80     i++;
81 greg 1.4 xfsca *=
82 greg 1.1 m4[0][0] =
83     m4[1][1] =
84 greg 1.7 m4[2][2] = dtmp;
85 greg 1.1 break;
86    
87     case 'm': /* mirror */
88     switch (av[i][2]) {
89     case 'x':
90 greg 1.6 checkarg(3,0);
91 greg 1.4 xfsca *=
92 greg 1.1 m4[0][0] = -1.0;
93     break;
94     case 'y':
95 greg 1.6 checkarg(3,0);
96 greg 1.4 xfsca *=
97 greg 1.1 m4[1][1] = -1.0;
98     break;
99     case 'z':
100 greg 1.6 checkarg(3,0);
101 greg 1.4 xfsca *=
102 greg 1.1 m4[2][2] = -1.0;
103     break;
104     default:
105     return(i);
106     }
107     break;
108    
109 greg 1.4 case 'i': /* iterate */
110 greg 1.6 checkarg(2,1);
111 greg 1.5 while (icnt-- > 0) {
112 greg 1.9 multmat4(ret->xfm, ret->xfm, xfmat);
113     ret->sca *= xfsca;
114 greg 1.4 }
115 greg 1.8 icnt = atoi(av[++i]);
116 greg 1.4 setident4(xfmat);
117     xfsca = 1.0;
118 greg 1.8 continue;
119 greg 1.4
120 greg 1.1 default:
121     return(i);
122    
123     }
124     multmat4(xfmat, xfmat, m4);
125     }
126 greg 1.4 done:
127 greg 1.8 while (icnt-- > 0) {
128 greg 1.9 multmat4(ret->xfm, ret->xfm, xfmat);
129     ret->sca *= xfsca;
130 greg 1.8 }
131 greg 1.1 return(i);
132     }
133    
134    
135     #ifdef INVXF
136     int
137 greg 1.9 invxf(ret, ac, av) /* invert transform specification */
138     register XF *ret;
139 greg 1.1 int ac;
140     char *av[];
141     {
142     double atof(), sin(), cos();
143 greg 1.4 double xfmat[4][4], m4[4][4];
144 greg 1.7 double xfsca, dtmp;
145 greg 1.5 int i, icnt;
146 greg 1.1
147 greg 1.9 setident4(ret->xfm);
148     ret->sca = 1.0;
149 greg 1.4
150 greg 1.8 icnt = 1;
151 greg 1.4 setident4(xfmat);
152     xfsca = 1.0;
153    
154 greg 1.1 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 greg 1.6 checkarg(2,3);
162 greg 1.1 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 greg 1.6 checkarg(3,1);
171 greg 1.7 dtmp = -d2r(atof(av[++i]));
172     m4[1][1] = m4[2][2] = cos(dtmp);
173     m4[2][1] = -(m4[1][2] = sin(dtmp));
174 greg 1.1 break;
175     case 'y':
176 greg 1.6 checkarg(3,1);
177 greg 1.7 dtmp = -d2r(atof(av[++i]));
178     m4[0][0] = m4[2][2] = cos(dtmp);
179     m4[0][2] = -(m4[2][0] = sin(dtmp));
180 greg 1.1 break;
181     case 'z':
182 greg 1.6 checkarg(3,1);
183 greg 1.7 dtmp = -d2r(atof(av[++i]));
184     m4[0][0] = m4[1][1] = cos(dtmp);
185     m4[1][0] = -(m4[0][1] = sin(dtmp));
186 greg 1.1 break;
187     default:
188     return(i);
189     }
190     break;
191    
192     case 's': /* scale */
193 greg 1.6 checkarg(2,1);
194 greg 1.7 dtmp = atof(av[i+1]);
195     if (dtmp == 0.0) goto done;
196     i++;
197 greg 1.5 xfsca *=
198 greg 1.1 m4[0][0] =
199     m4[1][1] =
200 greg 1.7 m4[2][2] = 1.0 / dtmp;
201 greg 1.1 break;
202    
203     case 'm': /* mirror */
204     switch (av[i][2]) {
205     case 'x':
206 greg 1.6 checkarg(3,0);
207 greg 1.5 xfsca *=
208 greg 1.1 m4[0][0] = -1.0;
209     break;
210     case 'y':
211 greg 1.6 checkarg(3,0);
212 greg 1.5 xfsca *=
213 greg 1.1 m4[1][1] = -1.0;
214     break;
215     case 'z':
216 greg 1.6 checkarg(3,0);
217 greg 1.5 xfsca *=
218 greg 1.1 m4[2][2] = -1.0;
219     break;
220     default:
221     return(i);
222     }
223     break;
224    
225 greg 1.4 case 'i': /* iterate */
226 greg 1.6 checkarg(2,1);
227 greg 1.5 while (icnt-- > 0) {
228 greg 1.9 multmat4(ret->xfm, xfmat, ret->xfm);
229     ret->sca *= xfsca;
230 greg 1.4 }
231 greg 1.8 icnt = atoi(av[++i]);
232 greg 1.4 setident4(xfmat);
233     xfsca = 1.0;
234     break;
235    
236 greg 1.1 default:
237     return(i);
238    
239     }
240     multmat4(xfmat, m4, xfmat); /* left multiply */
241 greg 1.4 }
242     done:
243 greg 1.8 while (icnt-- > 0) {
244 greg 1.9 multmat4(ret->xfm, xfmat, ret->xfm);
245     ret->sca *= xfsca;
246 greg 1.8 }
247 greg 1.1 return(i);
248 greg 1.9 }
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 greg 1.1 }
260     #endif