ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/image.c
Revision: 1.15
Committed: Thu Apr 18 14:52:55 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.14: +15 -10 lines
Log Message:
changed interface to header routines

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1986 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * image.c - routines for image generation.
9     *
10     * 10/17/85
11     */
12    
13     #include "standard.h"
14    
15     #include "view.h"
16    
17 greg 1.5 VIEW stdview = STDVIEW; /* default view parameters */
18 greg 1.1
19    
20     char *
21 greg 1.5 setview(v) /* set hvec and vvec, return message on error */
22     register VIEW *v;
23 greg 1.3 {
24 greg 1.12 static char ill_horiz[] = "illegal horizontal view size";
25     static char ill_vert[] = "illegal vertical view size";
26    
27 greg 1.1 if (normalize(v->vdir) == 0.0) /* normalize direction */
28     return("zero view direction");
29    
30 greg 1.14 if (normalize(v->vup) == 0.0) /* normalize view up */
31     return("zero view up vector");
32    
33 greg 1.5 fcross(v->hvec, v->vdir, v->vup); /* compute horiz dir */
34    
35     if (normalize(v->hvec) == 0.0)
36 greg 1.14 return("view up parallel to view direction");
37 greg 1.1
38 greg 1.5 fcross(v->vvec, v->hvec, v->vdir); /* compute vert dir */
39    
40 greg 1.12 if (v->horiz <= FTINY)
41     return(ill_horiz);
42     if (v->vert <= FTINY)
43     return(ill_vert);
44    
45     switch (v->type) {
46     case VT_PAR: /* parallel view */
47 greg 1.5 v->hn2 = v->horiz;
48 greg 1.12 v->vn2 = v->vert;
49     break;
50     case VT_PER: /* perspective view */
51     if (v->horiz >= 180.0-FTINY)
52     return(ill_horiz);
53     if (v->vert >= 180.0-FTINY)
54     return(ill_vert);
55 greg 1.5 v->hn2 = 2.0 * tan(v->horiz*(PI/180.0/2.0));
56 greg 1.12 v->vn2 = 2.0 * tan(v->vert*(PI/180.0/2.0));
57     break;
58     case VT_ANG: /* angular fisheye */
59     if (v->horiz > 360.0+FTINY)
60     return(ill_horiz);
61     if (v->vert > 360.0+FTINY)
62     return(ill_vert);
63     v->hn2 = v->horiz / 90.0;
64     v->vn2 = v->vert / 90.0;
65     break;
66     case VT_HEM: /* hemispherical fisheye */
67     if (v->horiz > 180.0+FTINY)
68     return(ill_horiz);
69     if (v->vert > 180.0+FTINY)
70     return(ill_vert);
71     v->hn2 = 2.0 * sin(v->horiz*(PI/180.0/2.0));
72     v->vn2 = 2.0 * sin(v->vert*(PI/180.0/2.0));
73     break;
74     default:
75 greg 1.1 return("unknown view type");
76 greg 1.12 }
77 greg 1.13 if (v->type != VT_ANG) {
78 greg 1.12 v->hvec[0] *= v->hn2;
79     v->hvec[1] *= v->hn2;
80     v->hvec[2] *= v->hn2;
81     v->vvec[0] *= v->vn2;
82     v->vvec[1] *= v->vn2;
83     v->vvec[2] *= v->vn2;
84     }
85 greg 1.5 v->hn2 *= v->hn2;
86     v->vn2 *= v->vn2;
87 greg 1.1
88     return(NULL);
89     }
90    
91    
92 greg 1.7 normaspect(va, ap, xp, yp) /* fix pixel aspect or resolution */
93     double va; /* view aspect ratio */
94     double *ap; /* pixel aspect in (or out if 0) */
95     int *xp, *yp; /* x and y resolution in (or out if *ap!=0) */
96 greg 1.6 {
97     if (*ap <= FTINY)
98 greg 1.7 *ap = va * *xp / *yp; /* compute pixel aspect */
99 greg 1.6 else if (va * *xp > *ap * *yp)
100 greg 1.10 *xp = *yp / va * *ap + .5; /* reduce x resolution */
101 greg 1.6 else
102 greg 1.10 *yp = *xp * va / *ap + .5; /* reduce y resolution */
103 greg 1.6 }
104    
105    
106 greg 1.5 viewray(orig, direc, v, x, y) /* compute ray origin and direction */
107 greg 1.1 FVECT orig, direc;
108     register VIEW *v;
109     double x, y;
110     {
111 greg 1.12 double d, z;
112    
113 greg 1.5 x += v->hoff - 0.5;
114     y += v->voff - 0.5;
115 greg 1.1
116 greg 1.12 switch(v->type) {
117     case VT_PAR: /* parallel view */
118 greg 1.5 orig[0] = v->vp[0] + x*v->hvec[0] + y*v->vvec[0];
119     orig[1] = v->vp[1] + x*v->hvec[1] + y*v->vvec[1];
120     orig[2] = v->vp[2] + x*v->hvec[2] + y*v->vvec[2];
121 greg 1.1 VCOPY(direc, v->vdir);
122 greg 1.12 return(0);
123     case VT_PER: /* perspective view */
124 greg 1.1 VCOPY(orig, v->vp);
125 greg 1.5 direc[0] = v->vdir[0] + x*v->hvec[0] + y*v->vvec[0];
126     direc[1] = v->vdir[1] + x*v->hvec[1] + y*v->vvec[1];
127     direc[2] = v->vdir[2] + x*v->hvec[2] + y*v->vvec[2];
128 greg 1.1 normalize(direc);
129 greg 1.12 return(0);
130     case VT_HEM: /* hemispherical fisheye */
131 greg 1.13 z = 1.0 - x*x*v->hn2 - y*y*v->vn2;
132 greg 1.12 if (z < 0.0)
133     return(-1);
134     z = sqrt(z);
135     VCOPY(orig, v->vp);
136     direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0];
137     direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1];
138     direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2];
139     return(0);
140     case VT_ANG: /* angular fisheye */
141     x *= v->horiz/180.0;
142     y *= v->vert/180.0;
143     d = x*x + y*y;
144     if (d > 1.0)
145     return(-1);
146     VCOPY(orig, v->vp);
147     if (d <= FTINY) {
148     VCOPY(direc, v->vdir);
149     return(0);
150     }
151     d = sqrt(d);
152     z = cos(PI*d);
153     d = sqrt(1 - z*z)/d;
154     x *= d;
155     y *= d;
156     direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0];
157     direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1];
158     direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2];
159     return(0);
160 greg 1.1 }
161 greg 1.12 return(-1);
162 greg 1.1 }
163    
164    
165 greg 1.5 viewpixel(xp, yp, zp, v, p) /* find image location for point */
166 greg 1.3 double *xp, *yp, *zp;
167     register VIEW *v;
168     FVECT p;
169     {
170     double d;
171     FVECT disp;
172 greg 1.5
173 greg 1.3 disp[0] = p[0] - v->vp[0];
174     disp[1] = p[1] - v->vp[1];
175     disp[2] = p[2] - v->vp[2];
176    
177 greg 1.12 switch (v->type) {
178     case VT_PAR: /* parallel view */
179 greg 1.3 if (zp != NULL)
180     *zp = DOT(disp,v->vdir);
181 greg 1.13 break;
182 greg 1.12 case VT_PER: /* perspective view */
183 greg 1.11 d = DOT(disp,v->vdir);
184 greg 1.3 if (zp != NULL) {
185     *zp = sqrt(DOT(disp,disp));
186     if (d < 0.0)
187     *zp = -*zp;
188     }
189 greg 1.11 if (d < 0.0) /* fold pyramid */
190     d = -d;
191     if (d > FTINY) {
192     d = 1.0/d;
193     disp[0] *= d;
194     disp[1] *= d;
195     disp[2] *= d;
196     }
197 greg 1.13 break;
198 greg 1.12 case VT_HEM: /* hemispherical fisheye */
199     d = normalize(disp);
200     if (zp != NULL) {
201     if (DOT(disp,v->vdir) < 0.0)
202     *zp = -d;
203     else
204     *zp = d;
205     }
206 greg 1.13 break;
207 greg 1.12 case VT_ANG: /* angular fisheye */
208     d = normalize(disp);
209     if (zp != NULL)
210     *zp = d;
211     *xp = 0.5 - v->hoff;
212     *yp = 0.5 - v->voff;
213     d = DOT(disp,v->vdir);
214     if (d >= 1.0-FTINY)
215     return;
216     if (d <= -(1.0-FTINY)) {
217     *xp += 180.0/v->horiz;
218     *yp += 180.0/v->vert;
219     return;
220     }
221     d = acos(d)/PI / sqrt(1.0 - d*d);
222     *xp += DOT(disp,v->hvec)*d*180.0/v->horiz;
223     *yp += DOT(disp,v->vvec)*d*180.0/v->vert;
224     return;
225 greg 1.3 }
226 greg 1.13 *xp = DOT(disp,v->hvec)/v->hn2 + 0.5 - v->hoff;
227     *yp = DOT(disp,v->vvec)/v->vn2 + 0.5 - v->voff;
228 greg 1.3 }
229    
230    
231 greg 1.5 int
232     getviewopt(v, ac, av) /* process view argument */
233     register VIEW *v;
234     int ac;
235     register char *av[];
236     {
237     #define check(c,n) if ((av[0][c]&&av[0][c]!=' ') || n>=ac) return(-1)
238     extern double atof();
239    
240 greg 1.9 if (ac <= 0 || av[0][0] != '-' || av[0][1] != 'v')
241 greg 1.5 return(-1);
242     switch (av[0][2]) {
243     case 't': /* type */
244     if (!av[0][3] || av[0][3]==' ')
245     return(-1);
246     check(4,0);
247     v->type = av[0][3];
248     return(0);
249     case 'p': /* point */
250     check(3,3);
251     v->vp[0] = atof(av[1]);
252     v->vp[1] = atof(av[2]);
253     v->vp[2] = atof(av[3]);
254     return(3);
255     case 'd': /* direction */
256     check(3,3);
257     v->vdir[0] = atof(av[1]);
258     v->vdir[1] = atof(av[2]);
259     v->vdir[2] = atof(av[3]);
260     return(3);
261     case 'u': /* up */
262     check(3,3);
263     v->vup[0] = atof(av[1]);
264     v->vup[1] = atof(av[2]);
265     v->vup[2] = atof(av[3]);
266     return(3);
267     case 'h': /* horizontal size */
268     check(3,1);
269     v->horiz = atof(av[1]);
270     return(1);
271     case 'v': /* vertical size */
272     check(3,1);
273     v->vert = atof(av[1]);
274     return(1);
275     case 's': /* shift */
276     check(3,1);
277     v->hoff = atof(av[1]);
278     return(1);
279     case 'l': /* lift */
280     check(3,1);
281     v->voff = atof(av[1]);
282     return(1);
283     default:
284     return(-1);
285     }
286     #undef check
287     }
288    
289    
290     int
291     sscanview(vp, s) /* get view parameters from string */
292     VIEW *vp;
293 greg 1.1 register char *s;
294     {
295 greg 1.5 int ac;
296     char *av[4];
297     int na;
298     int nvopts = 0;
299    
300     while (*s == ' ')
301     s++;
302 greg 1.9 while (*s) {
303 greg 1.5 ac = 0;
304     do {
305     av[ac++] = s;
306     while (*s && *s != ' ')
307     s++;
308     while (*s == ' ')
309     s++;
310     } while (*s && ac < 4);
311     if ((na = getviewopt(vp, ac, av)) >= 0) {
312     if (na+1 < ac)
313     s = av[na+1];
314     nvopts++;
315 greg 1.9 } else if (ac > 1)
316     s = av[1];
317     }
318 greg 1.5 return(nvopts);
319 greg 1.1 }
320    
321    
322     fprintview(vp, fp) /* write out view parameters */
323     register VIEW *vp;
324     FILE *fp;
325     {
326     fprintf(fp, " -vt%c", vp->type);
327     fprintf(fp, " -vp %.6g %.6g %.6g", vp->vp[0], vp->vp[1], vp->vp[2]);
328     fprintf(fp, " -vd %.6g %.6g %.6g", vp->vdir[0], vp->vdir[1], vp->vdir[2]);
329     fprintf(fp, " -vu %.6g %.6g %.6g", vp->vup[0], vp->vup[1], vp->vup[2]);
330     fprintf(fp, " -vh %.6g -vv %.6g", vp->horiz, vp->vert);
331 greg 1.9 fprintf(fp, " -vs %.6g -vl %.6g", vp->hoff, vp->voff);
332 greg 1.1 }
333    
334    
335 greg 1.3 static char *altname[] = {NULL,"rpict","rview","pinterp",VIEWSTR,NULL};
336 greg 1.1
337 greg 1.15 struct myview {
338     VIEW *hv;
339     int ok;
340     };
341 greg 1.1
342 greg 1.15
343 greg 1.1 static
344 greg 1.15 gethview(s, v) /* get view from header */
345 greg 1.1 char *s;
346 greg 1.15 register struct myview *v;
347 greg 1.1 {
348     register char **an;
349    
350     for (an = altname; *an != NULL; an++)
351     if (!strncmp(*an, s, strlen(*an))) {
352 greg 1.15 if (sscanview(v->hv, s+strlen(*an)) > 0)
353     v->ok++;
354 greg 1.1 return;
355     }
356     }
357    
358    
359     int
360 greg 1.8 viewfile(fname, vp, xp, yp) /* get view from file */
361 greg 1.1 char *fname;
362     VIEW *vp;
363 greg 1.8 int *xp, *yp;
364 greg 1.1 {
365     extern char *progname;
366 greg 1.15 struct myview mvs;
367 greg 1.1 FILE *fp;
368    
369     if ((fp = fopen(fname, "r")) == NULL)
370     return(-1);
371    
372     altname[0] = progname;
373 greg 1.15 mvs.hv = vp;
374     mvs.ok = 0;
375 greg 1.1
376 greg 1.15 getheader(fp, gethview, &mvs);
377 greg 1.8
378     if (xp != NULL && yp != NULL
379     && fgetresolu(xp, yp, fp) == -1)
380 greg 1.15 mvs.ok = 0;
381 greg 1.1
382     fclose(fp);
383    
384 greg 1.15 return(mvs.ok);
385 greg 1.1 }