ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo2.c
(Generate patch)

Comparing ray/src/hd/rholo2.c (file contents):
Revision 3.19 by gwlarson, Tue Dec 1 15:47:05 1998 UTC vs.
Revision 3.21 by gwlarson, Mon Dec 7 16:56:08 1998 UTC

# Line 19 | Line 19 | struct gclim {
19          HOLO    *hp;                    /* holodeck pointer */
20          GCOORD  gc;                     /* grid cell */
21          FVECT   egp;                    /* eye grid point */
22 <        double  erg[2];                 /* eye range in wall grid coords */
22 >        double  erg2;                   /* mean square eye grid range */
23          double  gmin[2], gmax[2];       /* grid coordinate limits */
24   };                              /* a grid coordinate range */
25  
26  
27   static
28 < initeyelim(gcl, hd, gc)         /* initialize grid coordinate limits */
28 > initeyelim(gcl, hp, gc)         /* initialize grid coordinate limits */
29   register struct gclim   *gcl;
30 < int     hd;
30 > register HOLO   *hp;
31   GCOORD  *gc;
32   {
33          register FLOAT  *v;
34          register int    i;
35  
36 <        gcl->hp = hdlist[hd];
37 <        copystruct(&gcl->gc, gc);
38 <        hdgrid(gcl->egp, gcl->hp, myeye.vpt);
39 <        for (i = 0; i < 2; i++) {
40 <                v = gcl->hp->wg[((gcl->gc.w>>1)+i+1)%3];
41 <                gcl->erg[i] = myeye.rng * VLEN(v);
42 <                gcl->gmin[i] = FHUGE; gcl->gmax[i] = -FHUGE;
36 >        if (hp != NULL) {
37 >                hdgrid(gcl->egp, gcl->hp = hp, myeye.vpt);
38 >                gcl->erg2 = 0;
39 >                for (i = 0, v = hp->wg[0]; i < 3; i++, v += 3)
40 >                        gcl->erg2 += DOT(v,v);
41 >                gcl->erg2 *= (1./3.) * myeye.rng*myeye.rng;
42          }
43 +        if (gc != NULL)
44 +                copystruct(&gcl->gc, gc);
45 +        gcl->gmin[0] = gcl->gmin[1] = FHUGE;
46 +        gcl->gmax[0] = gcl->gmax[1] = -FHUGE;
47   }
48  
49  
50   static
51 < groweyelim(gcl, gp)             /* grow grid limits about eye point */
51 > groweyelim(gcl, gc, r0, r1, tight)      /* grow grid limits about eye point */
52   register struct gclim   *gcl;
53 < FVECT   gp;
53 > GCOORD  *gc;
54 > double  r0, r1;
55 > int     tight;
56   {
57 <        FVECT   ab;
58 <        double  l2, d, mult, wg;
59 <        register int    i, g;
60 <
57 >        FVECT   gp, ab;
58 >        double  ab2, od, cfact;
59 >        double  sqcoef[3], ctcoef[3], licoef[3], cnst;
60 >        int     gw, gi[2];
61 >        double  wallpos, a, b, c, d, e, f;
62 >        double  root[2], yex;
63 >        int     n, i, j, nex;
64 >                                                /* point/view cone */
65 >        i = gc->w>>1;
66 >        gp[i] = gc->w&1 ? gcl->hp->grid[i] : 0;
67 >        gp[hdwg0[gc->w]] = gc->i[0] + r0;
68 >        gp[hdwg1[gc->w]] = gc->i[1] + r1;
69          VSUB(ab, gcl->egp, gp);
70 <        l2 = DOT(ab,ab);
71 <        if (l2 <= gcl->erg[0]*gcl->erg[1]) {
70 >        ab2 = DOT(ab, ab);
71 >        gw = gcl->gc.w>>1;
72 >        if ((i==gw ? ab[gw]*ab[gw] : ab2)  <= gcl->erg2 + FTINY) {
73                  gcl->gmin[0] = gcl->gmin[1] = -FHUGE;
74                  gcl->gmax[0] = gcl->gmax[1] = FHUGE;
75 <                return;
75 >                return;                 /* too close (to wall) */
76          }
77 <        mult = gp[g = gcl->gc.w>>1];
78 <        if (gcl->gc.w&1)
79 <                mult -= gcl->hp->grid[g];
80 <        if (ab[g]*ab[g] > gcl->erg[0]*gcl->erg[1])
81 <                mult /= -ab[g];
82 <        else if (fabs(ab[hdwg0[gcl->gc.w]]) > fabs(ab[hdwg1[gcl->gc.w]]))
83 <                mult = (gcl->gc.i[0] + .5 - gp[hdwg0[gcl->gc.w]]) /
84 <                                ab[hdwg0[gcl->gc.w]];
85 <        else
86 <                mult = (gcl->gc.i[1] + .5 - gp[hdwg1[gcl->gc.w]]) /
87 <                                ab[hdwg1[gcl->gc.w]];
77 >        ab2 = 1./ab2;                           /* 1/norm2(ab) */
78 >        od = DOT(gp, ab);                       /* origin dot direction */
79 >        cfact = 1./(1. - ab2*gcl->erg2);        /* tan^2 + 1 of cone angle */
80 >        for (i = 0; i < 3; i++) {               /* compute cone equation */
81 >                sqcoef[i] = ab[i]*ab[i]*cfact*ab2 - 1.;
82 >                ctcoef[i] = 2.*ab[i]*ab[(i+1)%3]*cfact*ab2;
83 >                licoef[i] = 2.*(gp[i] - ab[i]*cfact*od*ab2);
84 >        }
85 >        cnst = cfact*od*od*ab2 - DOT(gp,gp);
86 >        /*
87 >         * CONE:        sqcoef[0]*x*x + sqcoef[1]*y*y + sqcoef[2]*z*z
88 >         *              + ctcoef[0]*x*y + ctcoef[1]*y*z + ctcoef[2]*z*x
89 >         *              + licoef[0]*x + licoef[1]*y + licoef[2]*z + cnst == 0
90 >         */
91 >                                /* equation for conic section in plane */
92 >        gi[0] = hdwg0[gcl->gc.w];
93 >        gi[1] = hdwg1[gcl->gc.w];
94 >        wallpos = gcl->gc.w&1 ? gcl->hp->grid[gw] : 0;
95 >        a = sqcoef[gi[0]];                                      /* x2 */
96 >        b = ctcoef[gi[0]];                                      /* xy */
97 >        c = sqcoef[gi[1]];                                      /* y2 */
98 >        d = ctcoef[gw]*wallpos + licoef[gi[0]];                 /* x */
99 >        e = ctcoef[gi[1]]*wallpos + licoef[gi[1]];              /* y */
100 >        f = wallpos*(wallpos*sqcoef[gw] + licoef[gw]) + cnst;
101          for (i = 0; i < 2; i++) {
102 <                g = ((gcl->gc.w>>1)+i+1)%3;
103 <                wg = gp[g] + mult*ab[g];
104 <                d = mult*gcl->erg[i];
105 <                if (d < 0.) d = -d;
106 <                if (wg - d < gcl->gmin[i])
107 <                        gcl->gmin[i] = wg - d;
108 <                if (wg + d > gcl->gmax[i])
109 <                        gcl->gmax[i] = wg + d;
102 >                if (i) {                /* swap x and y coefficients */
103 >                        register double t;
104 >                        t = a; a = c; c = t;
105 >                        t = d; d = e; e = t;
106 >                }
107 >                nex = 0;                /* check global extrema */
108 >                n = quadratic(root, a*(4.*a*c-b*b), 2.*a*(2.*c*d-b*e),
109 >                                d*(c*d-b*e) + f*b*b);
110 >                while (n-- > 0) {
111 >                        if (gc->w>>1 == gi[i] &&
112 >                                        (gc->w&1) ^ root[n] < gp[gc->w>>1]) {
113 >                                if (gc->w&1)
114 >                                        gcl->gmin[i] = -FHUGE;
115 >                                else
116 >                                        gcl->gmax[i] = FHUGE;
117 >                                nex++;
118 >                                continue;               /* hyperbolic */
119 >                        }
120 >                        if (tight) {
121 >                                yex = (-2.*a*root[n] - d)/b;
122 >                                if (yex < gcl->gc.i[1-i] ||
123 >                                                yex > gcl->gc.i[1-i]+1)
124 >                                        continue;       /* outside cell */
125 >                        }
126 >                        if (root[n] < gcl->gmin[i])
127 >                                gcl->gmin[i] = root[n];
128 >                        if (root[n] > gcl->gmax[i])
129 >                                gcl->gmax[i] = root[n];
130 >                        nex++;
131 >                }
132 >                                        /* check local extrema */
133 >                for (j = nex < 2 ? 2 : 0; j--; ) {
134 >                        yex = gcl->gc.i[1-i] + j;
135 >                        n = quadratic(root, a, b*yex+d, yex*(yex*c+e)+f);
136 >                        while (n-- > 0) {
137 >                                if (gc->w>>1 == gi[i] &&
138 >                                        (gc->w&1) ^ root[n] < gp[gc->w>>1])
139 >                                        continue;
140 >                                if (root[n] < gcl->gmin[i])
141 >                                        gcl->gmin[i] = root[n];
142 >                                if (root[n] > gcl->gmax[i])
143 >                                        gcl->gmax[i] = root[n];
144 >                        }
145 >                }
146          }
147   }
148  
# Line 97 | Line 160 | register struct gclim  *gcl;
160                          gcl->gmin[i] = gcl->gc.i[i];
161                  if (gcl->gmax[i] > gcl->gc.i[i]+1)
162                          gcl->gmax[i] = gcl->gc.i[i]+1;
163 <                if ((incell &= gcl->gmax[i] > gcl->gmin[i])) {
163 >                if (gcl->gmax[i] > gcl->gmin[i]) {
164                          rrng[i][0] = 256.*(gcl->gmin[i] - gcl->gc.i[i]) +
165                                          (1.-FTINY);
166                          rrng[i][1] = 256.*(gcl->gmax[i] - gcl->gc.i[i]) +
167                                          (1.-FTINY) - rrng[i][0];
168 <                        incell &= rrng[i][1] > 0;
169 <                }
168 >                } else
169 >                        rrng[i][0] = rrng[i][1] = 0;
170 >                incell &= rrng[i][1] > 0;
171          }
172          return(incell);
173   }
# Line 113 | Line 177 | packrays(rod, p)               /* pack ray origins and directions *
177   register float  *rod;
178   register PACKET *p;
179   {
180 < #define gp      ro
181 < #ifdef DEBUG
118 <        double dist2sum = 0.;
180 > #if 0
181 >        double  dist2sum = 0.;
182          FVECT   vt;
183   #endif
184          int     nretries = p->nr + 2;
# Line 130 | Line 193 | register PACKET        *p;
193          if (!hdbcoord(gc, hdlist[p->hd], p->bi))
194                  error(CONSISTENCY, "bad beam index in packrays");
195          if ((useyelim = myeye.rng > FTINY)) {
196 <                initeyelim(&eyelim, p->hd, gc);
197 <                gp[gc[1].w>>1] = gc[1].w&1 ?
198 <                                hdlist[p->hd]->grid[gc[1].w>>1] : 0;
199 <                gp[hdwg0[gc[1].w]] = gc[1].i[0];
200 <                gp[hdwg1[gc[1].w]] = gc[1].i[1];
201 <                groweyelim(&eyelim, gp);
202 <                gp[hdwg0[gc[1].w]]++;
203 <                gp[hdwg1[gc[1].w]]++;
141 <                groweyelim(&eyelim, gp);
142 <                useyelim &= clipeyelim(rrng0, &eyelim);
196 >                initeyelim(&eyelim, hdlist[p->hd], gc);
197 >                groweyelim(&eyelim, gc+1, 0., 0., 0);
198 >                groweyelim(&eyelim, gc+1, 1., 1., 0);
199 >                useyelim = clipeyelim(rrng0, &eyelim);
200 > #ifdef DEBUG
201 >                if (!useyelim)
202 >                        error(WARNING, "no eye overlap in packrays");
203 > #endif
204          }
205          for (i = 0; i < p->nr; i++) {
206          retry:
207                  if (useyelim) {
208 +                        initeyelim(&eyelim, NULL, gc+1);
209                          p->ra[i].r[0][0] = (int)(frandom()*rrng0[0][1])
210                                                  + rrng0[0][0];
211                          p->ra[i].r[0][1] = (int)(frandom()*rrng0[1][1])
212                                                  + rrng0[1][0];
213 <                        initeyelim(&eyelim, p->hd, gc+1);
214 <                        gp[gc[0].w>>1] = gc[0].w&1 ?
215 <                                        hdlist[p->hd]->grid[gc[0].w>>1] : 0;
154 <                        gp[hdwg0[gc[0].w]] = gc[0].i[0] +
155 <                                        (1./256.)*(p->ra[i].r[0][0]+.5);
156 <                        gp[hdwg1[gc[0].w]] = gc[0].i[1] +
157 <                                        (1./256.)*(p->ra[i].r[0][1]+.5);
158 <                        groweyelim(&eyelim, gp);
213 >                        groweyelim(&eyelim, gc,
214 >                                        (1./256.)*(p->ra[i].r[0][0]+.5),
215 >                                        (1./256.)*(p->ra[i].r[0][1]+.5), 1);
216                          if (!clipeyelim(rrng1, &eyelim)) {
217 <                                useyelim &= nretries-- > 0;
217 >                                useyelim = nretries-- > 0;
218   #ifdef DEBUG
219                                  if (!useyelim)
220 <                                        error(WARNING, "exceeded retry limit in packrays");
220 >                                        error(WARNING,
221 >                                        "exceeded retry limit in packrays");
222   #endif
223                                  goto retry;
224                          }
# Line 175 | Line 233 | register PACKET        *p;
233                          p->ra[i].r[1][1] = frandom() * 256.;
234                  }
235                  d = hdray(ro, rd, hdlist[p->hd], gc, p->ra[i].r);
236 < #ifdef DEBUG
236 > #if 0
237                  VSUM(vt, ro, rd, d);
238                  dist2sum += dist2line(myeye.vpt, ro, vt);
239   #endif
# Line 190 | Line 248 | register PACKET        *p;
248                  VCOPY(rod, rd);
249                  rod += 3;
250          }
251 < #ifdef DEBUG
252 <        fprintf(stderr, "RMS distance = %f\n", sqrt(dist2sum/p->nr));
251 > #if 0
252 >        fprintf(stderr, "%f RMS (%d retries)\t", sqrt(dist2sum/p->nr),
253 >                        p->nr + 2 - nretries);
254   #endif
196 #undef gp
255   }
256  
257  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines