--- ray/src/rt/rtrace.c 2003/02/22 02:07:29 2.27
+++ ray/src/rt/rtrace.c 2005/06/21 15:06:50 2.48
@@ -1,66 +1,11 @@
#ifndef lint
-static const char RCSid[] = "$Id: rtrace.c,v 2.27 2003/02/22 02:07:29 greg Exp $";
+static const char RCSid[] = "$Id: rtrace.c,v 2.48 2005/06/21 15:06:50 greg Exp $";
#endif
/*
* rtrace.c - program and variables for individual ray tracing.
*/
-/* ====================================================================
- * The Radiance Software License, Version 1.0
- *
- * Copyright (c) 1990 - 2002 The Regents of the University of California,
- * through Lawrence Berkeley National Laboratory. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes Radiance software
- * (http://radsite.lbl.gov/)
- * developed by the Lawrence Berkeley National Laboratory
- * (http://www.lbl.gov/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
- * and "The Regents of the University of California" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact radiance@radsite.lbl.gov.
- *
- * 5. Products derived from this software may not be called "Radiance",
- * nor may "Radiance" appear in their name, without prior written
- * permission of Lawrence Berkeley National Laboratory.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of Lawrence Berkeley National Laboratory. For more
- * information on Lawrence Berkeley National Laboratory, please see
- * .
- */
+#include "copyright.h"
/*
* Input is in the form:
@@ -76,10 +21,13 @@ static const char RCSid[] = "$Id: rtrace.c,v 2.27 2003
* irradiance values are desired.
*/
-#include "ray.h"
+#include
+#include "platform.h"
+#include "ray.h"
+#include "ambient.h"
+#include "source.h"
#include "otypes.h"
-
#include "resolu.h"
CUBE thescene; /* our scene */
@@ -98,21 +46,23 @@ char *outvals = "v"; /* output specification */
int do_irrad = 0; /* compute irradiance? */
+int rand_samp = 0; /* pure Monte Carlo sampling? */
+
void (*trace)() = NULL; /* trace call */
-extern void ambnotify(), tranotify();
-void (*addobjnotify[])() = {ambnotify, tranotify, NULL};
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 */
+#ifndef MAXTSET
+#define MAXTSET 1024 /* maximum number in trace set */
+#endif
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 */
+double shadthresh = .03; /* shadow threshold */
+double shadcert = .75; /* shadow certainty */
int directrelay = 2; /* number of source relays */
int vspretest = 512; /* virtual source pretest density */
int directvis = 1; /* sources visible? */
@@ -128,42 +78,53 @@ double specjitter = 1.; /* specular sampling jitter
int backvis = 1; /* back face visibility */
-int maxdepth = 6; /* maximum recursion depth */
-double minweight = 4e-3; /* minimum ray weight */
+int maxdepth = -10; /* maximum recursion depth */
+double minweight = 2e-3; /* minimum ray weight */
char *ambfile = NULL; /* ambient file name */
COLOR ambval = BLKCOLOR; /* ambient value */
int ambvwt = 0; /* initial weight for ambient value */
-double ambacc = 0.2; /* ambient accuracy */
-int ambres = 128; /* ambient resolution */
-int ambdiv = 512; /* ambient divisions */
-int ambssamp = 0; /* ambient super-samples */
+double ambacc = 0.15; /* ambient accuracy */
+int ambres = 256; /* ambient resolution */
+int ambdiv = 1024; /* ambient divisions */
+int ambssamp = 512; /* ambient super-samples */
int ambounce = 0; /* ambient bounces */
-char *amblist[128]; /* ambient include/exclude list */
+char *amblist[AMBLLEN]; /* ambient include/exclude list */
int ambincl = -1; /* include == 1, exclude == 0 */
+static int castonly = 0;
static RAY thisray; /* for our convenience */
-static void oputo(), oputd(), oputv(), oputl(), oputL(),
- oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
+typedef void putf_t(double v);
+static putf_t puta, putd, putf;
-static void ourtrace(), tabin();
-static void (*ray_out[16])(), (*every_out[16])();
-static int castonly = 0;
+typedef void oputf_t(RAY *r);
+static oputf_t oputo, oputd, oputv, oputl, oputL, oputc, oputp,
+ oputn, oputN, oputs, oputw, oputW, oputm, oputM, oputtilde;
-static void puta(), putf(), putd();
+static void setoutput(char *vs);
+static void tranotify(OBJECT obj);
+static void bogusray(void);
+static void rad(FVECT org, FVECT dir, double dmax);
+static void irrad(FVECT org, FVECT dir);
+static void printvals(RAY *r);
+static int getvec(FVECT vec, int fmt, FILE *fp);
+static void tabin(RAY *r);
+static void ourtrace(RAY *r);
-static void (*putreal)();
+static oputf_t *ray_out[16], *every_out[16];
+static putf_t *putreal;
-void bogusray(), rad(), irrad(), printvals();
+void (*addobjnotify[])() = {ambnotify, tranotify, NULL};
void
-quit(code) /* quit program */
-int code;
+quit( /* quit program */
+ int code
+)
{
-#ifndef NIX
+#ifndef NON_POSIX /* XXX we don't clean up elsewhere? */
headclean(); /* delete header file */
pfclean(); /* clean up persist files */
#endif
@@ -171,9 +132,10 @@ int code;
}
-char *
-formstr(f) /* return format identifier */
-int f;
+extern char *
+formstr( /* return format identifier */
+ int f
+)
{
switch (f) {
case 'a': return("ascii");
@@ -185,11 +147,13 @@ int f;
}
-void
-rtrace(fname) /* trace rays from file */
-char *fname;
+extern void
+rtrace( /* trace rays from file */
+ char *fname
+)
{
- long vcount = hresolu>1 ? hresolu*vresolu : vresolu;
+ unsigned long vcount = (hresolu > 1) ? (unsigned long)hresolu*vresolu
+ : vresolu;
long nextflush = hresolu;
FILE *fp;
double d;
@@ -201,10 +165,8 @@ 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_FILE_BINARY(fp);
/* set up output */
setoutput(outvals);
switch (outform) {
@@ -230,46 +192,62 @@ char *fname;
d = normalize(direc);
if (d == 0.0) { /* zero ==> flush */
bogusray();
- if (--nextflush <= 0 || vcount <= 0) {
+ if (--nextflush <= 0 || !vcount) {
fflush(stdout);
nextflush = hresolu;
}
} else {
- samplendx++;
+ samplendx = rand_samp ? random() : samplendx+1;
/* compute and print */
if (imm_irrad)
irrad(orig, direc);
else
rad(orig, direc, lim_dist ? d : 0.0);
/* flush if time */
- if (--nextflush == 0) {
+ if (!--nextflush) {
fflush(stdout);
nextflush = hresolu;
}
}
if (ferror(stdout))
error(SYSTEM, "write error");
- if (--vcount == 0) /* check for end */
+ if (vcount && !--vcount) /* check for end */
break;
}
fflush(stdout);
- if (vcount > 0)
- error(USER, "read error");
+ if (vcount)
+ error(USER, "unexpected EOF on input");
if (fname != NULL)
fclose(fp);
}
-setoutput(vs) /* set up output tables */
-register char *vs;
+static void
+trace_sources(void) /* trace rays to light sources, also */
{
- extern void (*trace)();
- register void (**table)() = ray_out;
+ int sn;
+
+ for (sn = 0; sn < nsources; sn++)
+ source[sn].sflags |= SFOLLOW;
+}
+
+static void
+setoutput( /* set up output tables */
+ register char *vs
+)
+{
+ register oputf_t **table = ray_out;
+
castonly = 1;
while (*vs)
switch (*vs++) {
+ case 'T': /* trace sources */
+ if (!*vs) break;
+ trace_sources();
+ /* fall through */
case 't': /* trace */
+ if (!*vs) break;
*table = NULL;
table = every_out;
trace = ourtrace;
@@ -289,6 +267,9 @@ register char *vs;
*table++ = oputl;
castonly = 0;
break;
+ case 'c': /* local coordinates */
+ *table++ = oputc;
+ break;
case 'L': /* single ray length */
*table++ = oputL;
break;
@@ -308,49 +289,67 @@ register char *vs;
case 'w': /* weight */
*table++ = oputw;
break;
+ case 'W': /* coefficient */
+ *table++ = oputW;
+ if (ambounce > 0 && (ambacc > FTINY || ambssamp > 0))
+ error(WARNING,
+ "-otW accuracy depends on -aa 0 -as 0");
+ break;
case 'm': /* modifier */
*table++ = oputm;
break;
+ case 'M': /* material */
+ *table++ = oputM;
+ break;
+ case '~': /* tilde */
+ *table++ = oputtilde;
+ break;
}
*table = NULL;
}
-void
-bogusray() /* print out empty record */
+static void
+bogusray(void) /* print out empty record */
{
thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
- rayorigin(&thisray, NULL, PRIMARY, 1.0);
+ thisray.rmax = 0.0;
+ rayorigin(&thisray, PRIMARY, NULL, NULL);
printvals(&thisray);
}
-void
-rad(org, dir, dmax) /* compute and print ray value(s) */
-FVECT org, dir;
-double dmax;
+static void
+rad( /* compute and print ray value(s) */
+ FVECT org,
+ FVECT dir,
+ double dmax
+)
{
VCOPY(thisray.rorg, org);
VCOPY(thisray.rdir, dir);
thisray.rmax = dmax;
- rayorigin(&thisray, NULL, PRIMARY, 1.0);
+ rayorigin(&thisray, PRIMARY, NULL, NULL);
if (castonly) {
- if (!localhit(&thisray, &thescene))
+ if (!localhit(&thisray, &thescene)) {
if (thisray.ro == &Aftplane) { /* clipped */
thisray.ro = NULL;
thisray.rot = FHUGE;
} else
sourcehit(&thisray);
+ }
} else
rayvalue(&thisray);
printvals(&thisray);
}
-void
-irrad(org, dir) /* compute immediate irradiance value */
-FVECT org, dir;
+static void
+irrad( /* compute immediate irradiance value */
+ FVECT org,
+ FVECT dir
+)
{
register int i;
@@ -358,7 +357,8 @@ FVECT org, dir;
thisray.rorg[i] = org[i] + dir[i];
thisray.rdir[i] = -dir[i];
}
- rayorigin(&thisray, NULL, PRIMARY, 1.0);
+ thisray.rmax = 0.0;
+ rayorigin(&thisray, PRIMARY, NULL, NULL);
/* pretend we hit surface */
thisray.rot = 1.0-1e-4;
thisray.rod = 1.0;
@@ -371,11 +371,12 @@ FVECT org, dir;
}
-void
-printvals(r) /* print requested ray values */
-RAY *r;
+static void
+printvals( /* print requested ray values */
+ RAY *r
+)
{
- register void (**tp)();
+ register oputf_t **tp;
if (ray_out[0] == NULL)
return;
@@ -386,11 +387,12 @@ RAY *r;
}
-int
-getvec(vec, fmt, fp) /* get a vector from fp */
-register FVECT vec;
-int fmt;
-FILE *fp;
+static int
+getvec( /* get a vector from fp */
+ register FVECT vec,
+ int fmt,
+ FILE *fp
+)
{
static float vf[3];
static double vd[3];
@@ -423,9 +425,10 @@ FILE *fp;
}
-void
-tranotify(obj) /* record new modifier */
-OBJECT obj;
+static void
+tranotify( /* record new modifier */
+ OBJECT obj
+)
{
static int hitlimit = 0;
register OBJREC *o = objptr(obj);
@@ -452,10 +455,11 @@ OBJECT obj;
static void
-ourtrace(r) /* print ray values */
-RAY *r;
+ourtrace( /* print ray values */
+ RAY *r
+)
{
- register void (**tp)();
+ register oputf_t **tp;
if (every_out[0] == NULL)
return;
@@ -467,15 +471,17 @@ RAY *r;
tabin(r);
for (tp = every_out; *tp != NULL; tp++)
(**tp)(r);
- putchar('\n');
+ if (outform == 'a')
+ putchar('\n');
}
static void
-tabin(r) /* tab in appropriate amount */
-RAY *r;
+tabin( /* tab in appropriate amount */
+ RAY *r
+)
{
- register RAY *rp;
+ const RAY *rp;
for (rp = r->parent; rp != NULL; rp = rp->parent)
putchar('\t');
@@ -483,8 +489,9 @@ RAY *r;
static void
-oputo(r) /* print origin */
-register RAY *r;
+oputo( /* print origin */
+ RAY *r
+)
{
(*putreal)(r->rorg[0]);
(*putreal)(r->rorg[1]);
@@ -493,8 +500,9 @@ register RAY *r;
static void
-oputd(r) /* print direction */
-register RAY *r;
+oputd( /* print direction */
+ RAY *r
+)
{
(*putreal)(r->rdir[0]);
(*putreal)(r->rdir[1]);
@@ -503,12 +511,12 @@ register RAY *r;
static void
-oputv(r) /* print value */
-register RAY *r;
+oputv( /* print value */
+ RAY *r
+)
{
- COLR cout;
-
if (outform == 'c') {
+ COLR cout;
setcolr(cout, colval(r->rcol,RED),
colval(r->rcol,GRN),
colval(r->rcol,BLU));
@@ -522,25 +530,38 @@ register RAY *r;
static void
-oputl(r) /* print effective distance */
-register RAY *r;
+oputl( /* print effective distance */
+ RAY *r
+)
{
(*putreal)(r->rt);
}
static void
-oputL(r) /* print single ray length */
-register RAY *r;
+oputL( /* print single ray length */
+ RAY *r
+)
{
(*putreal)(r->rot);
}
static void
-oputp(r) /* print point */
-register RAY *r;
+oputc( /* print local coordinates */
+ RAY *r
+)
{
+ (*putreal)(r->uv[0]);
+ (*putreal)(r->uv[1]);
+}
+
+
+static void
+oputp( /* print point */
+ RAY *r
+)
+{
if (r->rot < FHUGE) {
(*putreal)(r->rop[0]);
(*putreal)(r->rop[1]);
@@ -554,8 +575,9 @@ register RAY *r;
static void
-oputN(r) /* print unperturbed normal */
-register RAY *r;
+oputN( /* print unperturbed normal */
+ RAY *r
+)
{
if (r->rot < FHUGE) {
(*putreal)(r->ron[0]);
@@ -570,8 +592,9 @@ register RAY *r;
static void
-oputn(r) /* print perturbed normal */
-RAY *r;
+oputn( /* print perturbed normal */
+ RAY *r
+)
{
FVECT pnorm;
@@ -589,8 +612,9 @@ RAY *r;
static void
-oputs(r) /* print name */
-register RAY *r;
+oputs( /* print name */
+ RAY *r
+)
{
if (r->ro != NULL)
fputs(r->ro->oname, stdout);
@@ -601,17 +625,33 @@ register RAY *r;
static void
-oputw(r) /* print weight */
-register RAY *r;
+oputw( /* print weight */
+ RAY *r
+)
{
(*putreal)(r->rweight);
}
static void
-oputm(r) /* print modifier */
-register RAY *r;
+oputW( /* print contribution */
+ RAY *r
+)
{
+ double contr[3];
+
+ raycontrib(contr, r, PRIMARY);
+ (*putreal)(contr[RED]);
+ (*putreal)(contr[GRN]);
+ (*putreal)(contr[BLU]);
+}
+
+
+static void
+oputm( /* print modifier */
+ RAY *r
+)
+{
if (r->ro != NULL)
if (r->ro->omod != OVOID)
fputs(objptr(r->ro->omod)->oname, stdout);
@@ -624,8 +664,36 @@ register RAY *r;
static void
-puta(v) /* print ascii value */
-double v;
+oputM( /* print material */
+ RAY *r
+)
+{
+ OBJREC *mat;
+
+ if (r->ro != NULL) {
+ if ((mat = findmaterial(r->ro)) != NULL)
+ fputs(mat->oname, stdout);
+ else
+ fputs(VOIDID, stdout);
+ } else
+ putchar('*');
+ putchar('\t');
+}
+
+
+static void
+oputtilde( /* output tilde (spacer) */
+ RAY *r
+)
+{
+ fputs("~\t", stdout);
+}
+
+
+static void
+puta( /* print ascii value */
+ double v
+)
{
printf("%e\t", v);
}