ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/image.c
Revision: 1.12
Committed: Sat Oct 13 20:56:01 1990 UTC (33 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +123 -31 lines
Log Message:
added fisheye view types

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