extern void /* add sources smaller than rad to computed subimage */ drawsources( COLOR *pic[], /* subimage pixel value array */ float *zbf[], /* subimage distance array (opt.) */ int x0, /* origin and size of subimage */ int xsiz, int y0, int ysiz ) { RREAL spoly[MAXVERT][2], ppoly[MAXVERT][2]; int nsv, npv; int xmin, xmax, ymin, ymax, x, y; RREAL cxy[2]; double w; RAY sr; register SPLIST *sp; register int i; /* check each source in our list */ for (sp = sphead; sp != NULL; sp = sp->next) { /* clip source poly to subimage */ nsv = box_clip_poly(sp->vl, sp->nv, (double)x0/hres, (double)(x0+xsiz)/hres, (double)y0/vres, (double)(y0+ysiz)/vres, spoly); if (!nsv) continue; /* find common subimage (BBox) */ xmin = x0 + xsiz; xmax = x0; ymin = y0 + ysiz; ymax = y0; for (i = 0; i < nsv; i++) { if ((double)xmin/hres > spoly[i][0]) xmin = spoly[i][0]*hres + FTINY; if ((double)xmax/hres < spoly[i][0]) xmax = spoly[i][0]*hres - FTINY; if ((double)ymin/vres > spoly[i][1]) ymin = spoly[i][1]*vres + FTINY; if ((double)ymax/vres < spoly[i][1]) ymax = spoly[i][1]*vres - FTINY; } /* evaluate each pixel in BBox */ for (y = ymin; y <= ymax; y++) for (x = xmin; x <= xmax; x++) { /* subarea for pixel */ npv = box_clip_poly(spoly, nsv, (double)x/hres, (x+1.)/hres, (double)y/vres, (y+1.)/vres, ppoly); if (!npv) continue; /* no overlap */ convex_center(ppoly, npv, cxy); if ((sr.rmax = viewray(sr.rorg,sr.rdir,&ourview, cxy[0],cxy[1])) < -FTINY) continue; /* not in view */ if (source[sp->sn].sflags & SSPOT && spotout(&sr, source[sp->sn].sl.s)) continue; /* outside spot */ rayorigin(&sr, SHADOW, NULL, NULL); sr.rsrc = sp->sn; rayvalue(&sr); /* compute value */ if (bright(sr.rcol) <= FTINY) continue; /* missed/blocked */ /* modify pixel */ w = poly_area(ppoly, npv) * hres * vres; if (zbf[y-y0] != NULL && sr.rt < 0.99*zbf[y-y0][x-x0]) { zbf[y-y0][x-x0] = sr.rt; } else if (!bigdiff(sr.rcol, pic[y-y0][x-x0], 0.01)) { /* source sample */ scalecolor(pic[y-y0][x-x0], w); continue; } scalecolor(sr.rcol, w); scalecolor(pic[y-y0][x-x0], 1.-w); addcolor(pic[y-y0][x-x0], sr.rcol); } } }
extern int refine_first(void) /* initial refinement pass */ { int *esamp = (int *)zprev; /* OK to reuse */ int hl_erri = errori(HL_ERR); int nextra = 0; int x, y, xp, yp; int neigh; register int n, np; if (sizeof(int) < sizeof(*zprev)) error(CONSISTENCY, "code error in refine_first"); if (!silent) { printf("\tFirst refinement pass..."); fflush(stdout); } memset((void *)esamp, '\0', sizeof(int)*hres*vres); /* * In our initial pass, we look for lower error pixels from * the same objects in the previous frame, and copy them here. */ for (y = vres; y--; ) for (x = hres; x--; ) { n = fndx(x, y); if (obuffer[n] == OVOID) continue; if (xmbuffer[n] == MO_UNK) continue; xp = x + xmbuffer[n]; if ((xp < 0) | (xp >= hres)) continue; yp = y + ymbuffer[n]; if ((yp < 0) | (yp >= vres)) continue; np = fndx(xp, yp); /* make sure we hit same object */ if (oprev[np] != obuffer[n]) continue; /* is previous frame error lower? */ if (aprev[np] < AMIN + ATIDIFF) continue; if (aprev[np] <= abuffer[n] + ATIDIFF) continue; /* shadow & highlight detection */ if (abuffer[n] > hl_erri && getclosest(&neigh, 1, x, y) && bigdiff(cbuffer[neigh], cprev[np], HL_ERR*(.9+.2*frandom()))) continue; abuffer[n] = aprev[np] - ATIDIFF; copycolor(cbuffer[n], cprev[np]); esamp[n] = 1; /* record extrapolated sample */ nextra++; } for (n = hres*vres; n--; ) /* update sample counts */ if (esamp[n]) sbuffer[n] = 1; if (!silent) printf("extrapolated %d pixels\n", nextra); return(1); }