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.20 by gwlarson, Thu Dec 3 15:21:05 1998 UTC vs.
Revision 3.25 by greg, Mon Jul 7 17:21:51 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Rtrace support routines for holodeck rendering
6   */
# Line 30 | Line 27 | register struct gclim  *gcl;
27   register HOLO   *hp;
28   GCOORD  *gc;
29   {
30 <        register FLOAT  *v;
30 >        register RREAL  *v;
31          register int    i;
32  
33          if (hp != NULL) {
# Line 48 | Line 45 | GCOORD *gc;
45  
46  
47   static
48 < groweyelim(gcl, gc, r0, r1)     /* grow grid limits about eye point */
48 > groweyelim(gcl, gc, r0, r1, tight)      /* grow grid limits about eye point */
49   register struct gclim   *gcl;
50   GCOORD  *gc;
51   double  r0, r1;
52 + int     tight;
53   {
54          FVECT   gp, ab;
55 <        double  vlen, plen, dv0, dv1;
56 <        double  rd2, dwall, gpos;
57 <        int     eyeout;
58 <        register int    i, g0, g1;
59 <
55 >        double  ab2, od, cfact;
56 >        double  sqcoef[3], ctcoef[3], licoef[3], cnst;
57 >        int     gw, gi[2];
58 >        double  wallpos, a, b, c, d, e, f;
59 >        double  root[2], yex;
60 >        int     n, i, j, nex;
61 >                                                /* point/view cone */
62          i = gc->w>>1;
63 <        if (gc->w&1)
64 <                eyeout = (gp[i] = gcl->hp->grid[i]) < gcl->egp[i];
65 <        else
66 <                eyeout = (gp[i] = 0) > gcl->egp[i];
63 >        gp[i] = gc->w&1 ? gcl->hp->grid[i] : 0;
64          gp[hdwg0[gc->w]] = gc->i[0] + r0;
65          gp[hdwg1[gc->w]] = gc->i[1] + r1;
66          VSUB(ab, gcl->egp, gp);
67 <        rd2 = DOT(ab,ab);
68 <        if (rd2 <= gcl->erg2) {
67 >        ab2 = DOT(ab, ab);
68 >        gw = gcl->gc.w>>1;
69 >        if ((i==gw ? ab[gw]*ab[gw] : ab2)  <= gcl->erg2 + FTINY) {
70                  gcl->gmin[0] = gcl->gmin[1] = -FHUGE;
71                  gcl->gmax[0] = gcl->gmax[1] = FHUGE;
72 <                return;
72 >                return;                 /* too close (to wall) */
73          }
74 <        rd2 = gcl->erg2 / rd2;
75 <        vlen = 1. - rd2;
76 <        plen = sqrt(rd2 * vlen);
77 <        g0 = gcl->gc.w>>1;
78 <        dwall = (gcl->gc.w&1 ? gcl->hp->grid[g0] : 0) - gp[g0];
79 <        for (i = 0; i < 4; i++) {
80 <                if (i == 2)
81 <                        plen = -plen;
82 <                g1 = (g0+(i&1)+1)%3;
83 <                dv0 = vlen*ab[g0] + plen*ab[g1];
84 <                dv1 = vlen*ab[g1] - plen*ab[g0];
85 <                if ((dv0 < 0 ^ dwall < 0 ^ eyeout) ||
86 <                                (dv0 <= FTINY && dv0 >= -FTINY)) {
87 <                        if (eyeout)
88 <                                dv1 = -dv1;
89 <                        if (dv1 > FTINY)
90 <                                gcl->gmax[i&1] = FHUGE;
91 <                        else if (dv1 < -FTINY)
92 <                                gcl->gmin[i&1] = -FHUGE;
93 <                } else {
94 <                        gpos = gp[g1] + dv1*dwall/dv0;
95 <                        if (gpos < gcl->gmin[i&1])
96 <                                gcl->gmin[i&1] = gpos;
97 <                        if (gpos > gcl->gmax[i&1])
98 <                                gcl->gmax[i&1] = gpos;
74 >        ab2 = 1./ab2;                           /* 1/norm2(ab) */
75 >        od = DOT(gp, ab);                       /* origin dot direction */
76 >        cfact = 1./(1. - ab2*gcl->erg2);        /* tan^2 + 1 of cone angle */
77 >        for (i = 0; i < 3; i++) {               /* compute cone equation */
78 >                sqcoef[i] = ab[i]*ab[i]*cfact*ab2 - 1.;
79 >                ctcoef[i] = 2.*ab[i]*ab[(i+1)%3]*cfact*ab2;
80 >                licoef[i] = 2.*(gp[i] - ab[i]*cfact*od*ab2);
81 >        }
82 >        cnst = cfact*od*od*ab2 - DOT(gp,gp);
83 >        /*
84 >         * CONE:        sqcoef[0]*x*x + sqcoef[1]*y*y + sqcoef[2]*z*z
85 >         *              + ctcoef[0]*x*y + ctcoef[1]*y*z + ctcoef[2]*z*x
86 >         *              + licoef[0]*x + licoef[1]*y + licoef[2]*z + cnst == 0
87 >         */
88 >                                /* equation for conic section in plane */
89 >        gi[0] = hdwg0[gcl->gc.w];
90 >        gi[1] = hdwg1[gcl->gc.w];
91 >        wallpos = gcl->gc.w&1 ? gcl->hp->grid[gw] : 0;
92 >        a = sqcoef[gi[0]];                                      /* x2 */
93 >        b = ctcoef[gi[0]];                                      /* xy */
94 >        c = sqcoef[gi[1]];                                      /* y2 */
95 >        d = ctcoef[gw]*wallpos + licoef[gi[0]];                 /* x */
96 >        e = ctcoef[gi[1]]*wallpos + licoef[gi[1]];              /* y */
97 >        f = wallpos*(wallpos*sqcoef[gw] + licoef[gw]) + cnst;
98 >        for (i = 0; i < 2; i++) {
99 >                if (i) {                /* swap x and y coefficients */
100 >                        register double t;
101 >                        t = a; a = c; c = t;
102 >                        t = d; d = e; e = t;
103                  }
104 +                nex = 0;                /* check global extrema */
105 +                n = quadratic(root, a*(4.*a*c-b*b), 2.*a*(2.*c*d-b*e),
106 +                                d*(c*d-b*e) + f*b*b);
107 +                while (n-- > 0) {
108 +                        if (gc->w>>1 == gi[i] &&
109 +                                        (gc->w&1) ^ root[n] < gp[gc->w>>1]) {
110 +                                if (gc->w&1)
111 +                                        gcl->gmin[i] = -FHUGE;
112 +                                else
113 +                                        gcl->gmax[i] = FHUGE;
114 +                                nex++;
115 +                                continue;               /* hyperbolic */
116 +                        }
117 +                        if (tight) {
118 +                                yex = (-2.*a*root[n] - d)/b;
119 +                                if (yex < gcl->gc.i[1-i] ||
120 +                                                yex > gcl->gc.i[1-i]+1)
121 +                                        continue;       /* outside cell */
122 +                        }
123 +                        if (root[n] < gcl->gmin[i])
124 +                                gcl->gmin[i] = root[n];
125 +                        if (root[n] > gcl->gmax[i])
126 +                                gcl->gmax[i] = root[n];
127 +                        nex++;
128 +                }
129 +                                        /* check local extrema */
130 +                for (j = nex < 2 ? 2 : 0; j--; ) {
131 +                        yex = gcl->gc.i[1-i] + j;
132 +                        n = quadratic(root, a, b*yex+d, yex*(yex*c+e)+f);
133 +                        while (n-- > 0) {
134 +                                if (gc->w>>1 == gi[i] &&
135 +                                        (gc->w&1) ^ root[n] < gp[gc->w>>1])
136 +                                        continue;
137 +                                if (root[n] < gcl->gmin[i])
138 +                                        gcl->gmin[i] = root[n];
139 +                                if (root[n] > gcl->gmax[i])
140 +                                        gcl->gmax[i] = root[n];
141 +                        }
142 +                }
143          }
144   }
145  
# Line 133 | Line 174 | packrays(rod, p)               /* pack ray origins and directions *
174   register float  *rod;
175   register PACKET *p;
176   {
177 + #if 0
178 +        double  dist2sum = 0.;
179 +        FVECT   vt;
180 + #endif
181          int     nretries = p->nr + 2;
182          struct gclim    eyelim;
183          short   rrng0[2][2], rrng1[2][2];
# Line 146 | Line 191 | register PACKET        *p;
191                  error(CONSISTENCY, "bad beam index in packrays");
192          if ((useyelim = myeye.rng > FTINY)) {
193                  initeyelim(&eyelim, hdlist[p->hd], gc);
194 <                groweyelim(&eyelim, gc+1, 0., 0.);
195 <                groweyelim(&eyelim, gc+1, 1., 1.);
196 <                useyelim &= clipeyelim(rrng0, &eyelim);
194 >                groweyelim(&eyelim, gc+1, 0., 0., 0);
195 >                groweyelim(&eyelim, gc+1, 1., 1., 0);
196 >                useyelim = clipeyelim(rrng0, &eyelim);
197 > #ifdef DEBUG
198 >                if (!useyelim)
199 >                        error(WARNING, "no eye overlap in packrays");
200 > #endif
201          }
202          for (i = 0; i < p->nr; i++) {
203          retry:
# Line 160 | Line 209 | register PACKET        *p;
209                                                  + rrng0[1][0];
210                          groweyelim(&eyelim, gc,
211                                          (1./256.)*(p->ra[i].r[0][0]+.5),
212 <                                        (1./256.)*(p->ra[i].r[0][1]+.5));
212 >                                        (1./256.)*(p->ra[i].r[0][1]+.5), 1);
213                          if (!clipeyelim(rrng1, &eyelim)) {
214 <                                useyelim &= nretries-- > 0;
214 >                                useyelim = nretries-- > 0;
215 > #ifdef DEBUG
216 >                                if (!useyelim)
217 >                                        error(WARNING,
218 >                                        "exceeded retry limit in packrays");
219 > #endif
220                                  goto retry;
221                          }
222                          p->ra[i].r[1][0] = (int)(frandom()*rrng1[0][1])
# Line 176 | Line 230 | register PACKET        *p;
230                          p->ra[i].r[1][1] = frandom() * 256.;
231                  }
232                  d = hdray(ro, rd, hdlist[p->hd], gc, p->ra[i].r);
233 + #if 0
234 +                VSUM(vt, ro, rd, d);
235 +                dist2sum += dist2line(myeye.vpt, ro, vt);
236 + #endif
237                  if (p->offset != NULL) {
238                          if (!vdef(OBSTRUCTIONS))
239                                  d *= frandom();         /* random offset */
# Line 187 | Line 245 | register PACKET        *p;
245                  VCOPY(rod, rd);
246                  rod += 3;
247          }
248 + #if 0
249 +        fprintf(stderr, "%f RMS (%d retries)\t", sqrt(dist2sum/p->nr),
250 +                        p->nr + 2 - nretries);
251 + #endif
252   }
253  
254  
# Line 215 | Line 277 | done_rtrace()                  /* clean up and close rtrace calculati
277          int     status;
278                                          /* already closed? */
279          if (!nprocs)
280 <                return;
280 >                return(0);
281                                          /* flush beam queue */
282          done_packets(flush_queue());
283                                          /* sync holodeck */
# Line 286 | Line 348 | getradfile()                   /* run rad and get needed variables */
348                          pippt = NULL;
349                  }
350          if (pippt != NULL)
351 <                strcpy(pippt, "> /dev/null");   /* nothing to match */
351 >                strcpy(pippt, "> " NULL_DEVICE);        /* nothing to match */
352          else
353                  sprintf(cp, ")[ \t]*=' > %s", tf2);
354   #ifdef DEBUG

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines