--- ray/src/util/ranimove1.c 2004/05/13 15:45:43 3.9 +++ ray/src/util/ranimove1.c 2012/10/05 01:03:22 3.22 @@ -1,10 +1,10 @@ #ifndef lint -static const char RCSid[] = "$Id: ranimove1.c,v 3.9 2004/05/13 15:45:43 greg Exp $"; +static const char RCSid[] = "$Id: ranimove1.c,v 3.22 2012/10/05 01:03:22 greg Exp $"; #endif /* * ranimove1.c * - * Basic frame rendering routines for ranimate(1). + * Basic frame rendering routines for ranimove(1). * * Created by Gregory Ward on Wed Jan 08 2003. */ @@ -30,14 +30,14 @@ float *zbuffer; /* depth at each pixel */ OBJECT *obuffer; /* object id at each pixel */ short *xmbuffer; /* x motion at each pixel */ short *ymbuffer; /* y motion at each pixel */ -BYTE *abuffer; /* accuracy at each pixel */ -BYTE *sbuffer; /* sample count per pixel */ +uby8 *abuffer; /* accuracy at each pixel */ +uby8 *sbuffer; /* sample count per pixel */ VIEW vwprev; /* last frame's view */ COLOR *cprev; /* last frame colors */ float *zprev; /* last frame depth */ OBJECT *oprev; /* last frame objects */ -BYTE *aprev; /* last frame accuracy */ +uby8 *aprev; /* last frame accuracy */ float *cerrmap; /* conspicuous error map */ COLOR *val2map; /* value-squared map for variance */ @@ -48,13 +48,14 @@ double hlsmax; /* maximum high-level saliency this f static void next_frame(void); -static int sample_here(int x, int y); -static int offset_cmp(const void *p1, const void *p2); -static void setmotion(int n, FVECT wpos); +static int sample_here(int x, int y); +static int offset_cmp(const void *p1, const void *p2); +static void setmotion(int n, FVECT wpos); static void init_frame_sample(void); -extern void +#if 0 +void write_map( /* write out float map (debugging) */ float *mp, char *fn @@ -79,6 +80,7 @@ write_map( /* write out float map (debugging) */ } fclose(fp); } +#endif static void @@ -105,6 +107,7 @@ next_frame(void) /* prepare next frame buffer */ error(USER, errmsg); } if (cbuffer == NULL) { + int n; /* compute resolution and allocate */ switch (sscanf(vval(RESOLUTION), "%d %d %lf", &hres, &vres, &pixaspect)) { @@ -128,30 +131,34 @@ next_frame(void) /* prepare next frame buffer */ obuffer = (OBJECT *)malloc(sizeof(OBJECT)*hres*vres); xmbuffer = (short *)malloc(sizeof(short)*hres*vres); ymbuffer = (short *)malloc(sizeof(short)*hres*vres); - abuffer = (BYTE *)calloc(hres*vres, sizeof(BYTE)); - sbuffer = (BYTE *)calloc(hres*vres, sizeof(BYTE)); + abuffer = (uby8 *)calloc(hres*vres, sizeof(uby8)); + sbuffer = (uby8 *)calloc(hres*vres, sizeof(uby8)); cprev = (COLOR *)malloc(sizeof(COLOR)*hres*vres); zprev = (float *)malloc(sizeof(float)*hres*vres); oprev = (OBJECT *)malloc(sizeof(OBJECT)*hres*vres); - aprev = (BYTE *)malloc(sizeof(BYTE)*hres*vres); + aprev = (uby8 *)malloc(sizeof(uby8)*hres*vres); if ((cbuffer==NULL) | (zbuffer==NULL) | (obuffer==NULL) | (xmbuffer==NULL) | (ymbuffer==NULL) | (abuffer==NULL) | (sbuffer==NULL) | (cprev==NULL) | (zprev == NULL) | (oprev==NULL) | (aprev==NULL)) error(SYSTEM, "out of memory in init_frame"); + for (n = hres*vres; n--; ) { + zprev[n] = -1.f; + oprev[n] = OVOID; + } frm_stop = getTime() + rtperfrm; } else { COLOR *cp; /* else just swap buffers */ float *fp; OBJECT *op; - BYTE *bp; + uby8 *bp; cp = cprev; cprev = cbuffer; cbuffer = cp; fp = zprev; zprev = zbuffer; zbuffer = fp; op = oprev; oprev = obuffer; obuffer = op; bp = aprev; aprev = abuffer; abuffer = bp; - memset(abuffer, '\0', sizeof(BYTE)*hres*vres); - memset(sbuffer, '\0', sizeof(BYTE)*hres*vres); + memset(abuffer, '\0', sizeof(uby8)*hres*vres); + memset(sbuffer, '\0', sizeof(uby8)*hres*vres); frm_stop += rtperfrm; } cerrmap = NULL; @@ -165,8 +172,8 @@ next_frame(void) /* prepare next frame buffer */ static int sample_here( /* 4x4 quincunx sample at this pixel? */ - register int x, - register int y + int x, + int y ) { if (y & 0x1) /* every other row has samples */ @@ -177,7 +184,7 @@ sample_here( /* 4x4 quincunx sample at this pixel? */ } -extern void +void sample_pos( /* compute jittered sample position */ double hv[2], int x, @@ -194,7 +201,7 @@ sample_pos( /* compute jittered sample position */ } -extern double +double sample_wt( /* compute interpolant sample weight */ int xo, int yo @@ -228,7 +235,7 @@ offset_cmp( /* compare offset distances */ } -extern int +int getclosest( /* get nc closest neighbors on same object */ int *iarr, int nc, @@ -241,7 +248,7 @@ getclosest( /* get nc closest neighbors on same object static int ioffs[NSCHECK]; OBJECT myobj; int i0, nf; - register int i, j; + int i, j; /* get our object number */ myobj = obuffer[fndx(x, y)]; /* special case for borders */ @@ -305,7 +312,7 @@ getclosest( /* get nc closest neighbors on same object static void setmotion( /* compute motion vector for this pixel */ - register int n, + int n, FVECT wpos ) { @@ -344,7 +351,7 @@ init_frame_sample(void) /* sample our initial frame * { RAY ir; int x, y; - register int n; + int n; if (!silent) { printf("\tComputing initial samples..."); @@ -355,8 +362,7 @@ init_frame_sample(void) /* sample our initial frame * for (x = hres; x--; ) { double hv[2]; n = fndx(x, y); - xmbuffer[n] = MO_UNK; - ymbuffer[n] = MO_UNK; + xmbuffer[n] = ymbuffer[n] = MO_UNK; sample_pos(hv, x, y, 0); ir.rmax = viewray(ir.rorg, ir.rdir, &vw, hv[0], hv[1]); if (ir.rmax < -FTINY) { @@ -367,10 +373,12 @@ init_frame_sample(void) /* sample our initial frame * continue; } if (!sample_here(x, y)) { /* just cast */ - rayorigin(&ir, NULL, PRIMARY, 1.0); + rayorigin(&ir, PRIMARY, NULL, NULL); if (!localhit(&ir, &thescene)) { - if (ir.ro != &Aftplane) - sourcehit(&ir); + if (ir.ro != &Aftplane && sourcehit(&ir)) { + rayshade(&ir, ir.ro->omod); + rayparticipate(&ir); + } copycolor(cbuffer[n], ir.rcol); zbuffer[n] = ir.rot; obuffer[n] = ir.robj; @@ -385,7 +393,7 @@ init_frame_sample(void) /* sample our initial frame * } if (nprocs > 1) { /* get sample */ int rval; - rayorigin(&ir, NULL, PRIMARY, 1.0); + rayorigin(&ir, PRIMARY, NULL, NULL); ir.rno = n; rval = ray_pqueue(&ir); if (!rval) @@ -399,7 +407,7 @@ init_frame_sample(void) /* sample our initial frame * zbuffer[n] = ir.rot; obuffer[n] = ir.robj; sbuffer[n] = 1; - if (ir.rot >= FHUGE) + if (ir.rot >= 0.99*FHUGE) abuffer[n] = ADISTANT; else { abuffer[n] = ALOWQ; @@ -442,25 +450,22 @@ init_frame_sample(void) /* sample our initial frame * } -extern int +int getambcolor( /* get ambient color for object if we can */ COLOR clr, int obj ) { - register OBJREC *op; + OBJREC *op; if (obj == OVOID) return(0); - op = objptr(obj); - if ((op->otype == OBJ_INSTANCE) & (op->omod == OVOID)) + op = objptr(obj); /* search for material */ + if (op->omod == OVOID) return(0); - /* search for material */ - do { - if (op->omod == OVOID || ofun[op->otype].flags & T_X) - return(0); - op = objptr(op->omod); - } while (!ismaterial(op->otype)); + op = findmaterial(objptr(op->omod)); + if (op == NULL) + return(0); /* * Since this routine is called to compute the difference * from rendering with and without interreflections, @@ -474,7 +479,7 @@ getambcolor( /* get ambient color for object if we ca if (lv[0] == op->oname[0] && !strcmp(lv+1, op->oname+1)) break; - if ((lv != NULL) != hirendparams.ambincl) + if ((lv != NULL) ^ hirendparams.ambincl) return(0); } switch (op->otype) { @@ -513,7 +518,7 @@ getambcolor( /* get ambient color for object if we ca } -extern double +double estimaterr( /* estimate relative error from samples */ COLOR cs, COLOR cs2, @@ -539,7 +544,7 @@ estimaterr( /* estimate relative error from samples * } -extern double +double comperr( /* estimate relative error in neighborhood */ int *neigh, int nc, @@ -550,7 +555,7 @@ comperr( /* estimate relative error in neighborhood * COLOR ctmp; int i; int ns; - register int n; + int n; /* add together samples */ setcolor(csum, 0., 0., 0.); setcolor(csum2, 0., 0., 0.); @@ -575,16 +580,16 @@ comperr( /* estimate relative error in neighborhood * } -extern void +void comp_frame_error(void) /* initialize frame error values */ { - BYTE *edone = NULL; + uby8 *edone = NULL; COLOR objamb; double eest; int neigh[NSAMPOK]; int nc; int x, y, i; - register int n; + int n; if (!silent) { printf("\tComputing error map\n"); @@ -602,10 +607,8 @@ comp_frame_error(void) /* initialize frame error valu * error should be less than the ambient value divided * by the returned ray value -- we take half of this. */ - edone = (BYTE *)calloc(hres*vres, sizeof(BYTE)); - for (y = vres; y--; ) - for (x = hres; x--; ) { - n = fndx(x, y); + edone = (uby8 *)calloc(hres*vres, sizeof(uby8)); + for (n = hres*vres; n--; ) { if ((abuffer[n] != ALOWQ) | (obuffer[n] == OVOID)) continue; if (!getambcolor(objamb, obuffer[n])) @@ -622,7 +625,7 @@ comp_frame_error(void) /* initialize frame error valu else if (i >= ADISTANT/2) i = ADISTANT/2-1; abuffer[n] = i; edone[n] = 1; - } + } } /* final statistical estimate */ for (y = vres; y--; ) @@ -654,23 +657,16 @@ comp_frame_error(void) /* initialize frame error valu } -extern void +void init_frame(void) /* render base (low quality) frame */ { int restart; - /* allocate/swap buffers */ next_frame(); /* check rendering status */ restart = (!nobjects || vdef(MOVE)); if (!restart && curparams != &lorendparams && nprocs > 1) restart = -1; - if (restart > 0) { - if (nprocs > 1) - ray_pdone(1); - else - ray_done(1); - } /* post low quality parameters */ if (curparams != &lorendparams) ray_restore(curparams = &lorendparams); @@ -702,11 +698,11 @@ init_frame(void) /* render base (low quality) frame init_frame_sample(); /* initialize frame error */ comp_frame_error(); -return; +#if 0 { float *ebuf = (float *)malloc(sizeof(float)*hres*vres); char fnm[256]; - register int n; + int n; for (n = hres*vres; n--; ) ebuf[n] = acctab[abuffer[n]]; sprintf(fnm, vval(BASENAME), fcur); @@ -714,19 +710,20 @@ return; write_map(ebuf, fnm); free((void *)ebuf); } +#endif } -extern void +void filter_frame(void) /* interpolation, motion-blur, and exposure */ { - double expval = expspec_val(getexp(fcur)); - int x, y; - int neigh[NPINTERP]; - int nc; - COLOR cval; - double w, wsum; - register int n; + const double expval = expspec_val(getexp(fcur)); + int x, y; + int neigh[NPINTERP]; + int nc; + COLOR cval; + double w, wsum; + int n; #if 0 /* XXX TEMPORARY!! */ @@ -740,20 +737,17 @@ filter_frame(void) /* interpolation, motion-blur, an free((void *)ebuf); } #endif - if (!silent) { printf("\tFiltering frame\n"); fflush(stdout); } /* normalize samples */ - for (y = vres; y--; ) - for (x = hres; x--; ) { - n = fndx(x, y); + for (n = hres*vres; n--; ) { if (sbuffer[n] <= 1) continue; w = 1.0/(double)sbuffer[n]; scalecolor(cbuffer[n], w); - } + } /* interpolate samples */ for (y = vres; y--; ) for (x = hres; x--; ) { @@ -762,6 +756,16 @@ filter_frame(void) /* interpolation, motion-blur, an continue; nc = getclosest(neigh, NPINTERP, x, y); setcolor(cbuffer[n], 0., 0., 0.); + if (nc <= 0) { /* no acceptable neighbors */ + if (y < vres-1) + nc = fndx(x, y+1); + else if (x < hres-1) + nc = fndx(x+1, y); + else + continue; + copycolor(cbuffer[n], cbuffer[nc]); + continue; + } wsum = 0.; while (nc-- > 0) { copycolor(cval, cbuffer[neigh[nc]]); @@ -771,10 +775,8 @@ filter_frame(void) /* interpolation, motion-blur, an addcolor(cbuffer[n], cval); wsum += w; } - if (wsum > FTINY) { - w = 1.0/wsum; - scalecolor(cbuffer[n], w); - } + w = 1.0/wsum; + scalecolor(cbuffer[n], w); } /* motion blur if requested */ if (mblur > .02) { @@ -852,26 +854,22 @@ filter_frame(void) /* interpolation, motion-blur, an } } /* compute final results */ - for (y = vres; y--; ) - for (x = hres; x--; ) { - n = fndx(x, y); + for (n = hres*vres; n--; ) { if (wbuffer[n] <= FTINY) continue; - w = 1./wbuffer[n]; + w = expval/wbuffer[n]; scalecolor(outbuffer[n], w); - } - } else - for (n = hres*vres; n--; ) - copycolor(outbuffer[n], cbuffer[n]); + } + } else { /* no blur -- just exposure */ + memcpy(outbuffer, cbuffer, sizeof(COLOR)*hres*vres); + for (n = ((expval < 0.99) | (expval > 1.01))*hres*vres; n--; ) + scalecolor(outbuffer[n], expval); + } /* for (n = hres*vres; n--; ) if (!sbuffer[n]) setcolor(outbuffer[n], 0., 0., 0.); */ - /* adjust exposure */ - if ((expval < 0.99) | (expval > 1.01)) - for (n = hres*vres; n--; ) - scalecolor(outbuffer[n], expval); #if 0 { float *sbuf = (float *)malloc(sizeof(float)*hres*vres); @@ -887,24 +885,24 @@ filter_frame(void) /* interpolation, motion-blur, an } -extern void +void send_frame(void) /* send frame to destination */ { - char pfname[1024]; + char fname[1024]; double d; FILE *fp; int y; /* open output picture */ - sprintf(pfname, vval(BASENAME), fcur); - strcat(pfname, ".pic"); - fp = fopen(pfname, "w"); + sprintf(fname, vval(BASENAME), fcur); + strcat(fname, ".hdr"); + fp = fopen(fname, "w"); if (fp == NULL) { - sprintf(errmsg, "cannot open output frame \"%s\"", pfname); + sprintf(errmsg, "cannot open output frame \"%s\"", fname); error(SYSTEM, errmsg); } SET_FILE_BINARY(fp); if (!silent) { - printf("\tWriting to \"%s\"\n", pfname); + printf("\tWriting to \"%s\"\n", fname); fflush(stdout); } /* write header */ @@ -933,14 +931,68 @@ send_frame(void) /* send frame to destination */ goto writerr; if (fclose(fp) == EOF) goto writerr; + if (vdef(ZNAME)) { /* output z-buffer */ + sprintf(fname, vval(ZNAME), fcur); + strcat(fname, ".zbf"); + fp = fopen(fname, "w"); + if (fp == NULL) { + sprintf(errmsg, "cannot open z-file \"%s\"\n", fname); + error(SYSTEM, errmsg); + } + SET_FILE_BINARY(fp); + if (!silent) { + printf("\tWriting depths to \"%s\"\n", fname); + fflush(stdout); + } + for (y = vres; y--; ) + if (fwrite(zbuffer+y*hres, sizeof(float), + hres, fp) != hres) + goto writerr; + if (fclose(fp) == EOF) + goto writerr; + } + if (vdef(MNAME)) { /* output motion buffer */ + unsigned short *mbuffer = (unsigned short *)malloc( + sizeof(unsigned short)*3*hres); + int x, n; + if (mbuffer == NULL) + error(SYSTEM, "out of memory in send_frame"); + sprintf(fname, vval(MNAME), fcur); + strcat(fname, ".mvo"); + fp = fopen(fname, "w"); + if (fp == NULL) { + sprintf(errmsg, "cannot open motion file \"%s\"\n", + fname); + error(SYSTEM, errmsg); + } + SET_FILE_BINARY(fp); + if (!silent) { + printf("\tWriting motion vectors to \"%s\"\n", fname); + fflush(stdout); + } + for (y = vres; y--; ) { + for (x = hres; x--; ) { + n = fndx(x,y); + mbuffer[3*x] = xmbuffer[n] + 0x8000; + mbuffer[3*x+1] = ymbuffer[n] + 0x8000; + mbuffer[3*x+2] = (oprev[n]!=OVOID)*0x8000; + } + if (fwrite(mbuffer, sizeof(*mbuffer), + 3*hres, fp) != 3*hres) + goto writerr; + } + free((void *)mbuffer); + if (fclose(fp) == EOF) + goto writerr; + } return; /* all is well */ writerr: - sprintf(errmsg, "error writing frame \"%s\"", pfname); + sprintf(errmsg, "error writing file \"%s\"", fname); error(SYSTEM, errmsg); } -extern void +void free_frame(void) /* free frame allocation */ { if (cbuffer == NULL)