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

Comparing ray/src/hd/rhdisp3.c (file contents):
Revision 3.2 by gregl, Thu Nov 20 14:21:41 1997 UTC vs.
Revision 3.7 by gregl, Wed Nov 26 20:12:19 1997 UTC

# Line 12 | Line 12 | static char SCCSid[] = "$SunId$ SGI";
12   #include "rhdisp.h"
13   #include "view.h"
14  
15 + struct cellist {
16 +        GCOORD  *cl;
17 +        int     n;
18 + };
19  
20 +
21   int
22   npixels(vp, hr, vr, hp, bi)     /* compute appropriate number to evaluate */
23 < VIEW    *vp;
23 > register VIEW   *vp;
24   int     hr, vr;
25   HOLO    *hp;
26   int     bi;
27   {
28 +        VIEW    vrev;
29          GCOORD  gc[2];
30 <        FVECT   cp[4];
31 <        FVECT   ip[4];
26 <        double  d;
30 >        FVECT   cp[4], ip[4];
31 >        double  af, ab;
32          register int    i;
33                                          /* compute cell corners in image */
34          if (!hdbcoord(gc, hp, bi))
35                  error(CONSISTENCY, "bad beam index in npixels");
36 <        hdcell(cp, hp, gc+1);
36 >        hdcell(cp, hp, gc+1);           /* find cell on front image */
37          for (i = 0; i < 4; i++) {
38                  viewloc(ip[i], vp, cp[i]);
39 +                if (ip[i][2] < 0.) {
40 +                        af = 0;
41 +                        goto getback;
42 +                }
43 +                ip[i][0] *= (double)hr; /* scale by resolution */
44 +                ip[i][1] *= (double)vr;
45 +        }
46 +                                        /* compute front area */
47 +        af = (ip[1][0]-ip[0][0])*(ip[2][1]-ip[0][1]) -
48 +                (ip[2][0]-ip[0][0])*(ip[1][1]-ip[0][1]);
49 +        af += (ip[2][0]-ip[3][0])*(ip[1][1]-ip[3][1]) -
50 +                (ip[1][0]-ip[3][0])*(ip[2][1]-ip[3][1]);
51 +        if (af >= 0) af *= 0.5;
52 +        else af *= -0.5;
53 + getback:
54 +        copystruct(&vrev, vp);          /* compute reverse view */
55 +        for (i = 0; i < 3; i++) {
56 +                vrev.vdir[i] = -vp->vdir[i];
57 +                vrev.vup[i] = -vp->vup[i];
58 +                vrev.hvec[i] = -vp->hvec[i];
59 +                vrev.vvec[i] = -vp->vvec[i];
60 +        }
61 +        hdcell(cp, hp, gc);             /* find cell on back image */
62 +        for (i = 0; i < 4; i++) {
63 +                viewloc(ip[i], &vrev, cp[i]);
64                  if (ip[i][2] < 0.)
65 <                        return(0);
65 >                        return((int)(af + 0.5));
66                  ip[i][0] *= (double)hr; /* scale by resolution */
67                  ip[i][1] *= (double)vr;
68          }
69 <                                        /* compute quad area */
70 <        d = (ip[1][0]-ip[0][0])*(ip[2][1]-ip[0][1]) -
69 >                                        /* compute back area */
70 >        ab = (ip[1][0]-ip[0][0])*(ip[2][1]-ip[0][1]) -
71                  (ip[2][0]-ip[0][0])*(ip[1][1]-ip[0][1]);
72 <        d += (ip[2][0]-ip[3][0])*(ip[1][1]-ip[3][1]) -
72 >        ab += (ip[2][0]-ip[3][0])*(ip[1][1]-ip[3][1]) -
73                  (ip[1][0]-ip[3][0])*(ip[2][1]-ip[3][1]);
74 <        if (d < 0)
75 <                d = -d;
76 <                                        /* round off result */
77 <        return((int)(.5*d+.5));
74 >        if (ab >= 0) ab *= 0.5;
75 >        else ab *= -0.5;
76 >                                        /* round off smaller area */
77 >        if (af <= ab)
78 >                return((int)(af + 0.5));
79 >        return((int)(ab + 0.5));
80   }
81  
82  
# Line 102 | Line 134 | char   *dp;
134                                  } else if (d < -FTINY) {        /* plane -> */
135                                          if ((t /= d) > lbeg)
136                                                  lbeg = t;
137 <                                } else if (t < 0)               /* outside */
138 <                                        goto nextscan;
137 >                                } else if (t < 0) {             /* outside */
138 >                                        lend = -1;
139 >                                        break;
140 >                                }
141                          }
142 +                        if (lbeg >= lend)
143 +                                continue;
144                          i = lend + .5;          /* visit cells on this scan */
145                          for (gc.i[0] = lbeg + .5; gc.i[0] < i; gc.i[0]++)
146                                  n += (*vf)(&gc, dp);
111                nextscan:;
147                  }
148          }
149          return(n);
150   }
151  
152  
153 + sect_behind(hp, vp)             /* check if section is "behind" viewpoint */
154 + register HOLO   *hp;
155 + register VIEW   *vp;
156 + {
157 +        FVECT   hcent;
158 +                                        /* compute holodeck section center */
159 +        VSUM(hcent, hp->orig, hp->xv[0], 0.5);
160 +        VSUM(hcent, hcent, hp->xv[1], 0.5);
161 +        VSUM(hcent, hcent, hp->xv[2], 0.5);
162 +                                        /* behind if center is behind */
163 +        return(DOT(vp->vdir,hcent) < DOT(vp->vdir,vp->vp));
164 + }
165 +
166 +
167 + viewpyramid(org, dir, hp, vp)   /* compute view pyramid */
168 + FVECT   org, dir[4];
169 + HOLO    *hp;
170 + VIEW    *vp;
171 + {
172 +        register int    i;
173 +                                        /* check view type */
174 +        if (vp->type == VT_PAR)
175 +                return(0);
176 +                                        /* in front or behind? */
177 +        if (!sect_behind(hp, vp)) {
178 +                if (viewray(org, dir[0], vp, 0., 0.) < -FTINY)
179 +                        return(0);
180 +                if (viewray(org, dir[1], vp, 0., 1.) < -FTINY)
181 +                        return(0);
182 +                if (viewray(org, dir[2], vp, 1., 1.) < -FTINY)
183 +                        return(0);
184 +                if (viewray(org, dir[3], vp, 1., 0.) < -FTINY)
185 +                        return(0);
186 +                return(1);
187 +        }                               /* reverse pyramid */
188 +        if (viewray(org, dir[3], vp, 0., 0.) < -FTINY)
189 +                return(0);
190 +        if (viewray(org, dir[2], vp, 0., 1.) < -FTINY)
191 +                return(0);
192 +        if (viewray(org, dir[1], vp, 1., 1.) < -FTINY)
193 +                return(0);
194 +        if (viewray(org, dir[0], vp, 1., 0.) < -FTINY)
195 +                return(0);
196 +        for (i = 0; i < 3; i++) {
197 +                dir[0][i] = -dir[0][i];
198 +                dir[1][i] = -dir[1][i];
199 +                dir[2][i] = -dir[2][i];
200 +                dir[3][i] = -dir[3][i];
201 +        }
202 +        return(-1);
203 + }
204 +
205 +
206   int
207   addcell(gcp, cl)                /* add a cell to a list */
208   GCOORD  *gcp;
209 < register int    *cl;
209 > register struct cellist *cl;
210   {
211 <        copystruct((GCOORD *)(cl+1) + *cl, gcp);
212 <        (*cl)++;
211 >        copystruct(cl->cl+cl->n, gcp);
212 >        cl->n++;
213          return(1);
214   }
215  
# Line 140 | Line 228 | register GCOORD        *gcp1, *gcp2;
228   }
229  
230  
231 < int *
232 < getviewcells(hp, vp)            /* get ordered cell list for section view */
231 > GCOORD *
232 > getviewcells(np, hp, vp)        /* get ordered cell list for section view */
233 > int     *np;            /* returned number of cells (negative if reversed) */
234   register HOLO   *hp;
235   VIEW    *vp;
236   {
237          FVECT   org, dir[4];
238 <        int     n;
239 <        register int    *cl;
238 >        int     orient;
239 >        struct cellist  cl;
240                                          /* compute view pyramid */
241 <        if (vp->type == VT_PAR) goto viewerr;
242 <        if (viewray(org, dir[0], vp, 0., 0.) < -FTINY) goto viewerr;
243 <        if (viewray(org, dir[1], vp, 0., 1.) < -FTINY) goto viewerr;
244 <        if (viewray(org, dir[2], vp, 1., 1.) < -FTINY) goto viewerr;
156 <        if (viewray(org, dir[3], vp, 1., 0.) < -FTINY) goto viewerr;
241 >        *np = 0;
242 >        orient = viewpyramid(org, dir, hp, vp);
243 >        if (!orient)
244 >                return(NULL);
245                                          /* allocate enough list space */
246 <        n = 2*( hp->grid[0]*hp->grid[1] +
247 <                hp->grid[0]*hp->grid[2] +
248 <                hp->grid[1]*hp->grid[2] );
249 <        cl = (int *)malloc(sizeof(int) + n*sizeof(GCOORD));
250 <        if (cl == NULL)
246 >        cl.n = 2*(      hp->grid[0]*hp->grid[1] +
247 >                        hp->grid[0]*hp->grid[2] +
248 >                        hp->grid[1]*hp->grid[2] );
249 >        cl.cl = (GCOORD *)malloc(cl.n*sizeof(GCOORD));
250 >        if (cl.cl == NULL)
251                  goto memerr;
252 <        *cl = 0;
253 <                                        /* add cells within pyramid */
254 <        visit_cells(org, dir, hp, addcell, cl);
255 <        if (!*cl) {
168 <                free((char *)cl);
252 >        cl.n = 0;                       /* add cells within pyramid */
253 >        visit_cells(org, dir, hp, addcell, &cl);
254 >        if (!cl.n) {
255 >                free((char *)cl.cl);
256                  return(NULL);
257          }
258 +        *np = cl.n * orient;
259   #if 0
260          /* We're just going to free this memory in a moment, and list is
261           * sorted automatically by visit_cells(), so we don't need this.
262           */
263 <        if (*cl < n) {                  /* optimize memory use */
264 <                cl = (int *)realloc((char *)cl,
265 <                                sizeof(int) + *cl*sizeof(GCOORD));
266 <                if (cl == NULL)
179 <                        goto memerr;
180 <        }
263 >                                        /* optimize memory use */
264 >        cl.cl = (GCOORD *)realloc((char *)cl.cl, cl.n*sizeof(GCOORD));
265 >        if (cl.cl == NULL)
266 >                goto memerr;
267                                          /* sort the list */
268 <        qsort((char *)(cl+1), *cl, sizeof(GCOORD), cellcmp);
268 >        qsort((char *)cl.cl, cl.n, sizeof(GCOORD), cellcmp);
269   #endif
270 <        return(cl);
185 < viewerr:
186 <        error(INTERNAL, "unusable view in getviewcells");
270 >        return(cl.cl);
271   memerr:
272          error(SYSTEM, "out of memory in getviewcells");
273 + }
274 +
275 +
276 + gridlines(f)                    /* run through holodeck section grid lines */
277 + int     (*f)();
278 + {
279 +        register int    hd, w, i;
280 +        int     g0, g1;
281 +        FVECT   wp[2], mov;
282 +        double  d;
283 +                                        /* do each wall on each section */
284 +        for (hd = 0; hdlist[hd] != NULL; hd++)
285 +                for (w = 0; w < 6; w++) {
286 +                        g0 = ((w>>1)+1)%3;
287 +                        g1 = ((w>>1)+2)%3;
288 +                        d = 1.0/hdlist[hd]->grid[g0];
289 +                        mov[0] = d * hdlist[hd]->xv[g0][0];
290 +                        mov[1] = d * hdlist[hd]->xv[g0][1];
291 +                        mov[2] = d * hdlist[hd]->xv[g0][2];
292 +                        if (w & 1) {
293 +                                VSUM(wp[0], hdlist[hd]->orig,
294 +                                                hdlist[hd]->xv[w>>1], 1.);
295 +                                VSUM(wp[0], wp[0], mov, 1.);
296 +                        } else
297 +                                VCOPY(wp[0], hdlist[hd]->orig);
298 +                        VSUM(wp[1], wp[0], hdlist[hd]->xv[g1], 1.);
299 +                        for (i = hdlist[hd]->grid[g0]; ; ) {    /* g0 lines */
300 +                                (*f)(wp);
301 +                                if (!--i) break;
302 +                                wp[0][0] += mov[0]; wp[0][1] += mov[1];
303 +                                wp[0][2] += mov[2]; wp[1][0] += mov[0];
304 +                                wp[1][1] += mov[1]; wp[1][2] += mov[2];
305 +                        }
306 +                        d = 1.0/hdlist[hd]->grid[g1];
307 +                        mov[0] = d * hdlist[hd]->xv[g1][0];
308 +                        mov[1] = d * hdlist[hd]->xv[g1][1];
309 +                        mov[2] = d * hdlist[hd]->xv[g1][2];
310 +                        if (w & 1)
311 +                                VSUM(wp[0], hdlist[hd]->orig,
312 +                                                hdlist[hd]->xv[w>>1], 1.);
313 +                        else
314 +                                VSUM(wp[0], hdlist[hd]->orig, mov, 1.);
315 +                        VSUM(wp[1], wp[0], hdlist[hd]->xv[g0], 1.);
316 +                        for (i = hdlist[hd]->grid[g1]; ; ) {    /* g1 lines */
317 +                                (*f)(wp);
318 +                                if (!--i) break;
319 +                                wp[0][0] += mov[0]; wp[0][1] += mov[1];
320 +                                wp[0][2] += mov[2]; wp[1][0] += mov[0];
321 +                                wp[1][1] += mov[1]; wp[1][2] += mov[2];
322 +                        }
323 +                }
324   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines