1 |
< |
/* Copyright (c) 1991 Regents of the University of California */ |
1 |
> |
/* Copyright (c) 1994 Regents of the University of California */ |
2 |
|
|
3 |
|
#ifndef lint |
4 |
|
static char SCCSid[] = "$SunId$ LBL"; |
16 |
|
|
17 |
|
#include "resolu.h" |
18 |
|
|
19 |
+ |
#include "paths.h" |
20 |
+ |
|
21 |
|
VIEW stdview = STDVIEW; /* default view parameters */ |
22 |
|
|
23 |
|
|
28 |
|
static char ill_horiz[] = "illegal horizontal view size"; |
29 |
|
static char ill_vert[] = "illegal vertical view size"; |
30 |
|
|
31 |
+ |
if (v->vfore < -FTINY || v->vaft < -FTINY || |
32 |
+ |
(v->vaft > FTINY && v->vaft <= v->vfore)) |
33 |
+ |
return("illegal fore/aft clipping plane"); |
34 |
+ |
|
35 |
|
if (normalize(v->vdir) == 0.0) /* normalize direction */ |
36 |
|
return("zero view direction"); |
37 |
|
|
111 |
|
} |
112 |
|
|
113 |
|
|
114 |
+ |
double |
115 |
|
viewray(orig, direc, v, x, y) /* compute ray origin and direction */ |
116 |
|
FVECT orig, direc; |
117 |
|
register VIEW *v; |
124 |
|
|
125 |
|
switch(v->type) { |
126 |
|
case VT_PAR: /* parallel view */ |
127 |
< |
orig[0] = v->vp[0] + x*v->hvec[0] + y*v->vvec[0]; |
128 |
< |
orig[1] = v->vp[1] + x*v->hvec[1] + y*v->vvec[1]; |
129 |
< |
orig[2] = v->vp[2] + x*v->hvec[2] + y*v->vvec[2]; |
127 |
> |
orig[0] = v->vp[0] + v->vfore*v->vdir[0] |
128 |
> |
+ x*v->hvec[0] + y*v->vvec[0]; |
129 |
> |
orig[1] = v->vp[1] + v->vfore*v->vdir[1] |
130 |
> |
+ x*v->hvec[1] + y*v->vvec[1]; |
131 |
> |
orig[2] = v->vp[2] + v->vfore*v->vdir[2] |
132 |
> |
+ x*v->hvec[2] + y*v->vvec[2]; |
133 |
|
VCOPY(direc, v->vdir); |
134 |
< |
return(0); |
134 |
> |
return(v->vaft > FTINY ? v->vaft - v->vfore : 0.0); |
135 |
|
case VT_PER: /* perspective view */ |
126 |
– |
VCOPY(orig, v->vp); |
136 |
|
direc[0] = v->vdir[0] + x*v->hvec[0] + y*v->vvec[0]; |
137 |
|
direc[1] = v->vdir[1] + x*v->hvec[1] + y*v->vvec[1]; |
138 |
|
direc[2] = v->vdir[2] + x*v->hvec[2] + y*v->vvec[2]; |
139 |
< |
normalize(direc); |
140 |
< |
return(0); |
139 |
> |
orig[0] = v->vp[0] + v->vfore*direc[0]; |
140 |
> |
orig[1] = v->vp[1] + v->vfore*direc[1]; |
141 |
> |
orig[2] = v->vp[2] + v->vfore*direc[2]; |
142 |
> |
d = normalize(direc); |
143 |
> |
return(v->vaft > FTINY ? (v->vaft - v->vfore)*d : 0.0); |
144 |
|
case VT_HEM: /* hemispherical fisheye */ |
145 |
|
z = 1.0 - x*x*v->hn2 - y*y*v->vn2; |
146 |
|
if (z < 0.0) |
147 |
< |
return(-1); |
147 |
> |
return(-1.0); |
148 |
|
z = sqrt(z); |
137 |
– |
VCOPY(orig, v->vp); |
149 |
|
direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0]; |
150 |
|
direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1]; |
151 |
|
direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2]; |
152 |
< |
return(0); |
152 |
> |
orig[0] = v->vp[0] + v->vfore*direc[0]; |
153 |
> |
orig[1] = v->vp[1] + v->vfore*direc[1]; |
154 |
> |
orig[2] = v->vp[2] + v->vfore*direc[2]; |
155 |
> |
return(v->vaft > FTINY ? v->vaft - v->vfore : 0.0); |
156 |
|
case VT_ANG: /* angular fisheye */ |
157 |
|
x *= v->horiz/180.0; |
158 |
|
y *= v->vert/180.0; |
159 |
|
d = x*x + y*y; |
160 |
|
if (d > 1.0) |
161 |
< |
return(-1); |
148 |
< |
VCOPY(orig, v->vp); |
149 |
< |
if (d <= FTINY) { |
150 |
< |
VCOPY(direc, v->vdir); |
151 |
< |
return(0); |
152 |
< |
} |
161 |
> |
return(-1.0); |
162 |
|
d = sqrt(d); |
163 |
|
z = cos(PI*d); |
164 |
< |
d = sqrt(1 - z*z)/d; |
164 |
> |
d = d <= FTINY ? PI : sqrt(1 - z*z)/d; |
165 |
|
x *= d; |
166 |
|
y *= d; |
167 |
|
direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0]; |
168 |
|
direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1]; |
169 |
|
direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2]; |
170 |
< |
return(0); |
170 |
> |
orig[0] = v->vp[0] + v->vfore*direc[0]; |
171 |
> |
orig[1] = v->vp[1] + v->vfore*direc[1]; |
172 |
> |
orig[2] = v->vp[2] + v->vfore*direc[2]; |
173 |
> |
return(v->vaft > FTINY ? v->vaft - v->vfore : 0.0); |
174 |
|
} |
175 |
< |
return(-1); |
175 |
> |
return(-1.0); |
176 |
|
} |
177 |
|
|
178 |
|
|
190 |
|
|
191 |
|
switch (v->type) { |
192 |
|
case VT_PAR: /* parallel view */ |
193 |
< |
ip[2] = DOT(disp,v->vdir); |
193 |
> |
ip[2] = DOT(disp,v->vdir) - v->vfore; |
194 |
|
break; |
195 |
|
case VT_PER: /* perspective view */ |
196 |
|
d = DOT(disp,v->vdir); |
198 |
|
if (d < 0.0) { /* fold pyramid */ |
199 |
|
ip[2] = -ip[2]; |
200 |
|
d = -d; |
201 |
< |
} else if (d > FTINY) { |
201 |
> |
} |
202 |
> |
if (d > FTINY) { |
203 |
|
d = 1.0/d; |
204 |
|
disp[0] *= d; |
205 |
|
disp[1] *= d; |
206 |
|
disp[2] *= d; |
207 |
|
} |
208 |
+ |
ip[2] *= (1.0 - v->vfore*d); |
209 |
|
break; |
210 |
|
case VT_HEM: /* hemispherical fisheye */ |
211 |
|
d = normalize(disp); |
213 |
|
ip[2] = -d; |
214 |
|
else |
215 |
|
ip[2] = d; |
216 |
+ |
ip[2] -= v->vfore; |
217 |
|
break; |
218 |
|
case VT_ANG: /* angular fisheye */ |
219 |
|
ip[0] = 0.5 - v->hoff; |
220 |
|
ip[1] = 0.5 - v->voff; |
221 |
< |
ip[2] = normalize(disp); |
221 |
> |
ip[2] = normalize(disp) - v->vfore; |
222 |
|
d = DOT(disp,v->vdir); |
223 |
|
if (d >= 1.0-FTINY) |
224 |
|
return; |
225 |
|
if (d <= -(1.0-FTINY)) { |
226 |
< |
ip[1] += 180.0/v->horiz; |
227 |
< |
ip[2] += 180.0/v->vert; |
226 |
> |
ip[0] += 180.0/v->horiz; |
227 |
> |
ip[1] += 180.0/v->vert; |
228 |
|
return; |
229 |
|
} |
230 |
|
d = acos(d)/PI / sqrt(1.0 - d*d); |
327 |
|
check(3,"f"); |
328 |
|
v->vert = atof(av[1]); |
329 |
|
return(1); |
330 |
+ |
case 'o': /* fore clipping plane */ |
331 |
+ |
check(3,"f"); |
332 |
+ |
v->vfore = atof(av[1]); |
333 |
+ |
return(1); |
334 |
+ |
case 'a': /* aft clipping plane */ |
335 |
+ |
check(3,"f"); |
336 |
+ |
v->vaft = atof(av[1]); |
337 |
+ |
return(1); |
338 |
|
case 's': /* shift */ |
339 |
|
check(3,"f"); |
340 |
|
v->hoff = atof(av[1]); |
391 |
|
fprintf(fp, " -vd %.6g %.6g %.6g", vp->vdir[0], vp->vdir[1], vp->vdir[2]); |
392 |
|
fprintf(fp, " -vu %.6g %.6g %.6g", vp->vup[0], vp->vup[1], vp->vup[2]); |
393 |
|
fprintf(fp, " -vh %.6g -vv %.6g", vp->horiz, vp->vert); |
394 |
+ |
fprintf(fp, " -vo %.6g -va %.6g", vp->vfore, vp->vaft); |
395 |
|
fprintf(fp, " -vs %.6g -vl %.6g", vp->hoff, vp->voff); |
396 |
|
} |
397 |
|
|
400 |
|
isview(s) /* is this a view string? */ |
401 |
|
char *s; |
402 |
|
{ |
403 |
< |
static char *altname[]={NULL,"rpict","rview","pinterp",VIEWSTR,NULL}; |
404 |
< |
extern char *progname, *rindex(); |
403 |
> |
static char *altname[]={NULL,VIEWSTR,"rpict","rview","pinterp",NULL}; |
404 |
> |
extern char *progname; |
405 |
|
register char *cp; |
406 |
|
register char **an; |
407 |
|
/* add program name to list */ |
408 |
< |
if (altname[0] == NULL) |
409 |
< |
if ((cp = rindex(progname, '/')) != NULL) |
410 |
< |
altname[0] = cp+1; |
411 |
< |
else |
412 |
< |
altname[0] = progname; |
408 |
> |
if (altname[0] == NULL) { |
409 |
> |
for (cp = progname; *cp; cp++) |
410 |
> |
; |
411 |
> |
while (cp > progname && !ISDIRSEP(cp[-1])) |
412 |
> |
cp--; |
413 |
> |
altname[0] = cp; |
414 |
> |
} |
415 |
|
/* skip leading path */ |
416 |
|
cp = s; |
417 |
|
while (*cp && *cp != ' ') |
418 |
|
cp++; |
419 |
< |
while (cp > s && cp[-1] != '/') |
419 |
> |
while (cp > s && !ISDIRSEP(cp[-1])) |
420 |
|
cp--; |
421 |
|
for (an = altname; *an != NULL; an++) |
422 |
|
if (!strncmp(*an, cp, strlen(*an))) |