--- ray/src/hd/rhdisp.c 1997/12/18 18:14:15 3.16 +++ ray/src/hd/rhdisp.c 1998/08/26 13:06:09 3.32 @@ -1,4 +1,4 @@ -/* Copyright (c) 1997 Silicon Graphics, Inc. */ +/* Copyright (c) 1998 Silicon Graphics, Inc. */ #ifndef lint static char SCCSid[] = "$SunId$ SGI"; @@ -24,10 +24,22 @@ char cmdlist[DC_NCMDS][8] = DC_INIT; int imm_mode = 0; /* bundles are being delivered immediately */ +int do_outside = 0; /* render from outside sections */ + +double eyesepdist = 1; /* eye separation distance */ + char *progname; /* global argv[0] */ FILE *sstdin, *sstdout; /* server's standard input and output */ +#ifdef DEBUG +#include +extern time_t time(); +static time_t tmodesw; +static time_t timm, tadd; +static long nimmrays, naddrays; +#endif + #define RDY_SRV 01 #define RDY_DEV 02 #define RDY_SIN 04 @@ -53,9 +65,21 @@ char *argv[]; sstdin = fdopen(inp, "r"); /* set command error vector */ erract[COMMAND].pf = eputs; +#ifdef DEBUG + tmodesw = time(NULL); +#endif /* enter main loop */ do { rdy = disp_wait(); + if (rdy & RDY_SRV) { /* process server result */ + res = serv_result(); + if (pause && res != DS_SHUTDOWN) { + serv_request(DR_ATTEN, 0, NULL); + while ((res = serv_result()) != DS_ACKNOW && + res != DS_SHUTDOWN) + ; + } + } if (rdy & RDY_DEV) { /* user input from driver */ inp = dev_input(); if (inp & DFL(DC_SETVIEW)) @@ -64,14 +88,6 @@ char *argv[]; printview(); if (inp & DFL(DC_LASTVIEW)) new_view(NULL); - if (inp & DFL(DC_RESUME)) { - serv_request(DR_NOOP, 0, NULL); - pause = 0; - } - if (inp & DFL(DC_PAUSE)) - pause = 1; - if (inp & DFL(DC_REDRAW)) - imm_mode = beam_sync() > 0; if (inp & DFL(DC_KILL)) { serv_request(DR_KILL, 0, NULL); pause = 0; @@ -82,6 +98,14 @@ char *argv[]; serv_request(DR_RESTART, 0, NULL); pause = 0; } + if (inp & DFL(DC_RESUME)) { + serv_request(DR_NOOP, 0, NULL); + pause = 0; + } + if (inp & DFL(DC_PAUSE)) + pause = 1; + if (inp & DFL(DC_REDRAW)) + imm_mode = beam_sync(1) > 0; if (inp & DFL(DC_QUIT)) serv_request(DR_SHUTDOWN, 0, NULL); } @@ -98,16 +122,17 @@ char *argv[]; pause = 0; break; } - if (rdy & RDY_SRV) { /* process server result */ - res = serv_result(); - if (pause && res != DS_SHUTDOWN) { - serv_request(DR_ATTEN, 0, NULL); - while ((res = serv_result()) != DS_ACKNOW && - res != DS_SHUTDOWN) - ; - } - } } while (res != DS_SHUTDOWN); +#ifdef DEBUG + if (timm && nimmrays) + fprintf(stderr, + "%s: %.1f rays recalled/second (%ld rays total)\n", + progname, (double)nimmrays/timm, nimmrays); + if (tadd && naddrays) + fprintf(stderr, + "%s: %.1f rays calculated/second (%ld rays total)\n", + progname, (double)naddrays/tadd, naddrays); +#endif /* all done */ quit(0); } @@ -121,13 +146,18 @@ disp_wait() /* wait for more input */ int n; register int i; /* see if we can avoid select call */ + flgs = 0; /* flag what's ready already */ if (imm_mode || stdin->_cnt > 0) - return(RDY_SRV); + flgs |= RDY_SRV; if (sstdin != NULL && sstdin->_cnt > 0) - return(RDY_SIN); - if (dev_flush()) + flgs |= RDY_SIN; + if (odev.inpready) + flgs |= RDY_DEV; + if (flgs) /* got something? */ + return(flgs); + if (dev_flush()) /* else flush output & check keyboard+mouse */ return(RDY_DEV); - /* make the call */ + /* if nothing, we need to call select */ FD_ZERO(&readset); FD_ZERO(&errset); FD_SET(0, &readset); FD_SET(0, &errset); @@ -136,6 +166,7 @@ disp_wait() /* wait for more input */ n = odev.ifd+1; if (sstdin != NULL) { FD_SET(fileno(sstdin), &readset); + FD_SET(fileno(sstdin), &errset); if (fileno(sstdin) >= n) n = fileno(sstdin) + 1; } @@ -145,12 +176,12 @@ disp_wait() /* wait for more input */ return(0); error(SYSTEM, "select call failure in disp_wait"); } - flgs = 0; /* flag what's ready */ if (FD_ISSET(0, &readset) || FD_ISSET(0, &errset)) flgs |= RDY_SRV; if (FD_ISSET(odev.ifd, &readset) || FD_ISSET(odev.ifd, &errset)) flgs |= RDY_DEV; - if (sstdin != NULL && FD_ISSET(fileno(sstdin), &readset)) + if (sstdin != NULL && (FD_ISSET(fileno(sstdin), &readset) || + FD_ISSET(fileno(sstdin), &errset))) flgs |= RDY_SIN; return(flgs); } @@ -160,6 +191,7 @@ add_holo(hdg) /* register a new holodeck section */ HDGRID *hdg; { VIEW nv; + double d; register int hd; for (hd = 0; hd < HDMAX && hdlist[hd] != NULL; hd++) @@ -180,6 +212,12 @@ HDGRID *hdg; VSUM(nv.vp, nv.vp, hdlist[0]->xv[2], 0.5); fcross(nv.vdir, hdlist[0]->xv[1], hdlist[0]->xv[2]); VCOPY(nv.vup, hdlist[0]->xv[2]); + if (do_outside) { + normalize(nv.vdir); + d = VLEN(hdlist[0]->xv[1]); + d += VLEN(hdlist[0]->xv[2]); + VSUM(nv.vp, nv.vp, nv.vdir, -d); + } new_view(&nv); } @@ -200,9 +238,16 @@ register PACKHEAD *p; for (i = p->nr; i--; ) { hdray(ro, rd, hdlist[p->hd], gc, packra(p)[i].r); d = hddepth(hdlist[p->hd], packra(p)[i].d); - VSUM(wp, ro, rd, d); /* might be behind viewpoint */ - dev_value(packra(p)[i].v, wp, rd); + if (d < .99*FHUGE) { + VSUM(wp, ro, rd, d); /* might be behind viewpoint */ + dev_value(packra(p)[i].v, rd, wp); + } else + dev_value(packra(p)[i].v, rd, NULL); } +#ifdef DEBUG + if (imm_mode) nimmrays += p->nr; + else naddrays += p->nr; +#endif } @@ -211,6 +256,8 @@ register VIEW *v; { static VIEW viewhist[VIEWHISTLEN]; static unsigned nhist; + VIEW *dv; + int i, res[2]; char *err; /* restore previous view? */ if (v == NULL) { @@ -220,20 +267,30 @@ register VIEW *v; while (nhist < VIEWHISTLEN && viewhist[nhist].type) nhist++; v = viewhist + ((nhist-1)%VIEWHISTLEN); - } else if ((err = setview(v)) != NULL) { + } else +again: + if ((err = setview(v)) != NULL) { error(COMMAND, err); return; } -again: if (v->type == VT_PAR) { error(COMMAND, "cannot handle parallel views"); return; } - if (!dev_view(v)) /* update display driver */ + if (!dev_view(v)) /* notify display driver */ goto again; dev_flush(); /* update screen */ - if (!beam_view(v)) /* update beam list */ - goto again; + beam_init(0); /* compute new beam set */ + for (i = 0; (dv = dev_auxview(i, res)) != NULL; i++) + if (!beam_view(dv, res[0], res[1])) { + if (!nhist) { + error(COMMAND, "invalid starting view"); + return; + } + copystruct(v, viewhist + ((nhist-1)%VIEWHISTLEN)); + goto again; + } + beam_sync(0); /* update server */ /* record new view */ if (v < viewhist || v >= viewhist+VIEWHISTLEN) { copystruct(viewhist + (nhist%VIEWHISTLEN), v); @@ -246,26 +303,28 @@ int usr_input() /* get user input and process it */ { VIEW vparams; - char cmd[128]; + char cmd[256]; register char *args; register int i; - if (fgets(cmd, sizeof(cmd), sstdin) == NULL) - return(DC_QUIT); + if (fgets(cmd, sizeof(cmd), sstdin) == NULL) { + fclose(sstdin); + sstdin = NULL; + return(-1); + } + if (*cmd == '\n') + return(DC_RESUME); for (args = cmd; *args && !isspace(*args); args++) ; while (isspace(*args)) *args++ = '\0'; - if (!*cmd) - return(DC_RESUME); if (*args && args[i=strlen(args)-1] == '\n') args[i] = '\0'; for (i = 0; i < DC_NCMDS; i++) if (!strcmp(cmd, cmdlist[i])) break; if (i >= DC_NCMDS) { - sprintf(errmsg, "unknown command: %s", cmd); - error(COMMAND, errmsg); + dev_auxcom(cmd, args); return(-1); } switch (i) { @@ -287,7 +346,8 @@ usr_input() /* get user input and process it */ /* handled in main() */ break; case DC_REDRAW: /* redraw from server */ - imm_mode = beam_sync() > 0; + imm_mode = beam_sync(1) > 0; + dev_clear(); break; case DC_KILL: /* kill rtrace process(es) */ serv_request(DR_KILL, 0, NULL); @@ -351,25 +411,39 @@ serv_result() /* get next server result and process error(INTERNAL, "bad holodeck record from server"); add_holo((HDGRID *)buf); break; + case DS_OUTSECT: + do_outside = 1; + goto noargs; + case DS_EYESEP: + if (msg.nbytes <= 1 || (eyesepdist = atof(buf)) <= FTINY) + error(INTERNAL, "bad eye separation from server"); + break; case DS_STARTIMM: case DS_ENDIMM: +#ifdef DEBUG + if (imm_mode != (msg.type==DS_STARTIMM)) { + time_t tnow = time(NULL); + if (imm_mode) timm += tnow - tmodesw; + else tadd += tnow - tmodesw; + tmodesw = tnow; + } +#endif imm_mode = msg.type==DS_STARTIMM; - if (msg.type == DS_ENDIMM) - dev_flush(); /* update display NOW */ - /* fall through */ + goto noargs; case DS_ACKNOW: case DS_SHUTDOWN: - if (msg.nbytes) { - sprintf(errmsg, - "unexpected body with server message %d", - msg.type); - error(INTERNAL, errmsg); - } - break; + goto noargs; default: error(INTERNAL, "unrecognized result from server process"); } return(msg.type); /* return message type */ +noargs: + if (msg.nbytes) { + sprintf(errmsg, "unexpected body with server message %d", + msg.type); + error(INTERNAL, errmsg); + } + return(msg.type); readerr: if (feof(stdin)) error(SYSTEM, "server process died");