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

Comparing ray/src/hd/rhd_x11.c (file contents):
Revision 3.2 by gregl, Thu Nov 20 18:04:28 1997 UTC vs.
Revision 3.22 by gregl, Sun Jan 4 08:32:01 1998 UTC

# Line 18 | Line 18 | static char SCCSid[] = "$SunId$ SGI";
18  
19   #include  "x11icon.h"
20  
21 < #define CTRL(c)         ((c)-'@')
21 > #ifndef RAYQLEN
22 > #define RAYQLEN         50000           /* max. rays to queue before flush */
23 > #endif
24  
25 + #ifndef FEQ
26 + #define FEQ(a,b)        ((a)-(b) <= FTINY && (a)-(b) >= -FTINY)
27 + #endif
28 +
29   #define GAMMA           2.2             /* default gamma correction */
30  
31 < #define MOVPCT          10              /* percent distance to move */
31 > #define MOVPCT          7               /* percent distance to move /frame */
32   #define MOVDIR(b)       ((b)==Button1 ? 1 : (b)==Button2 ? 0 : -1)
33 + #define MOVDEG          (-5)            /* degrees to orbit CW/down /frame */
34 + #define MOVORB(s)       ((s)&ShiftMask ? 1 : (s)&ControlMask ? -1 : 0)
35  
36   #define MINWIDTH        480             /* minimum graphics window width */
37   #define MINHEIGHT       400             /* minimum graphics window height */
# Line 49 | Line 57 | static unsigned long  *pixval = NULL;  /* allocated pix
57   static unsigned long  ourblack=0, ourwhite=1;
58  
59   static Display  *ourdisplay = NULL;     /* our display */
52
60   static XVisualInfo  ourvinfo;           /* our visual information */
54
61   static Window  gwind = 0;               /* our graphics window */
56
62   static GC  ourgc = 0;                   /* our graphics context for drawing */
58
63   static Colormap ourmap = 0;             /* our color map */
64  
65   static double   pwidth, pheight;        /* pixel dimensions (mm) */
# Line 81 | Line 85 | mytmflags()                    /* figure out tone mapping flags */
85          for (cp = tail; *cp && *cp != '.'; cp++)
86                  ;
87          if (cp-tail == 3 && !strncmp(tail, "x11", 3))
88 <                return(TM_F_CAMERA);
88 >                return(TM_F_CAMERA|TM_F_NOSTDERR);
89          if (cp-tail == 4 && !strncmp(tail, "x11h", 4))
90 <                return(TM_F_HUMAN);
90 >                return(TM_F_HUMAN|TM_F_NOSTDERR);
91          error(USER, "illegal driver name");
92   }
93  
# Line 99 | Line 103 | char  *id;
103          XWMHints  ourxwmhints;
104          XSizeHints      oursizhints;
105                                          /* set quadtree globals */
106 <        qtDepthEps = 0.02;
103 <        qtMinNodesiz = 1;
106 >        qtMinNodesiz = 2;
107                                          /* open display server */
108          ourdisplay = XOpenDisplay(NULL);
109          if (ourdisplay == NULL)
# Line 159 | Line 162 | char  *id;
162          oursizhints.min_height = MINHEIGHT;
163          oursizhints.flags = PMinSize;
164          XSetNormalHints(ourdisplay, gwind, &oursizhints);
162                                        /* map the window and get its size */
163        XMapWindow(ourdisplay, gwind);
164        dev_input();
165                                        /* allocate our leaf pile */
166        if (!qtAllocLeaves(DisplayWidth(ourdisplay,ourscreen) *
167                        DisplayHeight(ourdisplay,ourscreen) /
168                        (qtMinNodesiz*qtMinNodesiz)))
169                error(SYSTEM, "insufficient memory for leaf storage");
170
165                                          /* figure out sensible view */
166          pwidth = (double)DisplayWidthMM(ourdisplay, ourscreen) /
167                          DisplayWidth(ourdisplay, ourscreen);
168          pheight = (double)DisplayHeightMM(ourdisplay, ourscreen) /
169                          DisplayHeight(ourdisplay, ourscreen);
170          copystruct(&odev.v, &stdview);
177        odev.name = id;
171          odev.v.type = VT_PER;
172 <        odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
173 <        odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);
172 >                                        /* map the window and get its size */
173 >        XMapWindow(ourdisplay, gwind);
174 >        dev_input();                    /* sets size and view angles */
175 >                                        /* allocate our leaf pile */
176 >        if (!qtAllocLeaves(DisplayWidth(ourdisplay,ourscreen) *
177 >                        DisplayHeight(ourdisplay,ourscreen) * 3 /
178 >                        (qtMinNodesiz*qtMinNodesiz*2)))
179 >                error(SYSTEM, "insufficient memory for leaf storage");
180 >        odev.name = id;
181          odev.ifd = ConnectionNumber(ourdisplay);
182   }
183  
# Line 199 | Line 199 | dev_close()                    /* close our display */
199   }
200  
201  
202 + int
203   dev_view(nv)                    /* assign new driver view */
204   VIEW    *nv;
205   {
206 <        if (nv != &odev.v)
206 >        if (nv->type == VT_PAR ||               /* check view legality */
207 >                        nv->horiz > 160. || nv->vert > 160.) {
208 >                error(COMMAND, "illegal view type/angle");
209 >                nv->type = VT_PER;
210 >                nv->horiz = odev.v.horiz;
211 >                nv->vert = odev.v.vert;
212 >                return(0);
213 >        }
214 >        if (nv->vfore > FTINY) {
215 >                error(COMMAND, "cannot handle fore clipping");
216 >                nv->vfore = 0.;
217 >                return(0);
218 >        }
219 >        if (nv != &odev.v) {
220 >                if (!FEQ(nv->horiz,odev.v.horiz) ||     /* resize window? */
221 >                                !FEQ(nv->vert,odev.v.vert)) {
222 >                        int     dw = DisplayWidth(ourdisplay,ourscreen);
223 >                        int     dh = DisplayHeight(ourdisplay,ourscreen);
224 >
225 >                        dw -= 25;       /* for window frame */
226 >                        dh -= 50;
227 >                        odev.hres = 2.*VIEWDIST/pwidth *
228 >                                        tan(PI/180./2.*nv->horiz);
229 >                        odev.vres = 2.*VIEWDIST/pheight *
230 >                                        tan(PI/180./2.*nv->vert);
231 >                        if (odev.hres > dw) {
232 >                                odev.vres = dw * odev.vres / odev.hres;
233 >                                odev.hres = dw;
234 >                        }
235 >                        if (odev.vres > dh) {
236 >                                odev.hres = dh * odev.hres / odev.vres;
237 >                                odev.vres = dh;
238 >                        }
239 >                        XResizeWindow(ourdisplay, gwind, odev.hres, odev.vres);
240 >                        dev_input();    /* wait for resize event */
241 >                }
242                  copystruct(&odev.v, nv);
243 +        }
244          qtReplant();
245 +        return(1);
246   }
247  
248  
# Line 212 | Line 250 | int
250   dev_input()                     /* get X11 input */
251   {
252          inpresflags = 0;
253 +
254          do
255                  getevent();
256  
# Line 243 | Line 282 | int
282   dev_flush()                     /* flush output */
283   {
284          qtUpdate();
285 +        rayqleft = RAYQLEN;
286          return(XPending(ourdisplay));
287   }
288  
# Line 379 | Line 419 | getevent()                     /* get next event */
419  
420  
421   static
422 < moveview(dx, dy, move)          /* move our view */
423 < int     dx, dy, move;
422 > ilclip(dp, wp)                  /* clip world coordinates to device */
423 > int     dp[2][2];
424 > FVECT   wp[2];
425   {
426 +        static FVECT    vmin = {0.,0.,0.}, vmax = {1.,1.,FHUGE};
427 +        FVECT   ip[2];
428 +                                /* not exactly right, but who cares? */
429 +        viewloc(ip[0], &odev.v, wp[0]);
430 +        viewloc(ip[1], &odev.v, wp[1]);
431 +        if (!clip(ip[0], ip[1], vmin, vmax))
432 +                return(0);
433 +        dp[0][0] = ip[0][0]*odev.hres;
434 +        dp[0][1] = ip[0][1]*odev.vres;
435 +        dp[1][0] = ip[1][0]*odev.hres;
436 +        dp[1][1] = ip[1][1]*odev.vres;
437 +        return(1);
438 + }
439 +
440 +
441 + static
442 + draw3dline(wp)                  /* draw 3d line in world coordinates */
443 + FVECT   wp[2];
444 + {
445 +        int     dp[2][2];
446 +
447 +        if (!ilclip(dp, wp))
448 +                return;
449 +        XDrawLine(ourdisplay, gwind, ourgc,
450 +                        dp[0][0], odev.vres-1 - dp[0][1],
451 +                        dp[1][0], odev.vres-1 - dp[1][1]);
452 + }
453 +
454 +
455 + static
456 + draw_grids()                    /* draw holodeck section grids */
457 + {
458 +        static BYTE     gridrgb[3] = {0x0, 0xff, 0xff};
459 +        unsigned long  pixel;
460 +
461 +        if (!mapped)
462 +                return;
463 +        if (ncolors > 0)
464 +                pixel = pixval[get_pixel(gridrgb, xnewcolr)];
465 +        else
466 +                pixel = true_pixel(gridrgb);
467 +        XSetForeground(ourdisplay, ourgc, pixel);
468 +                                        /* draw each grid line */
469 +        gridlines(draw3dline);
470 + }
471 +
472 +
473 + static
474 + moveview(dx, dy, mov, orb)      /* move our view */
475 + int     dx, dy, mov, orb;
476 + {
477          VIEW    nv;
478 +        FVECT   odir, v1;
479          double  d;
480 <        register int    i;
480 >        register int    li;
481                                  /* start with old view */
482          copystruct(&nv, &odev.v);
483                                  /* change view direction */
484 <        if (move) {
485 <                register RLEAF  *lp;
393 <                if ((lp = qtFindLeaf(dx, dy)) == NULL)
484 >        if (mov | orb) {
485 >                if ((li = qtFindLeaf(dx, dy)) < 0)
486                          return(0);      /* not on window */
487 <                for (i = 0; i < 3; i++)
396 <                        nv.vdir[i] = lp->wp[i] - nv.vp[i];
487 >                VSUM(odir, qtL.wp[li], nv.vp, -1.);
488          } else {
489                  if (viewray(nv.vp, nv.vdir, &odev.v,
490                                  (dx+.5)/odev.hres, (dy+.5)/odev.vres) < -FTINY)
491                          return(0);      /* outside view */
492          }
493 <                                /* move viewpoint */
494 <        if (move > 0)
495 <                for (i = 0; i < 3; i++)
496 <                        nv.vp[i] += MOVPCT/100. * nv.vdir[i];
497 <        else if (move < 0)
498 <                for (i = 0; i < 3; i++)
499 <                        nv.vp[i] -= MOVPCT/100. * nv.vdir[i];
500 <        if (move && headlocked) {
501 <                d = 0;          /* bring head back to same height */
502 <                for (i = 0; i < 3; i++)
503 <                        d += odev.v.vup[i] * (odev.v.vp[i] - nv.vp[i]);
504 <                for (i = 0; i < 3; i++)
505 <                        nv.vp[i] += d * odev.v.vup[i];
493 >        if (orb && mov) {               /* orbit left/right */
494 >                spinvector(odir, odir, nv.vup, d=MOVDEG*PI/180.*mov);
495 >                VSUM(nv.vp, qtL.wp[li], odir, -1.);
496 >                spinvector(nv.vdir, nv.vdir, nv.vup, d);
497 >        } else if (orb) {               /* orbit up/down */
498 >                fcross(v1, odir, nv.vup);
499 >                if (normalize(v1) == 0.)
500 >                        return(0);
501 >                spinvector(odir, odir, v1, d=MOVDEG*PI/180.*orb);
502 >                VSUM(nv.vp, qtL.wp[li], odir, -1.);
503 >                spinvector(nv.vdir, nv.vdir, v1, d);
504 >        } else if (mov) {               /* move forward/backward */
505 >                d = MOVPCT/100. * mov;
506 >                VSUM(nv.vp, nv.vp, odir, d);
507          }
508 +        if (!mov ^ !orb && headlocked) {        /* restore head height */
509 +                VSUM(v1, odev.v.vp, nv.vp, -1.);
510 +                d = DOT(v1, odev.v.vup);
511 +                VSUM(nv.vp, nv.vp, odev.v.vup, d);
512 +        }
513          if (setview(&nv) != NULL)
514                  return(0);      /* illegal view */
515          dev_view(&nv);
516 <        inpresflags |= DEV_NEWVIEW;
516 >        inpresflags |= DFL(DC_SETVIEW);
517          return(1);
518   }
519  
# Line 425 | Line 522 | static
522   getmove(ebut)                           /* get view change */
523   XButtonPressedEvent     *ebut;
524   {
525 <        int     whichbutton = ebut->button;
525 >        int     movdir = MOVDIR(ebut->button);
526 >        int     movorb = MOVORB(ebut->state);
527          int     oldnodesiz = qtMinNodesiz;
528          Window  rootw, childw;
529          int     rootx, rooty, wx, wy;
530          unsigned int    statemask;
531  
532          qtMinNodesiz = 16;              /* for quicker update */
533 +        XNoOp(ourdisplay);
534  
535 <        do {
535 >        while (!XCheckMaskEvent(ourdisplay,
536 >                        ButtonReleaseMask, levptr(XEvent))) {
537 >
538                  if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw,
539                                  &rootx, &rooty, &wx, &wy, &statemask))
540                          break;          /* on another screen */
541  
542 <                if (!moveview(wx, odev.vres-1-wy, MOVDIR(whichbutton)))
542 >                if (!moveview(wx, odev.vres-1-wy, movdir, movorb)) {
543                          sleep(1);
544 <
545 <        } while (!XCheckMaskEvent(ourdisplay,
546 <                        ButtonReleaseMask, levptr(XEvent)));
547 <
548 <        if (!(inpresflags & DEV_NEWVIEW)) {     /* do final motion */
549 <                whichbutton = levptr(XButtonReleasedEvent)->button;
544 >                        continue;
545 >                }
546 >                XClearWindow(ourdisplay, gwind);
547 >                qtUpdate();
548 >                draw_grids();
549 >        }
550 >        if (!(inpresflags & DFL(DC_SETVIEW))) { /* do final motion */
551 >                movdir = MOVDIR(levptr(XButtonReleasedEvent)->button);
552                  wx = levptr(XButtonReleasedEvent)->x;
553                  wy = levptr(XButtonReleasedEvent)->y;
554 <                moveview(wx, odev.vres-1-wy, MOVDIR(whichbutton));
554 >                moveview(wx, odev.vres-1-wy, movdir, movorb);
555          }
556 +        dev_flush();
557  
558          qtMinNodesiz = oldnodesiz;      /* restore quadtree resolution */
559   }
# Line 472 | Line 576 | register XKeyPressedEvent  *ekey;
576          case 'H':                       /* turn off height motion lock */
577                  headlocked = 0;
578                  return;
579 <        case CTRL('Z'):
579 >        case 'l':                       /* retrieve last view */
580 >                inpresflags |= DFL(DC_LASTVIEW);
581 >                return;
582          case 'p':                       /* pause computation */
583 <                inpresflags |= DEV_WAIT;
583 >                inpresflags |= DFL(DC_PAUSE);
584                  return;
585 +        case 'v':                       /* spit out view */
586 +                inpresflags |= DFL(DC_GETVIEW);
587 +                return;
588          case '\n':
589 <        case '\r':                      /* release */
589 >        case '\r':                      /* resume computation */
590 >                inpresflags |= DFL(DC_RESUME);
591                  return;
592 <        case CTRL('D'):
593 <        case 'Q':
592 >        case CTRL('R'):                 /* redraw screen */
593 >                if (ncolors > 0)
594 >                        new_ctab(ncolors);
595 >                qtRedraw(0, 0, odev.hres, odev.vres);
596 >                return;
597 >        case CTRL('L'):                 /* refresh from server */
598 >                if (inpresflags & DFL(DC_REDRAW))
599 >                        return;
600 >                XClearWindow(ourdisplay, gwind);
601 >                draw_grids();
602 >                XFlush(ourdisplay);
603 >                qtCompost(100);                 /* unload the old tree */
604 >                if (ncolors > 0)
605 >                        new_ctab(ncolors);
606 >                inpresflags |= DFL(DC_REDRAW);  /* resend values from server */
607 >                rayqleft = 0;                   /* hold off update */
608 >                return;
609 >        case 'K':                       /* kill rtrace process(es) */
610 >                inpresflags |= DFL(DC_KILL);
611 >                break;
612 >        case 'R':                       /* restart rtrace */
613 >                inpresflags |= DFL(DC_RESTART);
614 >                break;
615 >        case 'C':                       /* clobber holodeck */
616 >                inpresflags |= DFL(DC_CLOBBER);
617 >                break;
618          case 'q':                       /* quit the program */
619 <                inpresflags |= DEV_SHUTDOWN;
619 >                inpresflags |= DFL(DC_QUIT);
620                  return;
621          default:
622                  XBell(ourdisplay, 0);
# Line 498 | Line 632 | register XExposeEvent  *eexp;
632          if (odev.hres == 0 || odev.vres == 0) { /* first exposure */
633                  odev.hres = eexp->width;
634                  odev.vres = eexp->height;
501                inpresflags |= DEV_NEWSIZE;
635          }
636          qtRedraw(eexp->x, odev.vres - eexp->y - eexp->height,
637                          eexp->x + eexp->width, odev.vres - eexp->y);
# Line 512 | Line 645 | register XConfigureEvent  *ersz;
645          if (ersz->width == odev.hres && ersz->height == odev.vres)
646                  return;
647  
515        if (odev.hres != 0 && odev.vres != 0) {
516                odev.v.horiz = 2.*180./PI * atan(
517                        tan(PI/180./2.*odev.v.horiz) * ersz->width/odev.hres );
518                odev.v.vert = 2.*180./PI * atan(
519                        tan(PI/180./2.*odev.v.vert) * ersz->height/odev.vres );
520                inpresflags |= DEV_NEWVIEW;
521        }
648          odev.hres = ersz->width;
649          odev.vres = ersz->height;
650  
651 <        inpresflags |= DEV_NEWSIZE;
651 >        odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
652 >        odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);
653 >
654 >        inpresflags |= DFL(DC_SETVIEW);
655   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines