Back to index

radiance  4R0+20100331
rhd_qtree2r.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: rhd_qtree2r.c,v 3.6 2004/01/01 11:21:55 schorsch Exp $";
00003 #endif
00004 /*
00005  * Quadtree display support routines for rectangle output.
00006  */
00007 
00008 #include "standard.h"
00009 #include "rhd_qtree.h"
00010 
00011 
00012 static void redraw(RTREE *tp, int x0, int y0, int x1, int y1, int l[2][2]);
00013 static void update( BYTE ca[3], RTREE *tp, int x0, int y0, int x1, int y1);
00014 
00015 
00016 static void
00017 redraw(       /* mark portion of a tree for redraw */
00018        register RTREE       *tp,
00019        int    x0,
00020        int    y0,
00021        int    x1,
00022        int    y1,
00023        int    l[2][2]
00024 )
00025 {
00026        int    quads = CH_ANY;
00027        int    mx, my;
00028        register int  i;
00029                                    /* compute midpoint */
00030        mx = (x0 + x1) >> 1;
00031        my = (y0 + y1) >> 1;
00032                                    /* see what to do */
00033        if (l[0][0] > mx)
00034               quads &= ~(CHF(UL)|CHF(DL));
00035        else if (l[0][1] < mx)
00036               quads &= ~(CHF(UR)|CHF(DR));
00037        if (l[1][0] > my)
00038               quads &= ~(CHF(DR)|CHF(DL));
00039        else if (l[1][1] < my)
00040               quads &= ~(CHF(UR)|CHF(UL));
00041        tp->flgs |= quads;          /* mark quadrants for update */
00042                                    /* climb the branches */
00043        for (i = 0; i < 4; i++)
00044               if (tp->flgs & BRF(i) && quads & CHF(i))
00045                      redraw(tp->k[i].b, i&01 ? mx : x0, i&02 ? my : y0,
00046                                    i&01 ? x1 : mx, i&02 ? y1 : my, l);
00047 }
00048 
00049 
00050 static void
00051 update(       /* update tree display as needed */
00052        BYTE   ca[3],        /* returned average color */
00053        register RTREE       *tp,
00054        int    x0,
00055        int    y0,
00056        int    x1,
00057        int    y1
00058 )
00059 {
00060        int    csm[3], nc;
00061        register BYTE *cp;
00062        BYTE   rgb[3];
00063        double dpth2[4], d2;
00064        int    gaps = 0;
00065        int    mx, my;
00066        register int  i;
00067                                    /* compute leaf depths */
00068        d2 = FHUGE*FHUGE;
00069        for (i = 0; i < 4; i++)
00070               if (tp->flgs & LFF(i)) {
00071                      FVECT  dv;
00072                      register float       *wp = qtL.wp[tp->k[i].li];
00073 
00074                      dv[0] = wp[0] - odev.v.vp[0];
00075                      dv[1] = wp[1] - odev.v.vp[1];
00076                      dv[2] = wp[2] - odev.v.vp[2];
00077                      dpth2[i] = DOT(dv,dv);
00078                      if (dpth2[i] < d2)
00079                             d2 = dpth2[i];
00080               }
00081        d2 *= (1.+qtDepthEps)*(1.+qtDepthEps);
00082                                    /* compute midpoint */
00083        mx = (x0 + x1) >> 1;
00084        my = (y0 + y1) >> 1;
00085                                    /* draw leaves */
00086        csm[0] = csm[1] = csm[2] = nc = 0;
00087        for (i = 0; i < 4; i++) {
00088               if (tp->flgs & LFF(i) && dpth2[i] <= d2) {
00089                      cp = qtL.rgb[tp->k[i].li];
00090                      csm[0] += cp[0]; csm[1] += cp[1]; csm[2] += cp[2];
00091                      nc++;
00092                      if (tp->flgs & CHF(i))
00093                             dev_paintr(cp, i&01 ? mx : x0, i&02 ? my : y0,
00094                                           i&01 ? x1 : mx, i&02 ? y1 : my);
00095               } else if ((tp->flgs & CHBRF(i)) == CHF(i))
00096                      gaps |= 1<<i; /* empty stem */
00097        }
00098                                    /* do branches */
00099        for (i = 0; i < 4; i++)
00100               if ((tp->flgs & CHBRF(i)) == CHBRF(i)) {
00101                      update(rgb, tp->k[i].b, i&01 ? mx : x0, i&02 ? my : y0,
00102                                    i&01 ? x1 : mx, i&02 ? y1 : my);
00103                      csm[0] += rgb[0]; csm[1] += rgb[1]; csm[2] += rgb[2];
00104                      nc++;
00105               }
00106        if (nc > 1) {
00107               ca[0] = csm[0]/nc; ca[1] = csm[1]/nc; ca[2] = csm[2]/nc;
00108        } else {
00109               ca[0] = csm[0]; ca[1] = csm[1]; ca[2] = csm[2];
00110        }
00111                                    /* fill in gaps with average */
00112        for (i = 0; gaps && i < 4; gaps >>= 1, i++)
00113               if (gaps & 01)
00114                      dev_paintr(ca, i&01 ? mx : x0, i&02 ? my : y0,
00115                                    i&01 ? x1 : mx, i&02 ? y1 : my);
00116        tp->flgs &= ~CH_ANY;        /* all done */
00117 }
00118 
00119 
00120 extern void
00121 qtRedraw(     /* redraw part or all of our screen */
00122        int    x0,
00123        int    y0,
00124        int    x1,
00125        int    y1
00126 )
00127 {
00128        int    lim[2][2];
00129 
00130        if (is_stump(&qtrunk))
00131               return;
00132        if (!qtMapLeaves(((lim[0][0]=x0) <= 0) & ((lim[1][0]=y0) <= 0) &
00133               ((lim[0][1]=x1) >= odev.hres-1) & ((lim[1][1]=y1) >= odev.vres-1)))
00134               return;
00135        redraw(&qtrunk, 0, 0, odev.hres, odev.vres, lim);
00136 }
00137 
00138 
00139 extern void
00140 qtUpdate(void)                     /* update our tree display */
00141 {
00142        BYTE   ca[3];
00143 
00144        if (is_stump(&qtrunk))
00145               return;
00146        if (!qtMapLeaves(0))
00147               return;
00148        update(ca, &qtrunk, 0, 0, odev.hres, odev.vres);
00149 }