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); }
int getinterest( /* get area of interest */ char *s, int direc, FVECT vec, double *mp ) { int x, y; RAY thisray; int i; if (sscanf(s, "%lf", mp) != 1) *mp = 1.0; else if (*mp < -FTINY) /* negative zoom is reduction */ *mp = -1.0 / *mp; else if (*mp <= FTINY) { /* too small */ error(COMMAND, "illegal magnification"); return(-1); } if (!sscanvec(sskip(s), vec)) { if (dev->getcur == NULL) return(-1); (*dev->comout)("Pick view center\n"); if ((*dev->getcur)(&x, &y) == ABORT) return(-1); if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) { error(COMMAND, "not on image"); return(-1); } if (!direc || ourview.type == VT_PAR) { rayorigin(&thisray, PRIMARY, NULL, NULL); if (!localhit(&thisray, &thescene)) { error(COMMAND, "not a local object"); return(-1); } } if (direc) if (ourview.type == VT_PAR) for (i = 0; i < 3; i++) vec[i] = thisray.rop[i] - ourview.vp[i]; else VCOPY(vec, thisray.rdir); else VCOPY(vec, thisray.rop); } else if (direc) { for (i = 0; i < 3; i++) vec[i] -= ourview.vp[i]; if (normalize(vec) == 0.0) { error(COMMAND, "point at view origin"); return(-1); } } return(0); }
static int strtoipt( /* convert string x y z to image point */ int ipt[2], char *str ) { FVECT im_pt, pt; if (!sscanvec(str, pt)) return(-1); if (DOT(pt,pt) <= FTINY) /* origin is really infinity */ ipt[0] = ipt[1] = -1; /* null vector */ else { viewloc(im_pt, &ourview, pt); loc2pix(ipt, &ourres, im_pt[0], im_pt[1]); } return(0); }
void traceray( /* trace a single ray */ char *s ) { RAY thisray; char buf[512]; thisray.rmax = 0.0; if (!sscanvec(s, thisray.rorg) || !sscanvec(sskip2(s,3), thisray.rdir)) { int x, y; if (dev->getcur == NULL) return; (*dev->comout)("Pick ray\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; } } else if (normalize(thisray.rdir) == 0.0) { error(COMMAND, "zero ray direction"); return; } ray_trace(&thisray); if (thisray.ro == NULL) (*dev->comout)("ray hit nothing"); else { OBJREC *mat = NULL; OBJREC *mod = NULL; char matspec[256]; OBJREC *ino; matspec[0] = '\0'; if (thisray.ro->omod != OVOID) { mod = objptr(thisray.ro->omod); mat = findmaterial(mod); } if (thisray.rod < 0.0) strcpy(matspec, "back of "); if (mod != NULL) { strcat(matspec, mod->oname); if (mat != mod && mat != NULL) sprintf(matspec+strlen(matspec), " (%s)", mat->oname); } else strcat(matspec, VOIDID); sprintf(buf, "ray hit %s %s \"%s\"", matspec, ofun[thisray.ro->otype].funame, thisray.ro->oname); if ((ino = objptr(thisray.robj)) != thisray.ro) sprintf(buf+strlen(buf), " in %s \"%s\"", ofun[ino->otype].funame, ino->oname); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (thisray.rot >= FHUGE) (*dev->comout)("at infinity"); else { sprintf(buf, "at (%.6g %.6g %.6g) (%.6g)", thisray.rop[0], thisray.rop[1], thisray.rop[2], raydistance(&thisray)); (*dev->comout)(buf); } (*dev->comin)(buf, NULL); sprintf(buf, "value (%.5g %.5g %.5g) (%.3gL)", colval(thisray.rcol,RED), colval(thisray.rcol,GRN), colval(thisray.rcol,BLU), luminance(thisray.rcol)); (*dev->comout)(buf); } (*dev->comin)(buf, NULL); }
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); }