| 1 |
gwlarson |
3.1 |
#ifndef lint
|
| 2 |
greg |
3.2 |
static const char RCSid[] = "$Id$";
|
| 3 |
gwlarson |
3.1 |
#endif
|
| 4 |
|
|
/*
|
| 5 |
|
|
* Convert view to beam list.
|
| 6 |
|
|
*/
|
| 7 |
|
|
|
| 8 |
|
|
#include "rholo.h"
|
| 9 |
|
|
#include "view.h"
|
| 10 |
|
|
#include "random.h"
|
| 11 |
|
|
|
| 12 |
|
|
#ifndef MINRES
|
| 13 |
|
|
#define MINRES 12 /* section sample resolution */
|
| 14 |
|
|
#endif
|
| 15 |
|
|
#ifndef NVSAMPS
|
| 16 |
|
|
#define NVSAMPS 16384 /* target number of view samples */
|
| 17 |
|
|
#endif
|
| 18 |
|
|
|
| 19 |
|
|
#define OJITTER 0.25 /* amount to jitter sample origin */
|
| 20 |
|
|
|
| 21 |
|
|
#define BALLOCBLK 128 /* beam allocation block size */
|
| 22 |
|
|
|
| 23 |
|
|
|
| 24 |
|
|
static BEAMLIST blist;
|
| 25 |
|
|
|
| 26 |
|
|
|
| 27 |
|
|
static
|
| 28 |
|
|
add2blist(hd, bi, nr) /* add to beam sample list */
|
| 29 |
|
|
int hd, bi, nr;
|
| 30 |
|
|
{
|
| 31 |
|
|
register int i;
|
| 32 |
|
|
|
| 33 |
|
|
for (i = blist.nb; i--; )
|
| 34 |
|
|
if (blist.bl[i].bi == bi && blist.bl[i].hd == hd) {
|
| 35 |
|
|
blist.bl[i].nr += nr; /* found it */
|
| 36 |
|
|
return;
|
| 37 |
|
|
}
|
| 38 |
|
|
i = blist.nb++; /* else add beam to list */
|
| 39 |
|
|
if (i % BALLOCBLK == 0) {
|
| 40 |
|
|
blist.bl = (PACKHEAD *)realloc((char *)blist.bl,
|
| 41 |
|
|
(i+BALLOCBLK)*sizeof(PACKHEAD));
|
| 42 |
|
|
CHECK(blist.bl==NULL, SYSTEM, "out of memory in add2blist");
|
| 43 |
|
|
}
|
| 44 |
|
|
blist.bl[i].hd = hd; blist.bl[i].bi = bi;
|
| 45 |
|
|
blist.bl[i].nr = nr; blist.bl[i].nc = 0;
|
| 46 |
|
|
}
|
| 47 |
|
|
|
| 48 |
|
|
|
| 49 |
|
|
int2 *
|
| 50 |
|
|
viewbeams(vp, hr, vr, blp) /* convert view into sections/beams */
|
| 51 |
|
|
VIEW *vp;
|
| 52 |
|
|
int hr, vr;
|
| 53 |
|
|
BEAMLIST *blp;
|
| 54 |
|
|
{
|
| 55 |
|
|
static int2 sectlist[HDMAX+1];
|
| 56 |
|
|
int2 sectarr[MINRES+1][MINRES+1];
|
| 57 |
|
|
double d0, d1, mindist;
|
| 58 |
|
|
GCOORD gc[2];
|
| 59 |
|
|
FVECT rorg, rdir;
|
| 60 |
|
|
int shr, svr, sampquant;
|
| 61 |
|
|
int v;
|
| 62 |
|
|
register int h, hd;
|
| 63 |
|
|
/* clear section flags */
|
| 64 |
|
|
bzero((char *)sectlist, sizeof(sectlist));
|
| 65 |
|
|
/* identify view sections */
|
| 66 |
|
|
for (v = 0; v <= MINRES; v++)
|
| 67 |
|
|
for (h = 0; h <= MINRES; h++) {
|
| 68 |
|
|
sectarr[v][h] = -1;
|
| 69 |
|
|
mindist = 0.99*FHUGE;
|
| 70 |
|
|
if (viewray(rorg, rdir, vp, (double)h/MINRES,
|
| 71 |
|
|
(double)v/MINRES) < -FTINY)
|
| 72 |
|
|
continue;
|
| 73 |
|
|
for (hd = 0; hdlist[hd] != NULL; hd++) {
|
| 74 |
|
|
d0 = hdinter(gc, NULL, &d1,
|
| 75 |
|
|
hdlist[hd], rorg, rdir);
|
| 76 |
|
|
if (d0 >= 0.99*FHUGE)
|
| 77 |
|
|
continue; /* missed */
|
| 78 |
|
|
if (d0 <= 0. && d1 >= 0.) {
|
| 79 |
|
|
sectarr[v][h] = hd;
|
| 80 |
|
|
break; /* inside */
|
| 81 |
|
|
}
|
| 82 |
|
|
if (d0 > 0. && d0 < mindist) {
|
| 83 |
|
|
sectarr[v][h] = hd;
|
| 84 |
|
|
mindist = d0;
|
| 85 |
|
|
} else if (d1 < 0. && -d1 < mindist) {
|
| 86 |
|
|
sectarr[v][h] = hd;
|
| 87 |
|
|
mindist = -d1;
|
| 88 |
|
|
}
|
| 89 |
|
|
}
|
| 90 |
|
|
if ((hd = sectarr[v][h]) >= 0)
|
| 91 |
|
|
sectlist[hd]++; /* flag section */
|
| 92 |
|
|
}
|
| 93 |
|
|
/* convert flags to list */
|
| 94 |
|
|
for (h = hd = 0; hdlist[hd] != NULL; h++, hd++) {
|
| 95 |
|
|
while (!sectlist[hd])
|
| 96 |
|
|
if (hdlist[++hd] == NULL)
|
| 97 |
|
|
goto loopexit;
|
| 98 |
|
|
sectlist[h] = hd;
|
| 99 |
|
|
}
|
| 100 |
|
|
loopexit:
|
| 101 |
|
|
sectlist[h] = -1; /* list terminator */
|
| 102 |
|
|
if (blp == NULL) /* if no beam list... */
|
| 103 |
|
|
return(sectlist); /* return early */
|
| 104 |
|
|
/* else set up sampling */
|
| 105 |
|
|
if (hr|vr && hr*vr <= NVSAMPS) {
|
| 106 |
|
|
shr = hr; svr = vr;
|
| 107 |
|
|
sampquant = 1;
|
| 108 |
|
|
} else {
|
| 109 |
|
|
shr = sqrt(NVSAMPS/viewaspect(vp)) + .5;
|
| 110 |
|
|
svr = (NVSAMPS + shr/2)/shr;
|
| 111 |
|
|
sampquant = (hr*vr + shr*svr/2)/(shr*svr);
|
| 112 |
|
|
}
|
| 113 |
|
|
blist.bl = NULL; blist.nb = 0; /* sample view rays */
|
| 114 |
|
|
for (v = svr; v--; )
|
| 115 |
|
|
for (h = shr; h--; ) {
|
| 116 |
|
|
hd = random()>>6 & 03; /* get section */
|
| 117 |
|
|
hd = sectarr[v*MINRES/svr + (hd&01)]
|
| 118 |
|
|
[h*MINRES/shr + (hd>>1)];
|
| 119 |
|
|
if (hd < 0)
|
| 120 |
|
|
continue;
|
| 121 |
|
|
/* get sample ray */
|
| 122 |
|
|
if (viewray(rorg, rdir, vp, (h+frandom())/shr,
|
| 123 |
|
|
(v+frandom())/svr) < -FTINY)
|
| 124 |
|
|
continue;
|
| 125 |
|
|
#ifdef OJITTER
|
| 126 |
|
|
/* jitter origin */
|
| 127 |
|
|
d0 = OJITTER*(frandom() - .5) / hdlist[hd]->grid[0];
|
| 128 |
|
|
VSUM(rorg, rorg, hdlist[hd]->xv[0], d0);
|
| 129 |
|
|
d0 = OJITTER*(frandom() - .5) / hdlist[hd]->grid[1];
|
| 130 |
|
|
VSUM(rorg, rorg, hdlist[hd]->xv[1], d0);
|
| 131 |
|
|
d0 = OJITTER*(frandom() - .5) / hdlist[hd]->grid[2];
|
| 132 |
|
|
VSUM(rorg, rorg, hdlist[hd]->xv[2], d0);
|
| 133 |
|
|
#endif
|
| 134 |
|
|
/* intersect section */
|
| 135 |
|
|
if (hdinter(gc, NULL, NULL, hdlist[hd], rorg, rdir)
|
| 136 |
|
|
>= 0.99*FHUGE)
|
| 137 |
|
|
continue;
|
| 138 |
|
|
/* add samples */
|
| 139 |
|
|
add2blist(hd, hdbindex(hdlist[hd],gc), sampquant);
|
| 140 |
|
|
}
|
| 141 |
|
|
copystruct(blp, &blist); /* transfer beam list */
|
| 142 |
|
|
return(sectlist); /* all done! */
|
| 143 |
|
|
}
|
| 144 |
|
|
|
| 145 |
|
|
|
| 146 |
|
|
int
|
| 147 |
|
|
nextview(vp, fp) /* get next view from fp */
|
| 148 |
|
|
VIEW *vp;
|
| 149 |
|
|
FILE *fp;
|
| 150 |
|
|
{
|
| 151 |
|
|
char linebuf[256];
|
| 152 |
|
|
|
| 153 |
|
|
while (fgets(linebuf, sizeof(linebuf), fp) != NULL)
|
| 154 |
|
|
if (isview(linebuf) && sscanview(vp, linebuf) > 0)
|
| 155 |
|
|
return(0);
|
| 156 |
|
|
return(EOF);
|
| 157 |
|
|
}
|