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 getpivot( /* pivot viewpoint */ char *s ) { FVECT vc; double angle, elev, mag; elev = 0.0; if (sscanf(s, "%lf %lf", &angle, &elev) < 1) { error(COMMAND, "missing angle"); return; } if (getinterest(sskip2(s,2), 0, vc, &mag) < 0) return; moveview(angle, elev, mag, vc); }
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); }
static void runrad( /* run rad and load variables */ int ac, char **av ) { static char optfile[] = TEMPLATE; int nvn = 0, nvv = 0; FILE *fp; register char *cp; char radcomm[256], buf[128], nam[32]; /* set rad commmand */ strcpy(radcomm, "rad -w -v 0 "); /* look out below! */ cp = radcomm + 19; if (silent) { strcpy(cp, "-s "); cp += 3; } while (ac--) { strcpy(cp, *av++); while (*cp) cp++; *cp++ = ' '; } strcpy(cp, "OPTFILE="); /* create temporary options file */ strcpy(cp+8, mktemp(optfile)); if (system(radcomm)) /* update octree */ error(USER, "error executing rad command"); /* replace "-v 0" with "-n -e -s -V" */ strcpy(radcomm+7, "-n -e -s -V"); radcomm[18] = ' '; if ((fp = popen(radcomm, "r")) == NULL) error(SYSTEM, "cannot start rad command"); buf[0] = '\0'; /* read variables alphabetically */ /* get exposure */ if ((cp = scan4var(buf, sizeof(buf), "EXPOSURE", fp)) != NULL) { expval = atof(cp); if ((*cp == '-') | (*cp == '+')) expval = pow(2., expval); expval *= 0.5; /* compensate for local shading */ } /* look for eye separation */ if ((cp = scan4var(buf, sizeof(buf), "EYESEP", fp)) != NULL) eyedist = atof(cp); /* look for materials */ while ((cp = scan4var(buf, sizeof(buf), "materials", fp)) != NULL) { nscenef += wordstring(scene+nscenef, cp); buf[0] = '\0'; } /* look for octree */ if ((cp = scan4var(buf, sizeof(buf), "OCTREE", fp)) != NULL) octree = savqstr(cp); /* look for scene files */ while ((cp = scan4var(buf, sizeof(buf), "scene", fp)) != NULL) { nscenef += wordstring(scene+nscenef, cp); buf[0] = '\0'; } /* load view names */ while ((cp = scan4var(buf, sizeof(buf), "view", fp)) != NULL) { if (nvn >= MAXVIEW) error(INTERNAL, "too many views in rad file"); vwl[nvn++].nam = *cp == '-' ? (char *)NULL : savqstr(atos(nam, sizeof(nam), cp)); buf[0] = '\0'; } /* load actual views */ do if (isview(buf)) { vwl[nvv].v = (VIEW *)bmalloc(sizeof(VIEW)); *(vwl[nvv].v) = stdview; sscanview(vwl[nvv].v, buf); if ((cp = setview(vwl[nvv++].v)) != NULL) { fprintf(stderr, "%s: bad view %d - %s\n", progname, nvv, cp); quit(1); } } while (fgets(buf, sizeof(buf), fp) != NULL); if (nvv != nvn) error(INTERNAL, "view miscount in runrad"); pclose(fp); /* open options file */ if ((fp = fopen(optfile, "r")) == NULL) error(SYSTEM, "cannot open options file"); /* get relevant options */ while (fgets(buf, sizeof(buf), fp) != NULL) if (!strncmp(buf, "-av ", 4)) setcolor(ambval, atof(buf+4), atof(sskip2(buf+4,1)), atof(sskip2(buf+4,2))); else if (backvis && !strncmp(buf, "-bv", 3) && (!buf[3] || strchr("0-FfNn \n",buf[3])!=NULL)) backvis = 0; fclose(fp); unlink(optfile); /* delete options file */ }