--- ray/src/rt/rpict.c 2003/10/27 10:30:18 2.65 +++ ray/src/rt/rpict.c 2008/03/11 02:21:47 2.78 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id"; +static const char RCSid[] = "$Id: rpict.c,v 2.78 2008/03/11 02:21:47 greg Exp $"; #endif /* * rpict.c - routines and variables for picture generation. @@ -7,9 +7,6 @@ static const char RCSid[] = "$Id"; #include "copyright.h" -#include "platform.h" -#include "ray.h" - #include #ifndef NON_POSIX @@ -25,6 +22,10 @@ static const char RCSid[] = "$Id"; #include #include +#include "platform.h" +#include "ray.h" +#include "paths.h" +#include "ambient.h" #include "view.h" #include "random.h" #include "paths.h" @@ -46,7 +47,7 @@ int dimlist[MAXDIM]; /* sampling dimensions */ int ndims = 0; /* number of sampling dimensions */ int samplendx; /* sample index number */ -extern void ambnotify(); +//extern void ambnotify(); void (*addobjnotify[])() = {ambnotify, NULL}; VIEW ourview = STDVIEW; /* view parameters */ @@ -60,10 +61,14 @@ double dstrpix = 0.67; /* square pixel distribution double mblur = 0.; /* motion blur parameter */ +double dblur = 0.; /* depth-of-field blur parameter */ + void (*trace)() = NULL; /* trace call */ int do_irrad = 0; /* compute irradiance? */ +int rand_samp = 0; /* pure Monte Carlo sampling? */ + double dstrsrc = 0.0; /* square source distribution */ double shadthresh = .05; /* shadow threshold */ double shadcert = .5; /* shadow certainty */ @@ -88,12 +93,12 @@ double minweight = 4e-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.15; /* ambient accuracy */ +double ambacc = 0.2; /* ambient accuracy */ int ambres = 64; /* ambient resolution */ int ambdiv = 512; /* ambient divisions */ int ambssamp = 128; /* 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 */ int ralrm = 0; /* seconds between reports */ @@ -110,12 +115,25 @@ int hres, vres; /* resolution for this frame */ static VIEW lastview; /* the previous view input */ -extern char *mktemp(); /* XXX should be in stdlib.h or unistd.h */ +//extern char *mktemp(); /* XXX should be in stdlib.h or unistd.h */ -void report(); +//double pixvalue(); -double pixvalue(); +static void report(int); +static int nextview(FILE *fp); +static void render(char *zfile, char *oldfile); +static void fillscanline(COLOR *scanline, float *zline, char *sd, int xres, + int y, int xstep); +static void fillscanbar(COLOR *scanbar[], float *zbar[], int xres, + int y, int ysize); +static int fillsample(COLOR *colline, float *zline, int x, int y, + int xlen, int ylen, int b); +static double pixvalue(COLOR col, int x, int y); +static int salvage(char *oldfile); +static int pixnumber(int x, int y, int xres, int yres); + + #ifdef RHAS_STAT #include #include @@ -137,7 +155,7 @@ quit(code) /* quit program */ int code; { if (code) /* report status */ - report(); + report(0); #ifndef NON_POSIX headclean(); /* delete header file */ pfclean(); /* clean up persist files */ @@ -147,8 +165,8 @@ int code; #ifndef NON_POSIX -void -report() /* report progress */ +static void +report(int dummy) /* report progress */ { double u, s; #ifdef BSD @@ -187,8 +205,8 @@ report() /* report progress */ #endif } #else -void -report() /* report progress */ +static void +report(int dummy) /* report progress */ { tlastrept = time((time_t *)NULL); sprintf(errmsg, "%lu rays, %4.2f%% after %5.4f hours\n", @@ -198,10 +216,13 @@ report() /* report progress */ #endif -void -rpict(seq, pout, zout, prvr) /* generate image(s) */ -int seq; -char *pout, *zout, *prvr; +extern void +rpict( /* generate image(s) */ + int seq, + char *pout, + char *zout, + char *prvr +) /* * If seq is greater than zero, then we will render a sequence of * images based on view parameter strings read from the standard input. @@ -296,8 +317,7 @@ char *pout, *zout, *prvr; } hres = hresolu; vres = vresolu; pa = pixaspect; if (prvr != NULL) { - if (viewfile(prvr, &ourview, &rs) <= 0 - || rs.rt != PIXSTANDARD) { + if (viewfile(prvr, &ourview, &rs) <= 0) { sprintf(errmsg, "cannot recover view parameters from \"%s\"", prvr); error(WARNING, errmsg); @@ -341,8 +361,10 @@ char *pout, *zout, *prvr; } -nextview(fp) /* get next view from fp */ -FILE *fp; +static int +nextview( /* get next view from fp */ + FILE *fp +) { char linebuf[256]; @@ -354,8 +376,11 @@ FILE *fp; } -render(zfile, oldfile) /* render the scene */ -char *zfile, *oldfile; +static void +render( /* render the scene */ + char *zfile, + char *oldfile +) { COLOR *scanbar[MAXDIV+1]; /* scanline arrays of pixel values */ float *zbar[MAXDIV+1]; /* z values */ @@ -417,7 +442,7 @@ char *zfile, *oldfile; error(SYSTEM, "z-file seek error in render"); pctdone = 100.0*i/vres; if (ralrm > 0) /* report init stats */ - report(); + report(0); #ifdef SIGCONT else signal(SIGCONT, report); @@ -463,7 +488,7 @@ char *zfile, *oldfile; /* record progress */ pctdone = 100.0*(vres-1-ypos)/vres; if (ralrm > 0 && time((time_t *)NULL) >= tlastrept+ralrm) - report(); + report(0); #ifdef SIGCONT else signal(SIGCONT, report); @@ -492,7 +517,7 @@ alldone: free(sampdens); pctdone = 100.0; if (ralrm > 0) - report(); + report(0); #ifdef SIGCONT signal(SIGCONT, SIG_DFL); #endif @@ -504,11 +529,15 @@ memerr: } -fillscanline(scanline, zline, sd, xres, y, xstep) /* fill scan at y */ -register COLOR *scanline; -register float *zline; -register char *sd; -int xres, y, xstep; +static void +fillscanline( /* fill scan at y */ + register COLOR *scanline, + register float *zline, + register char *sd, + int xres, + int y, + int xstep +) { static int nc = 0; /* number of calls */ int bl = xstep, b = xstep; @@ -539,10 +568,14 @@ int xres, y, xstep; } -fillscanbar(scanbar, zbar, xres, y, ysize) /* fill interior */ -register COLOR *scanbar[]; -register float *zbar[]; -int xres, y, ysize; +static void +fillscanbar( /* fill interior */ + register COLOR *scanbar[], + register float *zbar[], + int xres, + int y, + int ysize +) { COLOR vline[MAXDIV+1]; float zline[MAXDIV+1]; @@ -568,13 +601,16 @@ int xres, y, ysize; } -int -fillsample(colline, zline, x, y, xlen, ylen, b) /* fill interior points */ -register COLOR *colline; -register float *zline; -int x, y; -int xlen, ylen; -int b; +static int +fillsample( /* fill interior points */ + register COLOR *colline, + register float *zline, + int x, + int y, + int xlen, + int ylen, + int b +) { double ratio; double z; @@ -621,14 +657,17 @@ int b; } -double -pixvalue(col, x, y) /* compute pixel value */ -COLOR col; /* returned color */ -int x, y; /* pixel position */ +static double +pixvalue( /* compute pixel value */ + COLOR col, /* returned color */ + int x, /* pixel position */ + int y +) { RAY thisray; FVECT lorg, ldir; - double hpos, vpos, lmax, d; + double hpos, vpos, vdist, lmax; + register int i; /* compute view ray */ hpos = (x+pixjitter())/hres; vpos = (y+pixjitter())/vres; @@ -637,13 +676,12 @@ int x, y; /* pixel position */ setcolor(col, 0.0, 0.0, 0.0); return(0.0); } - - samplendx = pixnumber(x,y,hres,vres); /* set pixel index */ - + vdist = ourview.vdist; + /* set pixel index */ + samplendx = pixnumber(x,y,hres,vres); /* optional motion blur */ if (lastview.type && mblur > FTINY && (lmax = viewray(lorg, ldir, &lastview, hpos, vpos)) >= -FTINY) { - register int i; register double d = mblur*(.5-urand(281+samplendx)); thisray.rmax = (1.-d)*thisray.rmax + d*lmax; @@ -653,9 +691,43 @@ int x, y; /* pixel position */ } if (normalize(thisray.rdir) == 0.0) return(0.0); + vdist = (1.-d)*vdist + d*lastview.vdist; } + /* optional depth-of-field */ + if (dblur > FTINY && vdist > FTINY) { + double vc, dfh, dfv; + /* PI/4. square/circle conv. */ + dfh = PI/4.*dblur*(.5 - frandom()); + dfv = PI/4.*dblur*(.5 - frandom()); + if (ourview.type == VT_PER || ourview.type == VT_PAR) { + dfh /= sqrt(ourview.hn2); + dfv /= sqrt(ourview.vn2); + for (i = 3; i--; ) { + vc = thisray.rorg[i] + vdist*thisray.rdir[i]; + thisray.rorg[i] += dfh*ourview.hvec[i] + + dfv*ourview.vvec[i] ; + thisray.rdir[i] = vc - thisray.rorg[i]; + } + } else { /* non-standard view case */ + double dfd = PI/4.*dblur*(.5 - frandom()); + if (ourview.type != VT_ANG && ourview.type != VT_PLS) { + if (ourview.type != VT_CYL) + dfh /= sqrt(ourview.hn2); + dfv /= sqrt(ourview.vn2); + } + for (i = 3; i--; ) { + vc = thisray.rorg[i] + vdist*thisray.rdir[i]; + thisray.rorg[i] += dfh*ourview.hvec[i] + + dfv*ourview.vvec[i] + + dfd*ourview.vdir[i] ; + thisray.rdir[i] = vc - thisray.rorg[i]; + } + } + if (normalize(thisray.rdir) == 0.0) + return(0.0); + } - rayorigin(&thisray, NULL, PRIMARY, 1.0); + rayorigin(&thisray, PRIMARY, NULL, NULL); rayvalue(&thisray); /* trace ray */ @@ -665,9 +737,10 @@ int x, y; /* pixel position */ } -int -salvage(oldfile) /* salvage scanlines from killed program */ -char *oldfile; +static int +salvage( /* salvage scanlines from killed program */ + char *oldfile +) { COLR *scanline; FILE *fp; @@ -721,13 +794,16 @@ gotzip: writerr: sprintf(errmsg, "write error during recovery of \"%s\"", oldfile); error(SYSTEM, errmsg); + return -1; /* pro forma return */ } - -int -pixnumber(x, y, xres, yres) /* compute pixel index (brushed) */ -register int x, y; -int xres, yres; +static int +pixnumber( /* compute pixel index (brushed) */ + register int x, + register int y, + int xres, + int yres +) { x -= y; while (x < 0)