--- ray/src/rt/srcdraw.c 2003/02/22 02:07:29 2.5 +++ ray/src/rt/srcdraw.c 2004/09/02 04:16:58 2.12 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: srcdraw.c,v 2.5 2003/02/22 02:07:29 greg Exp $"; +static const char RCSid[] = "$Id: srcdraw.c,v 2.12 2004/09/02 04:16:58 greg Exp $"; #endif /* * Draw small sources into image in case we missed them. @@ -7,67 +7,10 @@ static const char RCSid[] = "$Id: srcdraw.c,v 2.5 2003 * External symbols declared in ray.h */ -/* ==================================================================== - * 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" #include "ray.h" - #include "view.h" - #include "source.h" @@ -82,19 +25,33 @@ typedef struct splist { struct splist *next; /* next source in list */ int sn; /* source number */ short nv; /* number of vertices */ - FLOAT vl[3][2]; /* vertex array (last) */ + RREAL vl[3][2]; /* vertex array (last) */ } SPLIST; /* source polygon list */ extern VIEW ourview; /* our view parameters */ extern int hres, vres; /* our image resolution */ static SPLIST *sphead = NULL; /* our list of source polys */ +static int inregion(RREAL p[2], double cv, int crit); +static void clipregion(RREAL a[2], RREAL b[2], double cv, int crit, RREAL r[2]); +static int hp_clip_poly(RREAL vl[][2], int nv, double cv, int crit, + RREAL vlo[][2]); +static int box_clip_poly(RREAL vl[MAXVERT][2], int nv, + double xl, double xr, double yb, double ya, RREAL vlo[MAXVERT][2]); +static double minw2(RREAL vl[][2], int nv, double ar2); +static void convex_center(RREAL vl[][2], int nv, RREAL cv[2]); +static double poly_area(RREAL vl[][2], int nv); +static int convex_hull(RREAL vl[][2], int nv, RREAL vlo[][2]); +static void spinsert(int sn, RREAL vl[][2], int nv); +static int sourcepoly(int sn, RREAL sp[MAXVERT][2]); + static int -inregion(p, cv, crit) /* check if vertex is in region */ -FLOAT p[2]; -double cv; -int crit; +inregion( /* check if vertex is in region */ + RREAL p[2], + double cv, + int crit +) { switch (crit) { case CLIP_ABOVE: @@ -110,12 +67,14 @@ int crit; } -static -clipregion(a, b, cv, crit, r) /* find intersection with boundary */ -register FLOAT a[2], b[2]; -double cv; -int crit; -FLOAT r[2]; /* return value */ +static void +clipregion( /* find intersection with boundary */ + register RREAL a[2], + register RREAL b[2], + double cv, + int crit, + RREAL r[2] /* return value */ +) { switch (crit) { case CLIP_ABOVE: @@ -133,14 +92,15 @@ FLOAT r[2]; /* return value */ static int -hp_clip_poly(vl, nv, cv, crit, vlo) /* clip polygon to half-plane */ -FLOAT vl[][2]; -int nv; -double cv; -int crit; -FLOAT vlo[][2]; /* return value */ +hp_clip_poly( /* clip polygon to half-plane */ + RREAL vl[][2], + int nv, + double cv, + int crit, + RREAL vlo[][2] /* return value */ +) { - FLOAT *s, *p; + RREAL *s, *p; register int j, nvo; s = vl[nv-1]; @@ -160,13 +120,17 @@ FLOAT vlo[][2]; /* return value */ static int -box_clip_poly(vl, nv, xl, xr, yb, ya, vlo) /* clip polygon to box */ -FLOAT vl[MAXVERT][2]; -int nv; -double xl, xr, yb, ya; -FLOAT vlo[MAXVERT][2]; /* return value */ +box_clip_poly( /* clip polygon to box */ + RREAL vl[MAXVERT][2], + int nv, + double xl, + double xr, + double yb, + double ya, + RREAL vlo[MAXVERT][2] /* return value */ +) { - FLOAT vlt[MAXVERT][2]; + RREAL vlt[MAXVERT][2]; int nvt, nvo; nvt = hp_clip_poly(vl, nv, yb, CLIP_BELOW, vlt); @@ -179,13 +143,14 @@ FLOAT vlo[MAXVERT][2]; /* return value */ static double -minw2(vl, nv, ar2) /* compute square of minimum width */ -FLOAT vl[][2]; -int nv; -double ar2; +minw2( /* compute square of minimum width */ + RREAL vl[][2], + int nv, + double ar2 +) { double d2, w2, w2min, w2max; - register FLOAT *p0, *p1, *p2; + register RREAL *p0, *p1, *p2; int i, j; /* find minimum for all widths */ w2min = FHUGE; @@ -211,11 +176,12 @@ double ar2; } -static -convex_center(vl, nv, cv) /* compute center of convex polygon */ -register FLOAT vl[][2]; -int nv; -FLOAT cv[2]; /* return value */ +static void +convex_center( /* compute center of convex polygon */ + register RREAL vl[][2], + int nv, + RREAL cv[2] /* return value */ +) { register int i; /* simple average (suboptimal) */ @@ -230,12 +196,13 @@ FLOAT cv[2]; /* return value */ static double -poly_area(vl, nv) /* compute area of polygon */ -register FLOAT vl[][2]; -int nv; +poly_area( /* compute area of polygon */ + register RREAL vl[][2], + int nv +) { double a; - FLOAT v0[2], v1[2]; + RREAL v0[2], v1[2]; register int i; a = 0.; @@ -252,13 +219,14 @@ int nv; static int -convex_hull(vl, nv, vlo) /* compute polygon's convex hull */ -FLOAT vl[][2]; -int nv; -FLOAT vlo[][2]; /* return value */ +convex_hull( /* compute polygon's convex hull */ + RREAL vl[][2], + int nv, + RREAL vlo[][2] /* return value */ +) { int nvo, nvt; - FLOAT vlt[MAXVERT][2]; + RREAL vlt[MAXVERT][2]; double voa, vta; register int i, j; /* start with original polygon */ @@ -287,11 +255,12 @@ FLOAT vlo[][2]; /* return value */ } -static -spinsert(sn, vl, nv) /* insert new source polygon */ -int sn; -FLOAT vl[][2]; -int nv; +static void +spinsert( /* insert new source polygon */ + int sn, + RREAL vl[][2], + int nv +) { register SPLIST *spn; register int i; @@ -299,7 +268,7 @@ int nv; if (nv < 3) return; if (nv > 3) - spn = (SPLIST *)malloc(sizeof(SPLIST)+sizeof(FLOAT)*2*(nv-3)); + spn = (SPLIST *)malloc(sizeof(SPLIST)+sizeof(RREAL)*2*(nv-3)); else spn = (SPLIST *)malloc(sizeof(SPLIST)); if (spn == NULL) @@ -313,24 +282,29 @@ int nv; } -int -sourcepoly(sn, sp) /* compute image polygon for source */ -int sn; -FLOAT sp[MAXVERT][2]; +static int +sourcepoly( /* compute image polygon for source */ + int sn, + RREAL sp[MAXVERT][2] +) { - static char cubeord[8][6] = {{1,3,2,6,4,5},{0,4,5,7,3,2}, + static short cubeord[8][6] = {{1,3,2,6,4,5},{0,4,5,7,3,2}, {0,1,3,7,6,4},{0,1,5,7,6,2}, {0,2,6,7,5,1},{0,4,6,7,3,1}, {0,2,3,7,5,4},{1,5,4,6,2,3}}; register SRCREC *s = source + sn; FVECT ap, ip; - FLOAT pt[6][2]; + RREAL pt[6][2]; int dir; register int i, j; if (s->sflags & (SDISTANT|SFLAT)) { - if (s->sflags & SDISTANT && ourview.type == VT_PAR) - return(0); /* all or nothing case */ + if (s->sflags & SDISTANT) { + if (ourview.type == VT_PAR) + return(0); /* all or nothing case */ + if (s->srad >= 0.05) + return(0); /* should never be a problem */ + } if (s->sflags & SFLAT) { for (i = 0; i < 3; i++) ap[i] = s->sloc[i] - ourview.vp[i]; @@ -340,9 +314,9 @@ FLOAT sp[MAXVERT][2]; for (j = 0; j < 4; j++) { /* four corners */ for (i = 0; i < 3; i++) { ap[i] = s->sloc[i]; - if (j==1|j==2) ap[i] += s->ss[SU][i]; + if ((j==1)|(j==2)) ap[i] += s->ss[SU][i]; else ap[i] -= s->ss[SU][i]; - if (j==2|j==3) ap[i] += s->ss[SV][i]; + if ((j==2)|(j==3)) ap[i] += s->ss[SV][i]; else ap[i] -= s->ss[SV][i]; if (s->sflags & SDISTANT) { ap[i] *= 1. + ourview.vfore; @@ -383,10 +357,12 @@ FLOAT sp[MAXVERT][2]; /* initialize by finding sources smaller than rad */ -init_drawsources(rad) -int rad; /* source sample size */ +extern void +init_drawsources( + int rad /* source sample size */ +) { - FLOAT spoly[MAXVERT][2]; + RREAL spoly[MAXVERT][2]; int nsv; register SPLIST *sp; register int i; @@ -412,16 +388,20 @@ int rad; /* source sample size */ } } -void /* add sources smaller than rad to computed subimage */ -drawsources(pic, zbf, x0, xsiz, y0, ysiz) -COLOR *pic[]; /* subimage pixel value array */ -float *zbf[]; /* subimage distance array (opt.) */ -int x0, xsiz, y0, ysiz; /* origin and size of subimage */ +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 +) { - FLOAT spoly[MAXVERT][2], ppoly[MAXVERT][2]; + RREAL spoly[MAXVERT][2], ppoly[MAXVERT][2]; int nsv, npv; int xmin, xmax, ymin, ymax, x, y; - FLOAT cxy[2]; + RREAL cxy[2]; double w; RAY sr; register SPLIST *sp; @@ -464,22 +444,27 @@ int x0, xsiz, y0, ysiz; /* origin and size of subimag if (source[sp->sn].sflags & SSPOT && spotout(&sr, source[sp->sn].sl.s)) continue; /* outside spot */ - rayorigin(&sr, NULL, SHADOW, 1.0); - sr.rsrc = sp->sn; + w = poly_area(ppoly, npv) * hres * vres; + if (w < .95) { /* subpixel source */ + rayorigin(&sr, NULL, SHADOW, 1.0); + sr.rsrc = sp->sn; + } else + rayorigin(&sr, NULL, PRIMARY, 1.0); rayvalue(&sr); /* compute value */ if (bright(sr.rcol) <= FTINY) continue; /* missed/blocked */ /* modify pixel */ if (zbf[y-y0] != NULL && - sr.rt < 0.999*zbf[y-y0][x-x0]) + 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.001)) /* source sample */ - setcolor(pic[y-y0][x-x0], 0., 0., 0.); - w = poly_area(ppoly, npv) * hres * vres; - scalecolor(sr.rcol, w); - scalecolor(pic[y-y0][x-x0], 1.-w); - addcolor(pic[y-y0][x-x0], sr.rcol); + 0.01)) /* source sample */ + scalecolor(pic[y-y0][x-x0], w); + else { + scalecolor(sr.rcol, w); + scalecolor(pic[y-y0][x-x0], 1.-w); + addcolor(pic[y-y0][x-x0], sr.rcol); + } } } }