--- ray/src/rt/rtrace.c 1990/03/27 11:40:10 1.9 +++ ray/src/rt/rtrace.c 1993/06/18 10:14:42 2.15 @@ -1,4 +1,4 @@ -/* Copyright (c) 1986 Regents of the University of California */ +/* Copyright (c) 1992 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -20,25 +20,47 @@ static char SCCSid[] = "$SunId$ LBL"; * All values default to ascii representation of real * numbers. Binary representations can be selected * with '-ff' for float or '-fd' for double. By default, - * radiance is computed. The '-i' option indicates that + * radiance is computed. The '-i' or '-I' options indicate that * irradiance values are desired. */ #include "ray.h" +#include "octree.h" + #include "otypes.h" +#include "resolu.h" + +int dimlist[MAXDIM]; /* sampling dimensions */ +int ndims = 0; /* number of sampling dimensions */ +int samplendx = 0; /* index for this sample */ + +int imm_irrad = 0; /* compute immediate irradiance? */ + int inform = 'a'; /* input format */ int outform = 'a'; /* output format */ char *outvals = "v"; /* output specification */ +char *tralist[128]; /* list of modifers to trace (or no) */ +int traincl = -1; /* include == 1, exclude == 0 */ +#define MAXTSET 511 /* maximum number in trace set */ +OBJECT traset[MAXTSET+1]={0}; /* trace include/exclude set */ + int hresolu = 0; /* horizontal (scan) size */ int vresolu = 0; /* vertical resolution */ double dstrsrc = 0.0; /* square source distribution */ double shadthresh = .05; /* shadow threshold */ double shadcert = .5; /* shadow certainty */ +int directrelay = 1; /* number of source relays */ +int vspretest = 512; /* virtual source pretest density */ +int directvis = 1; /* sources visible? */ +double srcsizerat = .25; /* maximum ratio source size/dist. */ +double specthresh = .15; /* specular sampling threshold */ +double specjitter = 1.; /* specular sampling jitter */ + int maxdepth = 6; /* maximum recursion depth */ double minweight = 4e-3; /* minimum ray weight */ @@ -51,14 +73,18 @@ int ambounce = 0; /* ambient bounces */ char *amblist[128]; /* ambient include/exclude list */ int ambincl = -1; /* include == 1, exclude == 0 */ +extern OBJREC Lamb; /* a Lambertian surface */ + static RAY thisray; /* for our convenience */ -extern int oputo(), oputd(), oputv(), oputl(), - oputp(), oputn(), oputs(), oputw(), oputm(); +static int oputo(), oputd(), oputv(), oputl(), oputL(), + oputp(), oputn(), oputN(), oputs(), oputw(), oputm(); -static int (*ray_out[10])(), (*every_out[10])(); +static int ourtrace(), tabin(); +static int (*ray_out[16])(), (*every_out[16])(); +static int castonly = 0; -extern int puta(), putf(), putd(); +static int puta(), putf(), putd(); static int (*putreal)(); @@ -66,10 +92,28 @@ static int (*putreal)(); quit(code) /* quit program */ int code; { +#ifndef NIX + headclean(); /* delete header file */ + pfclean(); /* clean up persist files */ +#endif exit(code); } +char * +formstr(f) /* return format identifier */ +int f; +{ + switch (f) { + case 'a': return("ascii"); + case 'f': return("float"); + case 'd': return("double"); + case 'c': return(COLRFMT); + } + return("unknown"); +} + + rtrace(fname) /* trace rays from file */ char *fname; { @@ -84,13 +128,31 @@ char *fname; sprintf(errmsg, "cannot open input file \"%s\"", fname); error(SYSTEM, errmsg); } +#ifdef MSDOS + if (inform != 'a') + setmode(fileno(fp), O_BINARY); +#endif /* set up output */ - setoutput(outvals); + if (imm_irrad) + outvals = "v"; + else + setoutput(outvals); switch (outform) { case 'a': putreal = puta; break; case 'f': putreal = putf; break; case 'd': putreal = putd; break; + case 'c': + if (strcmp(outvals, "v")) + error(USER, "color format with value output only"); + break; + default: + error(CONSISTENCY, "botched output format"); } + if (hresolu > 0) { + if (vresolu > 0) + fprtresolu(hresolu, vresolu, stdout); + fflush(stdout); + } /* process file */ while (getvec(orig, inform, fp) == 0 && getvec(direc, inform, fp) == 0) { @@ -99,11 +161,12 @@ char *fname; fflush(stdout); continue; } + samplendx++; /* compute and print */ - if (outvals[0] == 'i') + if (imm_irrad) irrad(orig, direc); else - radiance(orig, direc); + traceray(orig, direc); /* flush if time */ if (--nextflush == 0) { fflush(stdout); @@ -114,24 +177,28 @@ char *fname; if (--vcount == 0) /* check for end */ break; } + fflush(stdout); if (vcount > 0) error(USER, "read error"); - fclose(fp); + if (fname != NULL) + fclose(fp); } setoutput(vs) /* set up output tables */ register char *vs; { - extern int ourtrace(), (*trace)(); + extern int (*trace)(); register int (**table)() = ray_out; + castonly = 1; while (*vs) switch (*vs++) { case 't': /* trace */ *table = NULL; table = every_out; trace = ourtrace; + castonly = 0; break; case 'o': /* origin */ *table++ = oputo; @@ -141,16 +208,25 @@ register char *vs; break; case 'v': /* value */ *table++ = oputv; + castonly = 0; break; - case 'l': /* length */ + case 'l': /* effective distance */ *table++ = oputl; + castonly = 0; break; + case 'L': /* single ray length */ + *table++ = oputL; + break; case 'p': /* point */ *table++ = oputp; break; - case 'n': /* normal */ + case 'n': /* perturbed normal */ *table++ = oputn; + castonly = 0; break; + case 'N': /* unperturbed normal */ + *table++ = oputN; + break; case 's': /* surface */ *table++ = oputs; break; @@ -165,7 +241,7 @@ register char *vs; } -radiance(org, dir) /* compute radiance value */ +traceray(org, dir) /* compute and print ray value(s) */ FVECT org, dir; { register int (**tp)(); @@ -173,7 +249,10 @@ FVECT org, dir; VCOPY(thisray.rorg, org); VCOPY(thisray.rdir, dir); rayorigin(&thisray, NULL, PRIMARY, 1.0); - rayvalue(&thisray); + if (castonly) + localhit(&thisray, &thescene) || sourcehit(&thisray); + else + rayvalue(&thisray); if (ray_out[0] == NULL) return; @@ -184,14 +263,9 @@ FVECT org, dir; } -irrad(org, dir) /* compute irradiance value */ +irrad(org, dir) /* compute immediate irradiance value */ FVECT org, dir; { - static double Lambfa[5] = {PI, PI, PI, 0.0, 0.0}; - static OBJREC Lamb = { - OVOID, MAT_PLASTIC, "Lambertian", - {0, 5, NULL, Lambfa}, NULL, -1, - }; register int i; for (i = 0; i < 3; i++) { @@ -218,12 +292,20 @@ register FVECT vec; int fmt; FILE *fp; { + extern char *fgetword(); static float vf[3]; + static double vd[3]; + char buf[32]; + register int i; switch (fmt) { case 'a': /* ascii */ - if (fscanf(fp, "%lf %lf %lf", vec, vec+1, vec+2) != 3) - return(-1); + for (i = 0; i < 3; i++) { + if (fgetword(buf, sizeof(buf), fp) == NULL || + !isflt(buf)) + return(-1); + vec[i] = atof(buf); + } break; case 'f': /* binary float */ if (fread((char *)vf, sizeof(float), 3, fp) != 3) @@ -231,14 +313,39 @@ FILE *fp; vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2]; break; case 'd': /* binary double */ - if (fread((char *)vec, sizeof(double), 3, fp) != 3) + if (fread((char *)vd, sizeof(double), 3, fp) != 3) return(-1); + vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2]; break; + default: + error(CONSISTENCY, "botched input format"); } return(0); } +tranotify(obj) /* record new modifier */ +OBJECT obj; +{ + static int hitlimit = 0; + register OBJREC *o = objptr(obj); + register char **tralp; + + if (hitlimit || !ismodifier(o->otype)) + return; + for (tralp = tralist; *tralp != NULL; tralp++) + if (!strcmp(o->oname, *tralp)) { + if (traset[0] >= MAXTSET) { + error(WARNING, "too many modifiers in trace list"); + hitlimit++; + return; /* should this be fatal? */ + } + insertelem(traset, obj); + return; + } +} + + static ourtrace(r) /* print ray values */ RAY *r; @@ -247,6 +354,10 @@ RAY *r; if (every_out[0] == NULL) return; + if (traincl == 1 && r->ro == NULL) + return; + if (traincl != -1 && traincl != inset(traset, r->ro->omod)) + return; tabin(r); for (tp = every_out; *tp != NULL; tp++) (**tp)(r); @@ -289,6 +400,15 @@ static oputv(r) /* print value */ register RAY *r; { + COLR cout; + + if (outform == 'c') { + setcolr(cout, colval(r->rcol,RED), + colval(r->rcol,GRN), + colval(r->rcol,BLU)); + fwrite((char *)cout, sizeof(cout), 1, stdout); + return; + } (*putreal)(colval(r->rcol,RED)); (*putreal)(colval(r->rcol,GRN)); (*putreal)(colval(r->rcol,BLU)); @@ -296,7 +416,7 @@ register RAY *r; static -oputl(r) /* print length */ +oputl(r) /* print effective distance */ register RAY *r; { (*putreal)(r->rt); @@ -304,6 +424,14 @@ register RAY *r; static +oputL(r) /* print single ray length */ +register RAY *r; +{ + (*putreal)(r->rot); +} + + +static oputp(r) /* print point */ register RAY *r; { @@ -320,7 +448,7 @@ register RAY *r; static -oputn(r) /* print normal */ +oputN(r) /* print unperturbed normal */ register RAY *r; { if (r->rot < FHUGE) { @@ -332,6 +460,25 @@ register RAY *r; (*putreal)(0.0); (*putreal)(0.0); } +} + + +static +oputn(r) /* print perturbed normal */ +RAY *r; +{ + FVECT pnorm; + + if (r->rot >= FHUGE) { + (*putreal)(0.0); + (*putreal)(0.0); + (*putreal)(0.0); + return; + } + raynormal(pnorm, r); + (*putreal)(pnorm[0]); + (*putreal)(pnorm[1]); + (*putreal)(pnorm[2]); }