| 1 | < | /* Copyright (c) 1998 Silicon Graphics, Inc. */ | 
| 1 | > | /* Copyright (c) 1999 Silicon Graphics, Inc. */ | 
| 2 |  |  | 
| 3 |  | #ifndef lint | 
| 4 |  | static char SCCSid[] = "$SunId$ SGI"; | 
| 10 |  |  | 
| 11 |  | #include "standard.h" | 
| 12 |  |  | 
| 13 | – | #include <sys/types.h> | 
| 13 |  | #include <GL/glx.h> | 
| 14 |  | #include <GL/glu.h> | 
| 15 |  |  | 
| 17 | – | #include "random.h" | 
| 16 |  | #include "rhd_odraw.h" | 
| 17 |  |  | 
| 18 |  | #ifndef DEPTHEPS | 
| 24 |  | #ifndef SFREEFRAC | 
| 25 |  | #define SFREEFRAC       0.2             /* fraction to free at a time */ | 
| 26 |  | #endif | 
| 27 | + | #ifndef REDRAWTHRESH | 
| 28 | + | #define REDRAWTHRESH    10240           /* number of samples for dissolve */ | 
| 29 | + | #endif | 
| 30 |  | #ifndef MAXFAN | 
| 31 |  | #define MAXFAN          32              /* maximum arms in a triangle fan */ | 
| 32 |  | #endif | 
| 145 |  | odView[i].bmap[j].nused = 0; | 
| 146 |  | } | 
| 147 |  | odView[i].snext = nextsamp; | 
| 148 | + | odView[i].n2redraw = 0; | 
| 149 |  | } | 
| 150 |  | CLR4ALL(odS.redraw, odS.nsamp);         /* clear redraw flags */ | 
| 151 |  | for (i = odS.nsamp; i--; ) {            /* clear values */ | 
| 191 |  | if (CHK4(odView[vn].pmap, vh*odView[vn].hhi + hh)) | 
| 192 |  | i = bp->first + bp->nsamp; | 
| 193 |  | else | 
| 194 | < | i = -1; | 
| 194 | > | i = 0; | 
| 195 |  | while (i-- > bp->first) | 
| 196 |  | if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */ | 
| 197 |  | /* search free list for it */ | 
| 206 |  | bp->nused++; | 
| 207 |  | goto gotit; | 
| 208 |  | } | 
| 209 | < | if (prox >= 0.999*odS.closeness(i)) | 
| 209 | > | if (prox >= 0.99*odS.closeness(i)) | 
| 210 |  | return(-1);     /* previous sample is fine */ | 
| 211 |  | goto gotit; | 
| 212 |  | } | 
| 211 | – | DCHECK(i>=-1, WARNING, "pixel in presence map not found in block"); | 
| 213 |  | if (bp->free != ENDFREE) {      /* allocate from free list */ | 
| 214 |  | i = bp->free; | 
| 215 |  | if (odS.ip[i][0] >= 0 & odS.ip[i][1] >= 0) | 
| 306 |  | else                                    /* else map it now */ | 
| 307 |  | tmMapPixels(odS.rgb[id], &odS.brt[id], odS.chr[id], 1); | 
| 308 |  | SET4(odS.redraw, id);                   /* mark for redraw */ | 
| 309 | + | odView[i].n2redraw++; | 
| 310 |  | } | 
| 311 |  | } | 
| 312 |  |  | 
| 320 |  | } | 
| 321 |  |  | 
| 322 |  |  | 
| 323 | + | odRedrawAll()                           /* mark all samples for redraw */ | 
| 324 | + | { | 
| 325 | + | register int    i; | 
| 326 | + |  | 
| 327 | + | if ((needmapping&(NEWMAP|NEWRGB)) == (NEWMAP|NEWRGB)) | 
| 328 | + | return;                 /* will be called later, anyway */ | 
| 329 | + | for (i = odS.nsamp; i--; ) | 
| 330 | + | if (odS.ip[i][0] >= 0) | 
| 331 | + | SET4(odS.redraw, i); | 
| 332 | + | /* not right, but not important */ | 
| 333 | + | for (i = 0; i < odNViews; i++) | 
| 334 | + | odView[i].n2redraw = odView[i].snext - odView[i].sfirst; | 
| 335 | + | } | 
| 336 | + |  | 
| 337 | + |  | 
| 338 |  | odRedraw(vn, hmin, vmin, hmax, vmax)    /* redraw view region */ | 
| 339 |  | int     vn, hmin, vmin, hmax, vmax; | 
| 340 |  | { | 
| 361 |  | for (j = vmin; j <= vmax; j++) { | 
| 362 |  | bp = odView[vn].bmap + j*odView[vn].hlow + i; | 
| 363 |  | for (k = bp->nsamp; k--; ) | 
| 364 | < | if (odS.ip[bp->first+k][0] >= 0) | 
| 364 | > | if (odS.ip[bp->first+k][0] >= 0) { | 
| 365 |  | SET4(odS.redraw, bp->first+k); | 
| 366 | + | odView[vn].n2redraw++; | 
| 367 | + | } | 
| 368 |  | } | 
| 369 |  | } | 
| 370 |  |  | 
| 445 |  | odUpdate(vn)                            /* update this view */ | 
| 446 |  | int     vn; | 
| 447 |  | { | 
| 448 | < | register int    i, j; | 
| 448 | > | static short    primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1}; | 
| 449 | > | int     myprime; | 
| 450 | > | register int    i, n; | 
| 451 |  |  | 
| 452 |  | DCHECK(vn<0 | vn>=odNViews, CONSISTENCY, | 
| 453 |  | "bad view number in odUpdate"); | 
| 456 |  | if (needmapping & NEWMAP) { | 
| 457 |  | if (needmapping & NEWHIST) | 
| 458 |  | tmClearHisto(); | 
| 459 | + | needmapping &= ~NEWHIST; | 
| 460 |  | if (tmAddHisto(odS.brt,odS.nsamp,1) != TM_E_OK) | 
| 461 |  | return; | 
| 462 |  | if (tmComputeMapping(0.,0.,0.) != TM_E_OK) | 
| 463 |  | return; | 
| 464 | < | for (i = odS.nsamp; i--; )      /* redraw all */ | 
| 465 | < | if (odS.ip[i][0] >= 0) | 
| 444 | < | SET4(odS.redraw, i); | 
| 464 | > | needmapping &= ~NEWMAP; | 
| 465 | > | odRedrawAll();                  /* redraw everything */ | 
| 466 |  | } | 
| 467 |  | if (tmMapPixels(odS.rgb,odS.brt,odS.chr,odS.nsamp) != TM_E_OK) | 
| 468 |  | return; | 
| 469 | < | needmapping = 0;                /* reset flag */ | 
| 469 | > | needmapping &= ~NEWRGB; | 
| 470 |  | } | 
| 471 | < | /* this code segment was too slow */ | 
| 472 | < | #if 0 | 
| 473 | < | for (i = odView[vn].sfirst; i < odView[vn].snext; i++) | 
| 471 | > | if (odView[vn].n2redraw <= 0) | 
| 472 | > | return; | 
| 473 | > | #if REDRAWTHRESH | 
| 474 | > | if (odView[vn].n2redraw < REDRAWTHRESH) | 
| 475 | > | goto quickdraw; | 
| 476 | > | /* pick a good prime step size */ | 
| 477 | > | n = odView[vn].snext - odView[vn].sfirst; | 
| 478 | > | for (i = 0; primes[i]<<5 >= n; i++) | 
| 479 | > | ; | 
| 480 | > | while ((myprime = primes[i++]) > 1) | 
| 481 | > | if (n % myprime) | 
| 482 | > | break; | 
| 483 | > | /* dissolve in new samples */ | 
| 484 | > | for (i = odView[vn].sfirst; n-- > 0; i += myprime) { | 
| 485 | > | if (i >= odView[vn].snext) | 
| 486 | > | i -= odView[vn].snext - odView[vn].sfirst; | 
| 487 |  | if (CHK4(odS.redraw, i)) { | 
| 488 |  | odDrawSamp(vn, i); | 
| 489 |  | CLR4(odS.redraw, i); | 
| 490 |  | } | 
| 491 | + | } | 
| 492 | + | odView[vn].n2redraw = 0; | 
| 493 | + | return; | 
| 494 | + | quickdraw:                              /* quicker sparse flag checking */ | 
| 495 |  | #endif | 
| 496 | < | /* redraw samples at each end */ | 
| 497 | < | for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++) | 
| 496 | > | /* redraw samples at end */ | 
| 497 | > | for (i = odView[vn].snext-31; i < odView[vn].snext; i++) | 
| 498 |  | if (CHK4(odS.redraw, i)) { | 
| 499 |  | odDrawSamp(vn, i); | 
| 500 |  | CLR4(odS.redraw, i); | 
| 501 |  | } | 
| 502 | < | for (i = odView[vn].snext-31; i < odView[vn].snext; i++) | 
| 502 | > | /* faster flag checks in middle */ | 
| 503 | > | for (n = odView[vn].snext>>5; n-- > (odView[vn].sfirst+0x1f)>>5; ) | 
| 504 | > | for (i = 0; odS.redraw[n]; i++)         /* skips faster */ | 
| 505 | > | if (odS.redraw[n] & 1L<<i) { | 
| 506 | > | odDrawSamp(vn, (n<<5)+i); | 
| 507 | > | odS.redraw[n] &= ~(1L<<i); | 
| 508 | > | } | 
| 509 | > | /* redraw samples at beginning */ | 
| 510 | > | for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++) | 
| 511 |  | if (CHK4(odS.redraw, i)) { | 
| 512 |  | odDrawSamp(vn, i); | 
| 513 |  | CLR4(odS.redraw, i); | 
| 514 |  | } | 
| 515 | < | /* faster flag checks in middle */ | 
| 470 | < | for (j = odView[vn].snext>>5; j-- > (odView[vn].sfirst+0x1f)>>5; ) | 
| 471 | < | for (i = 0; odS.redraw[j]; i++)         /* skips faster */ | 
| 472 | < | if (odS.redraw[j] & 1L<<i) { | 
| 473 | < | odDrawSamp(vn, (j<<5)+i); | 
| 474 | < | odS.redraw[j] &= ~(1L<<i); | 
| 475 | < | } | 
| 515 | > | odView[vn].n2redraw = 0; | 
| 516 |  | } | 
| 517 |  |  | 
| 518 |  |  | 
| 554 |  | double  sz; | 
| 555 |  | { | 
| 556 |  | int     na, dv; | 
| 557 | < | double  hrad, vrad, phi0, phi; | 
| 557 | > | double  hrad, vrad, phi; | 
| 558 |  | register int    i; | 
| 559 |  |  | 
| 560 |  | DCHECK(sz > 1, CONSISTENCY, "super-unary size in make_arms"); | 
| 561 | < | na = MAXFAN*sz*sz + 0.5;                /* keep area constant */ | 
| 561 | > | na = MAXFAN*sz + 0.5;                   /* keep arc length constant */ | 
| 562 |  | if (na < MINFAN) na = MINFAN; | 
| 563 |  | hrad = FANSIZE*sz*vp->hhi/vp->hlow; | 
| 564 |  | vrad = FANSIZE*sz*vp->vhi/vp->vlow; | 
| 565 |  | if (hrad*vrad < 2.25) | 
| 566 |  | hrad = vrad = 1.5; | 
| 527 | – | phi0 = (2.*PI) * frandom(); | 
| 567 |  | dv = OMAXDEPTH*sz + 0.5; | 
| 568 |  | for (i = 0; i < na; i++) { | 
| 569 | < | phi = phi0 + (2.*PI)*i/na; | 
| 569 | > | phi = (2.*PI)*i/na; | 
| 570 |  | ar[i][0] = cp[0] + tcos(phi)*hrad + 0.5; | 
| 571 |  | ar[i][1] = cp[1] + tsin(phi)*vrad + 0.5; | 
| 572 |  | ar[i][2] = dv; | 
| 619 |  | n = rise + run; | 
| 620 |  | while (n--)                     /* run out arm, checking depth */ | 
| 621 |  | if (run2 > rise2) { | 
| 583 | – | if (depthchange(vp, x, y, x+xstep, y)) | 
| 584 | – | break; | 
| 622 |  | x += xstep; | 
| 623 |  | rise2 += rise; | 
| 624 | < | } else { | 
| 588 | < | if (depthchange(vp, x, y, x, y+ystep)) | 
| 624 | > | if (depthchange(vp, x-xstep, y, x, y)) | 
| 625 |  | break; | 
| 626 | + | } else { | 
| 627 |  | y += ystep; | 
| 628 |  | run2 += run; | 
| 629 | + | if (depthchange(vp, x, y-ystep, x, y)) | 
| 630 | + | break; | 
| 631 |  | } | 
| 632 |  | if (n < 0)                      /* found something? */ | 
| 633 |  | return; | 
| 651 |  | } | 
| 652 |  |  | 
| 653 |  |  | 
| 654 | + | static int | 
| 655 | + | blockedge(vp, bi0, bi1)                 /* check for edge between blocks? */ | 
| 656 | + | register struct ODview  *vp; | 
| 657 | + | register int    bi0, bi1; | 
| 658 | + | { | 
| 659 | + | if (bi1 == bi0) | 
| 660 | + | return(0);              /* same block */ | 
| 661 | + | if (bi1 < 0) | 
| 662 | + | return(1);              /* end off view */ | 
| 663 | + | if (CHK4(vp->emap, bi1)) | 
| 664 | + | return(1);              /* end block has edges */ | 
| 665 | + | if (bi1 == bi0+1 || bi1 == bi0-1 || | 
| 666 | + | bi1 == bi0+vp->hlow || bi1 == bi0-vp->hlow) | 
| 667 | + | return(0);              /* end in adjacent block -- no edges */ | 
| 668 | + | return(1);                      /* conservative for rarer case */ | 
| 669 | + | } | 
| 670 | + |  | 
| 671 | + |  | 
| 672 |  | odDrawSamp(vn, id)                      /* draw view sample */ | 
| 673 |  | int     vn; | 
| 674 |  | register int    id; | 
| 675 |  | { | 
| 676 |  | GLshort arm[MAXFAN][3]; | 
| 677 | < | int     narms, blockindex, bi1; | 
| 677 | > | int     narms, blockindex; | 
| 678 |  | register struct ODview  *vp; | 
| 679 |  | double  size; | 
| 680 |  | int     home_edges; | 
| 691 |  | if (vp->emap != NULL) {         /* check for edge collisions */ | 
| 692 |  | home_edges = CHK4(vp->emap, blockindex); | 
| 693 |  | for (i = 0; i < narms; i++) | 
| 694 | < | /* the following test is flawed, because we could | 
| 695 | < | * be passing through a block on a diagonal run */ | 
| 639 | < | if (home_edges || | 
| 640 | < | ( (bi1 = getblock(vp, arm[i][0], arm[i][1])) | 
| 641 | < | != blockindex && | 
| 642 | < | (bi1 < 0 || CHK4(vp->emap, bi1)) )) | 
| 694 | > | if (home_edges || blockedge(vp, blockindex, | 
| 695 | > | getblock(vp, arm[i][0], arm[i][1]))) | 
| 696 |  | clip_edge(arm[i], odS.ip[id], vp); | 
| 697 |  | } | 
| 698 |  | /* draw triangle fan */ |