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

Comparing ray/src/hd/rhd_odraw.c (file contents):
Revision 3.1 by gwlarson, Fri Dec 18 11:55:19 1998 UTC vs.
Revision 3.17 by greg, Fri Jan 7 20:33:02 2005 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   * Routines for drawing samples using depth buffer checks.
6   */
7  
8   #include "standard.h"
9  
13 #include <sys/types.h>
10   #include <GL/glx.h>
11   #include <GL/glu.h>
12  
17 #include "random.h"
13   #include "rhd_odraw.h"
14  
15   #ifndef DEPTHEPS
# Line 26 | Line 21 | static char SCCSid[] = "$SunId$ SGI";
21   #ifndef SFREEFRAC
22   #define SFREEFRAC       0.2             /* fraction to free at a time */
23   #endif
24 + #ifndef REDRAWTHRESH
25 + #define REDRAWTHRESH    10240           /* number of samples for dissolve */
26 + #endif
27   #ifndef MAXFAN
28   #define MAXFAN          32              /* maximum arms in a triangle fan */
29   #endif
# Line 38 | Line 36 | static char SCCSid[] = "$SunId$ SGI";
36  
37   #define NEWMAP          01              /* need to recompute mapping */
38   #define NEWRGB          02              /* need to remap RGB values */
39 + #define NEWHIST         04              /* clear histogram as well */
40  
41   struct ODview   *odView;        /* our view list */
42   int     odNViews;               /* number of views in our list */
# Line 48 | Line 47 | static int     needmapping;    /* what needs doing with tone
47  
48  
49   #define SAMP32  (32*(2*sizeof(short)+sizeof(union ODfunion)+sizeof(TMbright)+\
50 <                        6*sizeof(BYTE))+sizeof(int4))
50 >                        6*sizeof(BYTE))+sizeof(int32))
51  
52 < int
53 < odInit(n)                               /* initialize drawing routines */
54 < int     n;
52 > static int sampcmp(const void *s0, const void *s1);
53 > static int odAllocBlockSamp(int vn, int hh, int vh, double prox);
54 > static int make_arms(GLshort ar[MAXFAN][3], short cp[2], struct ODview *vp,
55 >                double sz);
56 > static int depthchange(struct ODview *vp, int x0, int y0, int x1, int y1);
57 > static void clip_edge(GLshort p[3], short o[2], struct ODview *vp);
58 > static int getblock(struct ODview *vp, int h, int v);
59 > static int blockedge(struct ODview *vp, int bi0, int bi1);
60 > static void odDrawSamp(int vn, int id);
61 >
62 >
63 > extern int
64 > odInit(                         /* initialize drawing routines */
65 >        int     n
66 > )
67   {
68          int     nbytes, i, j, k, nextsamp, count, blockdiv;
69          int     res[2];
70  
71 <        if (odNViews) {                 /* deallocate view structures */
72 <                for (i = 0; i < odNViews; i++) {
73 <                        free((char *)odView[i].bmap);
71 >        if (odNViews > 0) {             /* deallocate view structures */
72 >                for (i = odNViews; i--; ) {
73 >                        free((void *)odView[i].bmap);
74 >                        free((void *)odView[i].pmap);
75                          if (odView[i].emap != NULL)
76 <                                free((char *)odView[i].emap);
76 >                                free((void *)odView[i].emap);
77                  }
78 <                free((char *)odView);
78 >                free((void *)odView);
79                  odView = NULL;
80                  odNViews = 0;
81          }
# Line 73 | Line 85 | int    n;
85                  for (i = 1024; nbytes > i-8; i <<= 1)
86                          ;
87                  n = (i-8)/SAMP32 * 32;
88 <                needmapping = NEWMAP;
88 >                needmapping = NEWHIST;
89          }
90          if (n != odS.nsamp) {   /* (re)allocate sample array */
91                  if (odS.nsamp)
# Line 87 | Line 99 | int    n;
99                          return(0);
100                                  /* assign larger alignment types earlier */
101                  odS.f = (union ODfunion *)odS.base;
102 <                odS.redraw = (int4 *)(odS.f + n);
102 >                odS.redraw = (int32 *)(odS.f + n);
103                  odS.ip = (short (*)[2])(odS.redraw + n/32);
104                  odS.brt = (TMbright *)(odS.ip + n);
105                  odS.chr = (BYTE (*)[3])(odS.brt + n);
# Line 108 | Line 120 | int    n;
120          if (blockdiv < 8) blockdiv = 8;
121          nextsamp = 0; count /= blockdiv*blockdiv;       /* # blocks */
122          while (i--) {                   /* initialize each view */
111                odView[i].emap = NULL;
112                odView[i].dmap = NULL;
123                  dev_auxview(i, res);
124                  odView[i].hhi = res[0];
125                  odView[i].hlow = (res[0] + blockdiv/2) / blockdiv;
# Line 117 | Line 127 | int    n;
127                  odView[i].vhi = res[1];
128                  odView[i].vlow = (res[1] + blockdiv/2) / blockdiv;
129                  if (odView[i].vlow < 1) odView[i].vlow = 1;
130 +                odView[i].emap = NULL;
131 +                odView[i].dmap = NULL;
132 +                odView[i].pmap = (int32 *)calloc(FL4NELS(res[0]*res[1]),
133 +                                sizeof(int32));
134 +                if (odView[i].pmap == NULL)
135 +                        return(0);
136                  j = odView[i].hlow*odView[i].vlow;
137                  odView[i].bmap = (struct ODblock *)malloc(
138                                  j * sizeof(struct ODblock));
# Line 125 | Line 141 | int    n;
141                  DCHECK(count<=0 | nextsamp>=n,
142                                  CONSISTENCY, "counter botch in odInit");
143                  if (!i) count = j;
144 <                while (j--) {
144 >                odView[i].sfirst = nextsamp;
145 >                while (j--) {           /* initialize blocks & free lists */
146 >                        odView[i].bmap[j].pthresh = FHUGE;
147                          odView[i].bmap[j].first = k = nextsamp;
148                          nextsamp += odView[i].bmap[j].nsamp =
149                                  (n - nextsamp)/count--;
# Line 135 | Line 153 | int    n;
153                          odS.nextfree(k-1) = ENDFREE;
154                          odView[i].bmap[j].nused = 0;
155                  }
156 +                odView[i].snext = nextsamp;
157 +                odView[i].n2redraw = 0;
158          }
159          CLR4ALL(odS.redraw, odS.nsamp);         /* clear redraw flags */
160 <        for (i = odS.nsamp; i--; )              /* clear values */
160 >        for (i = odS.nsamp; i--; ) {            /* clear values */
161                  odS.ip[i][0] = odS.ip[i][1] = -1;
162 +                odS.brt[i] = TM_NOBRT;
163 +        }
164 +        needmapping |= NEWMAP;                  /* compute new map on update */
165          return(odS.nsamp);                      /* return number of samples */
166   }
167  
# Line 146 | Line 169 | int    n;
169  
170  
171   int
172 < sampcmp(s0, s1)                 /* sample order, descending proximity */
173 < int     *s0, *s1;
172 > sampcmp(                        /* sample order, descending proximity */
173 >        const void      *s0,
174 >        const void      *s1
175 > )
176   {
177 <        register double diff = odS.closeness(*s1) - odS.closeness(*s0);
177 >        register double diff = odS.closeness(*(int*)s1) - odS.closeness(*(int*)s0);
178  
179          return (diff > FTINY ? 1 : diff < -FTINY ? -1 : 0);
180   }
181  
182  
183   int
184 < odAllocBlockSamp(vn, hl, vl)            /* allocate sample from block */
185 < int     vn, hl, vl;
184 > odAllocBlockSamp(       /* allocate sample from block */
185 >        int     vn,
186 >        int     hh,
187 >        int     vh,
188 >        double  prox
189 > )
190   {
191          int     si[SAMPSPERBLOCK+SAMPSPERBLOCK/4];
192 +        int     hl, vl;
193          VIEW    *vw;
164        FVECT   ro, rd;
194          int     res[2];
195          register struct ODblock *bp;
196 <        register int    i;
197 <
196 >        register int    i, j;
197 >                                        /* get block */
198 >        hl = hh*odView[vn].hlow/odView[vn].hhi;
199 >        vl = vh*odView[vn].vlow/odView[vn].vhi;
200          bp = odView[vn].bmap + vl*odView[vn].hlow + hl;
201 <        if (bp->free != ENDFREE) {      /* check free list first */
201 >        if (prox > bp->pthresh)
202 >                return(-1);             /* worse than free list occupants */
203 >                                        /* check for duplicate pixel */
204 >        if (CHK4(odView[vn].pmap, vh*odView[vn].hhi + hh))
205 >                i = bp->first + bp->nsamp;
206 >        else
207 >                i = 0;
208 >        while (i-- > bp->first)
209 >                if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */
210 >                                                /* search free list for it */
211 >                        if (i == bp->free)
212 >                                break;          /* special case */
213 >                        if (bp->free != ENDFREE)
214 >                                for (j = bp->free; odS.nextfree(j) != ENDFREE;
215 >                                                j = odS.nextfree(j))
216 >                                        if (odS.nextfree(j) == i) {
217 >                                                odS.nextfree(j) =
218 >                                                        odS.nextfree(i);
219 >                                                bp->nused++;
220 >                                                goto gotit;
221 >                                        }
222 >                        if (prox >= 0.99*odS.closeness(i))
223 >                                return(-1);     /* previous sample is fine */
224 >                        goto gotit;
225 >                }
226 >        if (bp->free != ENDFREE) {      /* allocate from free list */
227                  i = bp->free;
228 +                if ((odS.ip[i][0] >= 0) & (odS.ip[i][1] >= 0))
229 +                        CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi +
230 +                                                        odS.ip[i][0]);
231                  bp->free = odS.nextfree(i);
232                  bp->nused++;
233 <                return(i);
233 >                goto gotit;
234          }
235          DCHECK(bp->nsamp<=0, CONSISTENCY,
236                          "no available samples in odAllocBlockSamp");
# Line 183 | Line 242 | int    vn, hl, vl;
242          for (i = bp->nsamp; i--; )      /* figure out which are worse */
243                  si[i] = bp->first + i;
244          qsort((char *)si, bp->nsamp, sizeof(int), sampcmp);
245 <        i = bp->nsamp*SFREEFRAC + .5;   /* put them in a list */
245 >        i = bp->nsamp*SFREEFRAC + .5;   /* put them into free list */
246 >        if (i >= bp->nsamp) i = bp->nsamp-1;    /* paranoia */
247 >        bp->pthresh = odS.closeness(si[i]);     /* new proximity threshold */
248          while (--i > 0) {
249                  odS.nextfree(si[i]) = bp->free;
250                  bp->free = si[i];
251                  bp->nused--;
252          }
253 <        return(si[0]);                  /* return first free sample */
253 >        i = si[0];                      /* use worst sample */
254 >        CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi + odS.ip[i][0]);
255 > gotit:
256 >        odS.ip[i][0] = hh;
257 >        odS.ip[i][1] = vh;
258 >        odS.closeness(i) = prox;
259 >        SET4(odView[vn].pmap, vh*odView[vn].hhi + hh);
260 >        return(i);
261   }
262  
263  
264 < odSample(c, d, p)                       /* add a sample value */
265 < COLR    c;
266 < FVECT   d, p;
264 > extern void
265 > odSample(                       /* add a sample value */
266 >        COLR    c,
267 >        FVECT   d,
268 >        FVECT   p
269 > )
270   {
271          FVECT   disp;
272 <        double  d0, d1, h, v;
272 >        double  d0, d1, h, v, prox;
273          register VIEW   *vw;
274 <        int     hl, vl, hh, vh;
274 >        int     hh, vh;
275          int     res[2];
276          register int    i, id;
277  
# Line 235 | Line 306 | FVECT  d, p;
306                                                  (1.+DEPTHEPS)*d0 < d1))
307                          continue;                       /* occlusion error */
308                  }
238                hl = hh*odView[i].hlow/res[0];
239                vl = vh*odView[i].vlow/res[1];
240                                                /* may duplicate samples */
241                id = odAllocBlockSamp(i, hl, vl);
242                odS.ip[id][0] = hh;
243                odS.ip[id][1] = vh;
309                  if (p != NULL) {                /* compute closeness (sin^2) */
310                          d1 = DOT(disp, d);
311 <                        odS.closeness(id) = 1. - d1*d1/DOT(disp,disp);
311 >                        prox = 1. - d1*d1/DOT(disp,disp);
312                  } else
313 <                        odS.closeness(id) = 0.;
313 >                        prox = 0.;
314 >                                                /* allocate sample */
315 >                id = odAllocBlockSamp(i, hh, vh, prox);
316 >                if (id < 0)
317 >                        continue;               /* not good enough */
318                                                          /* convert color */
319 <                tmCvColrs(&odS.brt[id], odS.chr[id], c, 1);
319 >                tmCvColrs(tmGlobal, &odS.brt[id], odS.chr[id], (COLR *)c, 1);
320                  if (imm_mode | needmapping)             /* if immediate mode */
321                          needmapping |= NEWRGB;          /* map it later */
322                  else                                    /* else map it now */
323 <                        tmMapPixels(odS.rgb[id], &odS.brt[id], odS.chr[id], 1);
323 >                        tmMapPixels(tmGlobal, odS.rgb[id], &odS.brt[id],
324 >                                        odS.chr[id], 1);
325                  SET4(odS.redraw, id);                   /* mark for redraw */
326 +                odView[i].n2redraw++;
327          }
328   }
329  
330  
331 < odRemap()                               /* recompute tone mapping */
331 > extern void
332 > odRemap(                        /* recompute tone mapping */
333 >        int     newhist
334 > )
335   {
336          needmapping |= NEWMAP|NEWRGB;
337 +        if (newhist)
338 +                needmapping |= NEWHIST;
339   }
340  
341  
342 < odRedraw(vn, hmin, vmin, hmax, vmax)    /* redraw view region */
343 < int     vn, hmin, vmin, hmax, vmax;
342 > extern void
343 > odRedrawAll(void)                               /* mark all samples for redraw */
344   {
345 +        register int    i;
346 +
347 +        if ((needmapping&(NEWMAP|NEWRGB)) == (NEWMAP|NEWRGB))
348 +                return;                 /* will be called later, anyway */
349 +        for (i = odS.nsamp; i--; )
350 +                if (odS.ip[i][0] >= 0)
351 +                        SET4(odS.redraw, i);
352 +                                        /* not right, but not important */
353 +        for (i = 0; i < odNViews; i++)
354 +                odView[i].n2redraw = odView[i].snext - odView[i].sfirst;
355 + }
356 +
357 +
358 + extern void
359 + odRedraw(       /* redraw view region */
360 +        int     vn,
361 +        int     hmin,
362 +        int     vmin,
363 +        int     hmax,
364 +        int     vmax
365 + )
366 + {
367          int     i, j;
368          register struct ODblock *bp;
369          register int    k;
370  
371 <        if (vn<0 | vn>=odNViews)
371 >        if ((vn<0) | (vn>=odNViews))
372                  return;
373                                  /* check view limits */
374          if (hmin < 0) hmin = 0;
375          if (hmax >= odView[vn].hhi) hmax = odView[vn].hhi-1;
376          if (vmin < 0) vmin = 0;
377          if (vmax >= odView[vn].vhi) vmax = odView[vn].vhi-1;
378 <        if (hmax <= hmin | vmax <= vmin)
378 >        if ((hmax <= hmin) | (vmax <= vmin))
379                  return;
380                                  /* convert to low resolution */
381          hmin = hmin * odView[vn].hlow / odView[vn].hhi;
# Line 289 | Line 387 | int    vn, hmin, vmin, hmax, vmax;
387                  for (j = vmin; j <= vmax; j++) {
388                          bp = odView[vn].bmap + j*odView[vn].hlow + i;
389                          for (k = bp->nsamp; k--; )
390 <                                if (odS.ip[bp->first+k][0] >= 0)
390 >                                if (odS.ip[bp->first+k][0] >= 0) {
391                                          SET4(odS.redraw, bp->first+k);
392 +                                        odView[vn].n2redraw++;
393 +                                }
394                  }
395   }
396  
397  
398 < odDepthMap(vn, dm)                      /* assign depth map for view */
399 < int     vn;
400 < GLfloat *dm;
398 > extern void
399 > odDepthMap(                     /* assign depth map for view */
400 >        int     vn,
401 >        GLfloat *dm
402 > )
403   {
404          double  d0, d1;
405          int     i, j, hmin, hmax, vmin, vmax;
406          register int    k, l;
407  
306        DCHECK(vn<0 | vn>=odNViews, CONSISTENCY,
307                        "bad view number in odDepthMap");
408          if (dm == NULL) {                       /* free edge map */
409 +                if ((vn<0) | (vn>=odNViews))
410 +                        return;                 /* too late -- they're gone! */
411                  if (odView[vn].emap != NULL)
412 <                        free((char *)odView[vn].emap);
412 >                        free((void *)odView[vn].emap);
413                  odView[vn].emap = NULL;
414                  odView[vn].dmap = NULL;
415                  return;
416          }
417 +        DCHECK(vn<0 | vn>=odNViews, CONSISTENCY,
418 +                        "bad view number in odDepthMap");
419          odView[vn].dmap = dm;                   /* initialize edge map */
420          if (odView[vn].emap == NULL) {
421 <                odView[vn].emap = (int4 *)malloc(
422 <                        FL4NELS(odView[vn].hlow*odView[vn].vlow)*sizeof(int4));
421 >                odView[vn].emap = (int32 *)malloc(
422 >                        FL4NELS(odView[vn].hlow*odView[vn].vlow)*sizeof(int32));
423                  if (odView[vn].emap == NULL)
424                          error(SYSTEM, "out of memory in odDepthMap");
425          }
# Line 366 | Line 470 | GLfloat        *dm;
470   }
471  
472  
473 < odUpdate(vn)                            /* update this view */
474 < int     vn;
473 > extern void
474 > odUpdate(                               /* update this view */
475 >        int     vn
476 > )
477   {
478 <        int     i, j;
479 <        register struct ODblock *bp;
480 <        register int    k;
478 >        static short    primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1};
479 >        int     myprime;
480 >        register int    i, n;
481  
482          DCHECK(vn<0 | vn>=odNViews, CONSISTENCY,
483                          "bad view number in odUpdate");
484                                          /* need to do some tone mapping? */
485          if (needmapping & NEWRGB) {
486                  if (needmapping & NEWMAP) {
487 <                        tmClearHisto();
488 <                        if (tmAddHisto(odS.brt,odS.nsamp,1) != TM_E_OK)
487 >                        if (needmapping & NEWHIST)
488 >                                tmClearHisto(tmGlobal);
489 >                        needmapping &= ~NEWHIST;
490 >                        if (tmAddHisto(tmGlobal, odS.brt,odS.nsamp,1) != TM_E_OK)
491                                  return;
492 <                        if (tmComputeMapping(0.,0.,0.) != TM_E_OK)
492 >                        if (tmComputeMapping(tmGlobal, 0.,0.,0.) != TM_E_OK)
493                                  return;
494 <                        for (k = odS.nsamp; k--; )      /* redraw all */
495 <                                if (odS.ip[k][0] >= 0)
388 <                                        SET4(odS.redraw, k);
494 >                        needmapping &= ~NEWMAP;
495 >                        odRedrawAll();                  /* redraw everything */
496                  }
497 <                if (tmMapPixels(odS.rgb,odS.brt,odS.chr,odS.nsamp) != TM_E_OK)
497 >                if (tmMapPixels(tmGlobal, (BYTE *)(odS.rgb), odS.brt,
498 >                                (BYTE *)(odS.chr), odS.nsamp) != TM_E_OK)
499                          return;
500 <                needmapping = 0;                /* reset flag */
500 >                needmapping &= ~NEWRGB;
501          }
502 <                                        /* draw each block in view */
503 <        for (i = odView[vn].hlow; i--; )
504 <                for (j = odView[vn].vlow; j--; ) {
505 <                                        /* get block */
506 <                        bp = odView[vn].bmap + j*odView[vn].hlow + i;
507 <                                        /* do quick, conservative flag check */
508 <                        for (k = (bp->first+bp->nsamp+31)>>5;
509 <                                        k-- > bp->first>>5; )
510 <                                if (odS.redraw[k])
511 <                                        break;          /* non-zero flag */
512 <                        if (k < bp->first>>5)
513 <                                continue;               /* no flags set */
514 <                        for (k = bp->nsamp; k--; )      /* sample by sample */
515 <                                if (CHK4(odS.redraw, bp->first+k)) {
516 <                                        odDrawBlockSamp(vn, i, j, bp->first+k);
517 <                                        CLR4(odS.redraw, bp->first+k);
518 <                                }
502 >        if (odView[vn].n2redraw <= 0)
503 >                return;
504 > #if REDRAWTHRESH
505 >        if (odView[vn].n2redraw < REDRAWTHRESH)
506 >                goto quickdraw;
507 >                                        /* pick a good prime step size */
508 >        n = odView[vn].snext - odView[vn].sfirst;
509 >        for (i = 0; primes[i]<<5 >= n; i++)
510 >                ;
511 >        while ((myprime = primes[i++]) > 1)
512 >                if (n % myprime)
513 >                        break;
514 >                                        /* dissolve in new samples */
515 >        for (i = odView[vn].sfirst; n-- > 0; i += myprime) {
516 >                if (i >= odView[vn].snext)
517 >                        i -= odView[vn].snext - odView[vn].sfirst;
518 >                if (CHK4(odS.redraw, i)) {
519 >                        odDrawSamp(vn, i);
520 >                        CLR4(odS.redraw, i);
521                  }
522 +        }
523 +        odView[vn].n2redraw = 0;
524 +        return;
525 + quickdraw:                              /* quicker sparse flag checking */
526 + #endif
527 +                                        /* redraw samples at end */
528 +        for (i = odView[vn].snext-31; i < odView[vn].snext; i++)
529 +                if (CHK4(odS.redraw, i)) {
530 +                        odDrawSamp(vn, i);
531 +                        CLR4(odS.redraw, i);
532 +                }
533 +                                        /* faster flag checks in middle */
534 +        for (n = odView[vn].snext>>5; n-- > (odView[vn].sfirst+0x1f)>>5; )
535 +                for (i = 0; odS.redraw[n]; i++)         /* skips faster */
536 +                        if (odS.redraw[n] & 1L<<i) {
537 +                                odDrawSamp(vn, (n<<5)+i);
538 +                                odS.redraw[n] &= ~(1L<<i);
539 +                        }
540 +                                        /* redraw samples at beginning */
541 +        for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++)
542 +                if (CHK4(odS.redraw, i)) {
543 +                        odDrawSamp(vn, i);
544 +                        CLR4(odS.redraw, i);
545 +                }
546 +        odView[vn].n2redraw = 0;
547   }
548  
549  
550 +                                        /* this turned out to be unnecessary */
551   #if 0
552   static
553   clip_end(p, o, vp)                      /* clip line segment to view */
# Line 442 | Line 578 | register struct ODview *vp;
578  
579  
580   static int
581 < make_arms(ar, cp, vp, sz)               /* make arms for triangle fan */
582 < GLshort ar[MAXFAN][3];
583 < short   cp[2];
584 < register struct ODview  *vp;
585 < double  sz;
581 > make_arms(              /* make arms for triangle fan */
582 >        GLshort ar[MAXFAN][3],
583 >        short   cp[2],
584 >        register struct ODview  *vp,
585 >        double  sz
586 > )
587   {
588          int     na, dv;
589 <        double  hrad, vrad, phi0, phi;
589 >        double  hrad, vrad, phi;
590          register int    i;
591  
592          DCHECK(sz > 1, CONSISTENCY, "super-unary size in make_arms");
593 <        na = MAXFAN*sz*sz + 0.5;                /* keep area constant */
593 >        na = MAXFAN*sz + 0.5;                   /* keep arc length constant */
594          if (na < MINFAN) na = MINFAN;
595          hrad = FANSIZE*sz*vp->hhi/vp->hlow;
596          vrad = FANSIZE*sz*vp->vhi/vp->vlow;
597          if (hrad*vrad < 2.25)
598                  hrad = vrad = 1.5;
462        phi0 = (2.*PI) * frandom();
599          dv = OMAXDEPTH*sz + 0.5;
600          for (i = 0; i < na; i++) {
601 <                phi = phi0 + (2.*PI)*i/na;
601 >                phi = (2.*PI)*i/na;
602                  ar[i][0] = cp[0] + tcos(phi)*hrad + 0.5;
603                  ar[i][1] = cp[1] + tsin(phi)*vrad + 0.5;
604                  ar[i][2] = dv;
# Line 473 | Line 609 | double sz;
609  
610  
611   static int
612 < depthchange(vp, x0, y0, x1, y1)         /* check depth discontinuity */
613 < register struct ODview  *vp;
614 < int     x0, y0, x1, y1;
612 > depthchange(            /* check depth discontinuity */
613 >        register struct ODview  *vp,
614 >        int     x0,
615 >        int     y0,
616 >        int     x1,
617 >        int     y1
618 > )
619   {
620          register double d0, d1;
621  
622          DCHECK(x0<0 | x0>=vp->hhi | y0<0 | y0>=vp->vhi,
623                          CONSISTENCY, "coordinates off view in depthchange");
624  
625 <        if (x1<0 | x1>=vp->hhi | y1<0 | y1>=vp->vhi)
625 >        if ((x1<0) | (x1>=vp->hhi) | (y1<0) | (y1>=vp->vhi))
626                  return(1);
627  
628          d0 = vp->dmap[y0*vp->hhi + x0];
# Line 492 | Line 632 | int    x0, y0, x1, y1;
632   }
633  
634  
635 < static
636 < clip_edge(p, o, vp)                     /* clip line segment to depth edge */
637 < GLshort p[3];
638 < short   o[2];
639 < register struct ODview  *vp;
635 > static void
636 > clip_edge(                      /* clip line segment to depth edge */
637 >        GLshort p[3],
638 >        short   o[2],
639 >        register struct ODview  *vp
640 > )
641   {
642          int     x, y, xstep, ystep, rise, rise2, run, run2, n;
643  
# Line 515 | Line 656 | register struct ODview *vp;
656          n = rise + run;
657          while (n--)                     /* run out arm, checking depth */
658                  if (run2 > rise2) {
518                        if (depthchange(vp, x, y, x+xstep, y))
519                                break;
659                          x += xstep;
660                          rise2 += rise;
661 <                } else {
523 <                        if (depthchange(vp, x, y, x, y+ystep))
661 >                        if (depthchange(vp, x-xstep, y, x, y))
662                                  break;
663 +                } else {
664                          y += ystep;
665                          run2 += run;
666 +                        if (depthchange(vp, x, y-ystep, x, y))
667 +                                break;
668                  }
669          if (n < 0)                      /* found something? */
670                  return;
# Line 537 | Line 678 | register struct ODview *vp;
678  
679  
680   static int
681 < getblock(vp, h, v)                      /* get block index */
682 < register struct ODview  *vp;
683 < register int    h, v;
681 > getblock(                       /* get block index */
682 >        register struct ODview  *vp,
683 >        register int    h,
684 >        register int    v
685 > )
686   {
687 <        if (h<0 | h>=vp->hhi | v<0 | v>=vp->vhi)
687 >        if ((h<0) | (h>=vp->hhi) | (v<0) | (v>=vp->vhi))
688                  return(-1);
689          return(h*vp->hlow/vp->hhi + v*vp->vlow/vp->vhi*vp->hlow);
690   }
691  
692  
693 < odDrawBlockSamp(vn, h, v, id)           /* draw sample in view block */
694 < int     vn, h, v;
695 < register int    id;
693 > static int
694 > blockedge(                      /* check for edge between blocks? */
695 >        register struct ODview  *vp,
696 >        register int    bi0,
697 >        register int    bi1
698 > )
699   {
700 +        if (bi1 == bi0)
701 +                return(0);              /* same block */
702 +        if (bi1 < 0)
703 +                return(1);              /* end off view */
704 +        if (CHK4(vp->emap, bi1))
705 +                return(1);              /* end block has edges */
706 +        if (bi1 == bi0+1 || bi1 == bi0-1 ||
707 +                        bi1 == bi0+vp->hlow || bi1 == bi0-vp->hlow)
708 +                return(0);              /* end in adjacent block -- no edges */
709 +        return(1);                      /* conservative for rarer case */
710 + }
711 +
712 +
713 + static void
714 + odDrawSamp(                     /* draw view sample */
715 +        int     vn,
716 +        register int    id
717 + )
718 + {
719          GLshort arm[MAXFAN][3];
720 <        int     narms, blockindex, bi1;
720 >        int     narms, blockindex;
721          register struct ODview  *vp;
722          double  size;
723          int     home_edges;
724          register int    i;
725  
726          vp = odView + vn;
727 <        blockindex = v*vp->hlow + h;
728 <        DCHECK(odS.ip[id][0]*vp->hlow/vp->hhi != h |
564 <                        odS.ip[id][1]*vp->vlow/vp->vhi != v,
565 <                        CONSISTENCY, "bad sample position in odDrawBlockSamp");
727 >        blockindex = getblock(vp, odS.ip[id][0], odS.ip[id][1]);
728 >        DCHECK(blockindex<0, CONSISTENCY, "bad sample handed to odDrawSamp");
729          DCHECK(vp->bmap[blockindex].nused <= 0,
730 <                        CONSISTENCY, "bad in-use count in odDrawBlockSamp");
730 >                        CONSISTENCY, "bad in-use count in odDrawSamp");
731                                          /* create triangle fan */
732          size = 1./sqrt((double)vp->bmap[blockindex].nused);
733          narms = make_arms(arm, odS.ip[id], vp, size);
734          if (vp->emap != NULL) {         /* check for edge collisions */
735                  home_edges = CHK4(vp->emap, blockindex);
736                  for (i = 0; i < narms; i++)
737 <                        /* the following test is flawed, because we could
738 <                         * be passing through a block on a diagonal run */
576 <                        if (home_edges ||
577 <                                ( (bi1 = getblock(vp, arm[i][0], arm[i][1]))
578 <                                                != blockindex &&
579 <                                        (bi1 < 0 || CHK4(vp->emap, bi1)) ))
737 >                        if (home_edges || blockedge(vp, blockindex,
738 >                                        getblock(vp, arm[i][0], arm[i][1])))
739                                  clip_edge(arm[i], odS.ip[id], vp);
740          }
741                                          /* draw triangle fan */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines