Back to index

radiance  4R0+20100331
viewbeams.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: viewbeams.c,v 3.7 2004/01/01 11:21:55 schorsch Exp $";
00003 #endif
00004 /*
00005  * Convert view to beam list.
00006  */
00007 
00008 #include <string.h>
00009 
00010 #include "rholo.h"
00011 #include "view.h"
00012 #include "random.h"
00013 
00014 #ifndef MINRES
00015 #define MINRES              12            /* section sample resolution */
00016 #endif
00017 #ifndef NVSAMPS
00018 #define NVSAMPS             16384         /* target number of view samples */
00019 #endif
00020 
00021 #define OJITTER             0.25          /* amount to jitter sample origin */
00022 
00023 #define BALLOCBLK    128           /* beam allocation block size */
00024 
00025 
00026 static BEAMLIST      blist;
00027 
00028 
00029 static void
00030 add2blist(                  /* add to beam sample list */
00031        int    hd,
00032        int    bi,
00033        int    nr
00034 )
00035 {
00036        register int  i;
00037 
00038        for (i = blist.nb; i--; )
00039               if (blist.bl[i].bi == bi && blist.bl[i].hd == hd) {
00040                      blist.bl[i].nr += nr;       /* found it */
00041                      return;
00042               }
00043        i = blist.nb++;                           /* else add beam to list */
00044        if (i % BALLOCBLK == 0) {
00045               blist.bl = (PACKHEAD *)realloc((void *)blist.bl,
00046                             (i+BALLOCBLK)*sizeof(PACKHEAD));
00047               CHECK(blist.bl==NULL, SYSTEM, "out of memory in add2blist");
00048        }
00049        blist.bl[i].hd = hd; blist.bl[i].bi = bi;
00050        blist.bl[i].nr = nr; blist.bl[i].nc = 0;
00051 }
00052 
00053 
00054 extern int16 *
00055 viewbeams(           /* convert view into sections/beams */
00056        VIEW   *vp,
00057        int    hr,
00058        int    vr,
00059        BEAMLIST      *blp
00060 )
00061 {
00062        static int16  sectlist[HDMAX+1];
00063        int16  sectarr[MINRES+1][MINRES+1];
00064        double d0, d1, mindist;
00065        GCOORD gc[2];
00066        FVECT  rorg, rdir;
00067        int    shr, svr, sampquant;
00068        int    v;
00069        register int  h, hd;
00070                                           /* clear section flags */
00071        memset((char *)sectlist, '\0', sizeof(sectlist));
00072                                           /* identify view sections */
00073        for (v = 0; v <= MINRES; v++)
00074               for (h = 0; h <= MINRES; h++) {
00075                      sectarr[v][h] = -1;
00076                      mindist = 0.99*FHUGE;
00077                      if (viewray(rorg, rdir, vp, (double)h/MINRES,
00078                                    (double)v/MINRES) < -FTINY)
00079                             continue;
00080                      for (hd = 0; hdlist[hd] != NULL; hd++) {
00081                             d0 = hdinter(gc, NULL, &d1,
00082                                           hdlist[hd], rorg, rdir);
00083                             if (d0 >= 0.99*FHUGE)
00084                                    continue;            /* missed */
00085                             if (d0 <= 0. && d1 >= 0.) {
00086                                    sectarr[v][h] = hd;
00087                                    break;               /* inside */
00088                             }
00089                             if (d0 > 0. && d0 < mindist) {
00090                                    sectarr[v][h] = hd;
00091                                    mindist = d0;
00092                             } else if (d1 < 0. && -d1 < mindist) {
00093                                    sectarr[v][h] = hd;
00094                                    mindist = -d1;
00095                             }
00096                      }
00097                      if ((hd = sectarr[v][h]) >= 0)
00098                             sectlist[hd]++;             /* flag section */
00099               }
00100                                           /* convert flags to list */
00101        for (h = hd = 0; hdlist[hd] != NULL; h++, hd++) {
00102               while (!sectlist[hd])
00103                      if (hdlist[++hd] == NULL)
00104                             goto loopexit;
00105               sectlist[h] = hd;
00106        }
00107 loopexit:
00108        sectlist[h] = -1;                  /* list terminator */
00109        if (blp == NULL)                   /* if no beam list... */
00110               return(sectlist);                  /* return early */
00111                                           /* else set up sampling */
00112        if (hr|vr && hr*vr <= NVSAMPS) {
00113               shr = hr; svr = vr;
00114               sampquant = 1;
00115        } else {
00116               shr = sqrt(NVSAMPS/viewaspect(vp)) + .5;
00117               svr = (NVSAMPS + shr/2)/shr;
00118               sampquant = (hr*vr + shr*svr/2)/(shr*svr);
00119        }
00120        blist.bl = NULL; blist.nb = 0;            /* sample view rays */
00121        for (v = svr; v--; )
00122               for (h = shr; h--; ) {
00123                      hd = random()>>6 & 03;             /* get section */
00124                      hd = sectarr[v*MINRES/svr + (hd&01)]
00125                                    [h*MINRES/shr + (hd>>1)];
00126                      if (hd < 0)
00127                             continue;
00128                                                  /* get sample ray */
00129                      if (viewray(rorg, rdir, vp, (h+frandom())/shr,
00130                                    (v+frandom())/svr) < -FTINY)
00131                             continue;
00132 #ifdef OJITTER
00133                                                  /* jitter origin */
00134                      d0 = OJITTER*(frandom() - .5) / hdlist[hd]->grid[0];
00135                      VSUM(rorg, rorg, hdlist[hd]->xv[0], d0);
00136                      d0 = OJITTER*(frandom() - .5) / hdlist[hd]->grid[1];
00137                      VSUM(rorg, rorg, hdlist[hd]->xv[1], d0);
00138                      d0 = OJITTER*(frandom() - .5) / hdlist[hd]->grid[2];
00139                      VSUM(rorg, rorg, hdlist[hd]->xv[2], d0);
00140 #endif
00141                                                  /* intersect section */
00142                      if (hdinter(gc, NULL, NULL, hdlist[hd], rorg, rdir)
00143                                    >= 0.99*FHUGE)
00144                             continue;
00145                                                  /* add samples */
00146                      add2blist(hd, hdbindex(hdlist[hd],gc), sampquant);
00147               }
00148        *blp = blist;        /* transfer beam list */
00149        return(sectlist);                  /* all done! */
00150 }
00151 
00152 
00153 extern int
00154 nextview(                   /* get next view from fp */
00155        VIEW   *vp,
00156        FILE   *fp
00157 )
00158 {
00159        char   linebuf[256];
00160 
00161        while (fgets(linebuf, sizeof(linebuf), fp) != NULL)
00162               if (isview(linebuf) && sscanview(vp, linebuf) > 0)
00163                      return(0);
00164        return(EOF);
00165 }