ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/image.c
Revision: 1.13
Committed: Mon Oct 15 14:17:05 1990 UTC (33 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.12: +7 -13 lines
Log Message:
fixed bug in hemispherical view calculation

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 greg 1.13 if (v->type != VT_ANG) {
75 greg 1.12 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 greg 1.13 z = 1.0 - x*x*v->hn2 - y*y*v->vn2;
129 greg 1.12 if (z < 0.0)
130     return(-1);
131     z = sqrt(z);
132     VCOPY(orig, v->vp);
133     direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0];
134     direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1];
135     direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2];
136     return(0);
137     case VT_ANG: /* angular fisheye */
138     x *= v->horiz/180.0;
139     y *= v->vert/180.0;
140     d = x*x + y*y;
141     if (d > 1.0)
142     return(-1);
143     VCOPY(orig, v->vp);
144     if (d <= FTINY) {
145     VCOPY(direc, v->vdir);
146     return(0);
147     }
148     d = sqrt(d);
149     z = cos(PI*d);
150     d = sqrt(1 - z*z)/d;
151     x *= d;
152     y *= d;
153     direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0];
154     direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1];
155     direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2];
156     return(0);
157 greg 1.1 }
158 greg 1.12 return(-1);
159 greg 1.1 }
160    
161    
162 greg 1.5 viewpixel(xp, yp, zp, v, p) /* find image location for point */
163 greg 1.3 double *xp, *yp, *zp;
164     register VIEW *v;
165     FVECT p;
166     {
167     double d;
168     FVECT disp;
169 greg 1.5
170 greg 1.3 disp[0] = p[0] - v->vp[0];
171     disp[1] = p[1] - v->vp[1];
172     disp[2] = p[2] - v->vp[2];
173    
174 greg 1.12 switch (v->type) {
175     case VT_PAR: /* parallel view */
176 greg 1.3 if (zp != NULL)
177     *zp = DOT(disp,v->vdir);
178 greg 1.13 break;
179 greg 1.12 case VT_PER: /* perspective view */
180 greg 1.11 d = DOT(disp,v->vdir);
181 greg 1.3 if (zp != NULL) {
182     *zp = sqrt(DOT(disp,disp));
183     if (d < 0.0)
184     *zp = -*zp;
185     }
186 greg 1.11 if (d < 0.0) /* fold pyramid */
187     d = -d;
188     if (d > FTINY) {
189     d = 1.0/d;
190     disp[0] *= d;
191     disp[1] *= d;
192     disp[2] *= d;
193     }
194 greg 1.13 break;
195 greg 1.12 case VT_HEM: /* hemispherical fisheye */
196     d = normalize(disp);
197     if (zp != NULL) {
198     if (DOT(disp,v->vdir) < 0.0)
199     *zp = -d;
200     else
201     *zp = d;
202     }
203 greg 1.13 break;
204 greg 1.12 case VT_ANG: /* angular fisheye */
205     d = normalize(disp);
206     if (zp != NULL)
207     *zp = d;
208     *xp = 0.5 - v->hoff;
209     *yp = 0.5 - v->voff;
210     d = DOT(disp,v->vdir);
211     if (d >= 1.0-FTINY)
212     return;
213     if (d <= -(1.0-FTINY)) {
214     *xp += 180.0/v->horiz;
215     *yp += 180.0/v->vert;
216     return;
217     }
218     d = acos(d)/PI / sqrt(1.0 - d*d);
219     *xp += DOT(disp,v->hvec)*d*180.0/v->horiz;
220     *yp += DOT(disp,v->vvec)*d*180.0/v->vert;
221     return;
222 greg 1.3 }
223 greg 1.13 *xp = DOT(disp,v->hvec)/v->hn2 + 0.5 - v->hoff;
224     *yp = DOT(disp,v->vvec)/v->vn2 + 0.5 - v->voff;
225 greg 1.3 }
226    
227    
228 greg 1.5 int
229     getviewopt(v, ac, av) /* process view argument */
230     register VIEW *v;
231     int ac;
232     register char *av[];
233     {
234     #define check(c,n) if ((av[0][c]&&av[0][c]!=' ') || n>=ac) return(-1)
235     extern double atof();
236    
237 greg 1.9 if (ac <= 0 || av[0][0] != '-' || av[0][1] != 'v')
238 greg 1.5 return(-1);
239     switch (av[0][2]) {
240     case 't': /* type */
241     if (!av[0][3] || av[0][3]==' ')
242     return(-1);
243     check(4,0);
244     v->type = av[0][3];
245     return(0);
246     case 'p': /* point */
247     check(3,3);
248     v->vp[0] = atof(av[1]);
249     v->vp[1] = atof(av[2]);
250     v->vp[2] = atof(av[3]);
251     return(3);
252     case 'd': /* direction */
253     check(3,3);
254     v->vdir[0] = atof(av[1]);
255     v->vdir[1] = atof(av[2]);
256     v->vdir[2] = atof(av[3]);
257     return(3);
258     case 'u': /* up */
259     check(3,3);
260     v->vup[0] = atof(av[1]);
261     v->vup[1] = atof(av[2]);
262     v->vup[2] = atof(av[3]);
263     return(3);
264     case 'h': /* horizontal size */
265     check(3,1);
266     v->horiz = atof(av[1]);
267     return(1);
268     case 'v': /* vertical size */
269     check(3,1);
270     v->vert = atof(av[1]);
271     return(1);
272     case 's': /* shift */
273     check(3,1);
274     v->hoff = atof(av[1]);
275     return(1);
276     case 'l': /* lift */
277     check(3,1);
278     v->voff = atof(av[1]);
279     return(1);
280     default:
281     return(-1);
282     }
283     #undef check
284     }
285    
286    
287     int
288     sscanview(vp, s) /* get view parameters from string */
289     VIEW *vp;
290 greg 1.1 register char *s;
291     {
292 greg 1.5 int ac;
293     char *av[4];
294     int na;
295     int nvopts = 0;
296    
297     while (*s == ' ')
298     s++;
299 greg 1.9 while (*s) {
300 greg 1.5 ac = 0;
301     do {
302     av[ac++] = s;
303     while (*s && *s != ' ')
304     s++;
305     while (*s == ' ')
306     s++;
307     } while (*s && ac < 4);
308     if ((na = getviewopt(vp, ac, av)) >= 0) {
309     if (na+1 < ac)
310     s = av[na+1];
311     nvopts++;
312 greg 1.9 } else if (ac > 1)
313     s = av[1];
314     }
315 greg 1.5 return(nvopts);
316 greg 1.1 }
317    
318    
319     fprintview(vp, fp) /* write out view parameters */
320     register VIEW *vp;
321     FILE *fp;
322     {
323     fprintf(fp, " -vt%c", vp->type);
324     fprintf(fp, " -vp %.6g %.6g %.6g", vp->vp[0], vp->vp[1], vp->vp[2]);
325     fprintf(fp, " -vd %.6g %.6g %.6g", vp->vdir[0], vp->vdir[1], vp->vdir[2]);
326     fprintf(fp, " -vu %.6g %.6g %.6g", vp->vup[0], vp->vup[1], vp->vup[2]);
327     fprintf(fp, " -vh %.6g -vv %.6g", vp->horiz, vp->vert);
328 greg 1.9 fprintf(fp, " -vs %.6g -vl %.6g", vp->hoff, vp->voff);
329 greg 1.1 }
330    
331    
332     static VIEW *hview; /* view from header */
333     static int gothview; /* success indicator */
334 greg 1.3 static char *altname[] = {NULL,"rpict","rview","pinterp",VIEWSTR,NULL};
335 greg 1.1
336    
337     static
338     gethview(s) /* get view from header */
339     char *s;
340     {
341     register char **an;
342    
343     for (an = altname; *an != NULL; an++)
344     if (!strncmp(*an, s, strlen(*an))) {
345 greg 1.5 if (sscanview(hview, s+strlen(*an)) > 0)
346 greg 1.1 gothview++;
347     return;
348     }
349     }
350    
351    
352     int
353 greg 1.8 viewfile(fname, vp, xp, yp) /* get view from file */
354 greg 1.1 char *fname;
355     VIEW *vp;
356 greg 1.8 int *xp, *yp;
357 greg 1.1 {
358     extern char *progname;
359     FILE *fp;
360    
361     if ((fp = fopen(fname, "r")) == NULL)
362     return(-1);
363    
364     altname[0] = progname;
365     hview = vp;
366     gothview = 0;
367    
368     getheader(fp, gethview);
369 greg 1.8
370     if (xp != NULL && yp != NULL
371     && fgetresolu(xp, yp, fp) == -1)
372     gothview = 0;
373 greg 1.1
374     fclose(fp);
375    
376     return(gothview);
377     }