void lastview( /* return to a previous view */ char *s ) { char buf[128]; char *fname; int success; VIEW nv; /* get parameters from a file */ if (nextword(buf, sizeof(buf), s) != NULL) { nv = stdview; if ((fname = getpath(buf, "", R_OK)) == NULL || (success = viewfile(fname, &nv, NULL)) == -1) { sprintf(errmsg, "cannot open \"%s\"", buf); error(COMMAND, errmsg); return; } if (!success) error(COMMAND, "wrong file format"); else newview(&nv); return; } if (oldview.type == 0) { /* no old view! */ error(COMMAND, "no previous view"); return; } nv = ourview; ourview = oldview; oldview = nv; newimage(NULL); }
void getaim( /* aim camera */ char *s ) { VIEW nv = ourview; double zfact; if (getinterest(s, 1, nv.vdir, &zfact) < 0) return; zoomview(&nv, zfact); newview(&nv); }
void getorigin( /* origin viewpoint */ char *s ) { VIEW nv = ourview; double d; /* get new view origin */ if (sscanf(s, "%lf %lf", &d, &d) == 1) { /* just moving some distance */ VSUM(nv.vp, nv.vp, nv.vdir, d); } else if (!sscanvec(s, nv.vp)) { int x, y; /* need to pick origin */ RAY thisray; if (dev->getcur == NULL) return; (*dev->comout)("Pick point on surface for new origin\n"); if ((*dev->getcur)(&x, &y) == ABORT) return; if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) { error(COMMAND, "not on image"); return; } rayorigin(&thisray, PRIMARY, NULL, NULL); if (!localhit(&thisray, &thescene)) { error(COMMAND, "not a local object"); return; } if (thisray.rod < 0.0) /* don't look through other side */ flipsurface(&thisray); VSUM(nv.vp, thisray.rop, thisray.ron, 20.0*FTINY); VCOPY(nv.vdir, thisray.ron); } else if (!sscanvec(sskip2(s,3), nv.vdir) || normalize(nv.vdir) == 0.0) VCOPY(nv.vdir, ourview.vdir); d = DOT(nv.vdir, nv.vup); /* need different up vector? */ if (d*d >= 1.-2.*FTINY) { int i; nv.vup[0] = nv.vup[1] = nv.vup[2] = 0.0; for (i = 3; i--; ) if (nv.vdir[i]*nv.vdir[i] < 0.34) break; nv.vup[i] = 1.; } newview(&nv); }
void getrotate( /* rotate camera */ char *s ) { VIEW nv = ourview; double angle, elev, zfact; elev = 0.0; zfact = 1.0; if (sscanf(s, "%lf %lf %lf", &angle, &elev, &zfact) < 1) { error(COMMAND, "missing angle"); return; } spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.)); if (elev != 0.0) geodesic(nv.vdir, nv.vdir, nv.vup, elev*(PI/180.), GEOD_RAD); zoomview(&nv, zfact); newview(&nv); }
void loadview( /* load view from rad file */ char *s ) { char buf[512]; char *fname; FILE *fp; VIEW nv; strcpy(buf, "rad -n -s -V -v "); if (sscanf(s, "%s", buf+strlen(buf)) == 1) s = sskip(s); else strcat(buf, "1"); if (nextword(rifname, sizeof(rifname), s) == NULL && !rifname[0]) { error(COMMAND, "no previous rad file"); return; } if ((fname = getpath(rifname, "", R_OK)) == NULL) { sprintf(errmsg, "cannot access \"%s\"", rifname); error(COMMAND, errmsg); return; } sprintf(buf+strlen(buf), " %s", fname); if ((fp = popen(buf, "r")) == NULL) { error(COMMAND, "cannot run rad"); return; } buf[0] = '\0'; fgets(buf, sizeof(buf), fp); pclose(fp); nv = stdview; if (!sscanview(&nv, buf)) { error(COMMAND, "rad error -- no such view?"); return; } newview(&nv); }
void moveview( /* move viewpoint */ double angle, double elev, double mag, FVECT vc ) { double d; VIEW nv = ourview; int i; spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.)); if (elev != 0.0) geodesic(nv.vdir, nv.vdir, nv.vup, elev*(-PI/180.), GEOD_RAD); if (nv.type == VT_PAR) { nv.horiz /= mag; nv.vert /= mag; d = 0.0; /* don't move closer */ for (i = 0; i < 3; i++) d += (vc[i] - ourview.vp[i])*ourview.vdir[i]; } else { d = sqrt(dist2(ourview.vp, vc)) / mag; if (nv.vfore > FTINY) { nv.vfore += d - d*mag; if (nv.vfore < 0.0) nv.vfore = 0.0; } if (nv.vaft > FTINY) { nv.vaft += d - d*mag; if (nv.vaft <= nv.vfore) nv.vaft = 0.0; } nv.vdist /= mag; } for (i = 0; i < 3; i++) nv.vp[i] = vc[i] - d*nv.vdir[i]; newview(&nv); }
void getview( /* get/show/save view parameters */ char *s ) { FILE *fp; char buf[128]; char *fname; int change = 0; VIEW nv = ourview; while (isspace(*s)) s++; if (*s == '-') { /* command line parameters */ if (sscanview(&nv, s)) newview(&nv); else error(COMMAND, "bad view option(s)"); return; } if (nextword(buf, sizeof(buf), s) != NULL) { /* write to a file */ if ((fname = getpath(buf, NULL, 0)) == NULL || (fp = fopen(fname, "a")) == NULL) { sprintf(errmsg, "cannot open \"%s\"", buf); error(COMMAND, errmsg); return; } fputs(progname, fp); fprintview(&ourview, fp); fputs(sskip(s), fp); putc('\n', fp); fclose(fp); return; } sprintf(buf, "view type (%c): ", ourview.type); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (buf[0] == CTRL('C')) return; if (buf[0] && buf[0] != ourview.type) { nv.type = buf[0]; change++; } sprintf(buf, "view point (%.6g %.6g %.6g): ", ourview.vp[0], ourview.vp[1], ourview.vp[2]); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (buf[0] == CTRL('C')) return; if (sscanvec(buf, nv.vp)) change++; sprintf(buf, "view direction (%.6g %.6g %.6g): ", ourview.vdir[0]*ourview.vdist, ourview.vdir[1]*ourview.vdist, ourview.vdir[2]*ourview.vdist); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (buf[0] == CTRL('C')) return; if (sscanvec(buf, nv.vdir)) { nv.vdist = 1.; change++; } sprintf(buf, "view up (%.6g %.6g %.6g): ", ourview.vup[0], ourview.vup[1], ourview.vup[2]); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (buf[0] == CTRL('C')) return; if (sscanvec(buf, nv.vup)) change++; sprintf(buf, "view horiz and vert size (%.6g %.6g): ", ourview.horiz, ourview.vert); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (buf[0] == CTRL('C')) return; if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2) change++; sprintf(buf, "fore and aft clipping plane (%.6g %.6g): ", ourview.vfore, ourview.vaft); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (buf[0] == CTRL('C')) return; if (sscanf(buf, "%lf %lf", &nv.vfore, &nv.vaft) == 2) change++; sprintf(buf, "view shift and lift (%.6g %.6g): ", ourview.hoff, ourview.voff); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (buf[0] == CTRL('C')) return; if (sscanf(buf, "%lf %lf", &nv.hoff, &nv.voff) == 2) change++; if (change) newview(&nv); }