--- ray/src/common/image.c 2008/12/12 22:05:38 2.35 +++ ray/src/common/image.c 2018/01/24 04:23:06 2.42 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: image.c,v 2.35 2008/12/12 22:05:38 greg Exp $"; +static const char RCSid[] = "$Id: image.c,v 2.42 2018/01/24 04:23:06 greg Exp $"; #endif /* * image.c - routines for image generation. @@ -33,7 +33,8 @@ VIEW *v static char ill_horiz[] = "illegal horizontal view size"; static char ill_vert[] = "illegal vertical view size"; - if (v->vaft < -FTINY || (v->vaft > FTINY && v->vaft <= v->vfore)) + if ((v->vfore < -FTINY) | (v->vaft < -FTINY) || + (v->vaft > FTINY) & (v->vaft <= v->vfore)) return("illegal fore/aft clipping plane"); if (v->vdist <= FTINY) @@ -169,9 +170,7 @@ double y direc[0] = v->vdir[0] + x*v->hvec[0] + y*v->vvec[0]; direc[1] = v->vdir[1] + x*v->hvec[1] + y*v->vvec[1]; direc[2] = v->vdir[2] + x*v->hvec[2] + y*v->vvec[2]; - orig[0] = v->vp[0] + v->vfore*direc[0]; - orig[1] = v->vp[1] + v->vfore*direc[1]; - orig[2] = v->vp[2] + v->vfore*direc[2]; + VSUM(orig, v->vp, direc, v->vfore); d = normalize(direc); return(v->vaft > FTINY ? (v->vaft - v->vfore)*d : 0.0); case VT_HEM: /* hemispherical fisheye */ @@ -182,9 +181,7 @@ double y direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0]; direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1]; direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2]; - orig[0] = v->vp[0] + v->vfore*direc[0]; - orig[1] = v->vp[1] + v->vfore*direc[1]; - orig[2] = v->vp[2] + v->vfore*direc[2]; + VSUM(orig, v->vp, direc, v->vfore); return(v->vaft > FTINY ? v->vaft - v->vfore : 0.0); case VT_CYL: /* cylindrical panorama */ d = x * v->horiz * (PI/180.0); @@ -193,9 +190,7 @@ double y direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0]; direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1]; direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2]; - orig[0] = v->vp[0] + v->vfore*direc[0]; - orig[1] = v->vp[1] + v->vfore*direc[1]; - orig[2] = v->vp[2] + v->vfore*direc[2]; + VSUM(orig, v->vp, direc, v->vfore); d = normalize(direc); return(v->vaft > FTINY ? (v->vaft - v->vfore)*d : 0.0); case VT_ANG: /* angular fisheye */ @@ -212,31 +207,26 @@ double y direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0]; direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1]; direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2]; - orig[0] = v->vp[0] + v->vfore*direc[0]; - orig[1] = v->vp[1] + v->vfore*direc[1]; - orig[2] = v->vp[2] + v->vfore*direc[2]; + VSUM(orig, v->vp, direc, v->vfore); return(v->vaft > FTINY ? v->vaft - v->vfore : 0.0); case VT_PLS: /* planispheric fisheye */ x *= sqrt(v->hn2); y *= sqrt(v->vn2); d = x*x + y*y; z = (1. - d)/(1. + d); - d = d <= FTINY*FTINY ? PI : sqrt((1.0 - z*z)/d); - x *= d; - y *= d; + x *= (1. + z); + y *= (1. + z); direc[0] = z*v->vdir[0] + x*v->hvec[0] + y*v->vvec[0]; direc[1] = z*v->vdir[1] + x*v->hvec[1] + y*v->vvec[1]; direc[2] = z*v->vdir[2] + x*v->hvec[2] + y*v->vvec[2]; - orig[0] = v->vp[0] + v->vfore*direc[0]; - orig[1] = v->vp[1] + v->vfore*direc[1]; - orig[2] = v->vp[2] + v->vfore*direc[2]; + VSUM(orig, v->vp, direc, v->vfore); return(v->vaft > FTINY ? v->vaft - v->vfore : 0.0); } return(-1.0); } -void +int viewloc( /* find image location for point */ FVECT ip, VIEW *v, @@ -255,16 +245,16 @@ FVECT p case VT_PER: /* perspective view */ d = DOT(disp,v->vdir); ip[2] = VLEN(disp); - if (d < 0.0) { /* fold pyramid */ + if (d < -FTINY) { /* fold pyramid */ ip[2] = -ip[2]; d = -d; - } - if (d > FTINY) { - d = 1.0/d; - disp[0] *= d; - disp[1] *= d; - disp[2] *= d; - } + } else if (d <= FTINY) + return(0); /* at infinite edge */ + d = 1.0/d; + disp[0] *= d; + disp[1] *= d; + disp[2] *= d; + if (ip[2] < 0.0) d = -d; ip[2] *= (1.0 - v->vfore*d); break; case VT_HEM: /* hemispherical fisheye */ @@ -279,42 +269,46 @@ FVECT p d = DOT(disp,v->hvec); d2 = DOT(disp,v->vdir); ip[0] = 180.0/PI * atan2(d,d2) / v->horiz + 0.5 - v->hoff; - d = 1.0/sqrt(d*d + d2*d2); + d = d*d + d2*d2; + if (d <= FTINY*FTINY) + return(0); /* at pole */ + d = 1.0/sqrt(d); ip[1] = DOT(disp,v->vvec)*d/v->vn2 + 0.5 - v->voff; ip[2] = VLEN(disp); ip[2] *= (1.0 - v->vfore*d); - return; + goto gotall; case VT_ANG: /* angular fisheye */ ip[0] = 0.5 - v->hoff; ip[1] = 0.5 - v->voff; ip[2] = normalize(disp) - v->vfore; d = DOT(disp,v->vdir); if (d >= 1.0-FTINY) - return; + goto gotall; if (d <= -(1.0-FTINY)) { ip[0] += 180.0/v->horiz; - return; + goto gotall; } d = (180.0/PI)*acos(d) / sqrt(1.0 - d*d); ip[0] += DOT(disp,v->hvec)*d/v->horiz; ip[1] += DOT(disp,v->vvec)*d/v->vert; - return; + goto gotall; case VT_PLS: /* planispheric fisheye */ ip[0] = 0.5 - v->hoff; ip[1] = 0.5 - v->voff; ip[2] = normalize(disp) - v->vfore; d = DOT(disp,v->vdir); if (d >= 1.0-FTINY) - return; + goto gotall; if (d <= -(1.0-FTINY)) - return; /* really an error */ - d = sqrt(1.0 - d*d) / (1.0 + d); - ip[0] += DOT(disp,v->hvec)*d/sqrt(v->hn2); - ip[1] += DOT(disp,v->vvec)*d/sqrt(v->vn2); - return; + return(0); + ip[0] += DOT(disp,v->hvec)/((1. + d)*sqrt(v->hn2)); + ip[1] += DOT(disp,v->vvec)/((1. + d)*sqrt(v->vn2)); + goto gotall; } ip[0] = DOT(disp,v->hvec)/v->hn2 + 0.5 - v->hoff; ip[1] = DOT(disp,v->vvec)/v->vn2 + 0.5 - v->voff; +gotall: /* return -1 if behind */ + return(1 - 2*(ip[2] <= 0.0)); } @@ -326,7 +320,7 @@ int px, int py ) { - register int x, y; + int x, y; if (rp->rt & YMAJOR) { x = px; @@ -352,10 +346,11 @@ double lx, double ly ) { - register int x, y; + int x, y; - x = lx * rp->xr; - y = ly * rp->yr; + x = (int)(lx*rp->xr + .5 - (lx < 0.0)); + y = (int)(ly*rp->yr + .5 - (ly < 0.0)); + if (rp->rt & XDECR) x = rp->xr-1 - x; if (rp->rt & YDECR) @@ -498,7 +493,7 @@ VIEW *vp ) { static char vwstr[128]; - register char *cp = vwstr; + char *cp = vwstr; *cp = '\0'; if (vp->type != stdview.type) { @@ -557,8 +552,8 @@ char *s { static char *altname[]={NULL,VIEWSTR,"rpict","rview","rvu","rpiece","pinterp",NULL}; extern char *progname; - register char *cp; - register char **an; + char *cp; + char **an; /* add program name to list */ if (altname[0] == NULL) { for (cp = progname; *cp; cp++)