--- ray/src/rt/rv3.c 1989/04/05 09:38:12 1.2 +++ ray/src/rt/rv3.c 1990/02/22 11:46:15 1.13 @@ -12,11 +12,111 @@ static char SCCSid[] = "$SunId$ LBL"; #include "ray.h" +#include "octree.h" + #include "rpaint.h" #include "random.h" +#ifndef WFLUSH +#define WFLUSH 30 /* flush after this many rays */ +#endif + +getrect(s, r) /* get a box */ +char *s; +register RECT *r; +{ + int x0, y0, x1, y1; + + if (*s && !strncmp(s, "all", strlen(s))) { + r->l = r->d = 0; + r->r = hresolu; + r->u = vresolu; + return(0); + } + if (sscanf(s, "%d %d %d %d", &x0, &y0, &x1, &y1) != 4) { + if (dev->getcur == NULL) + return(-1); + (*dev->comout)("Pick first corner\n"); + if ((*dev->getcur)(&x0, &y0) == ABORT) + return(-1); + (*dev->comout)("Pick second corner\n"); + if ((*dev->getcur)(&x1, &y1) == ABORT) + return(-1); + } + if (x0 < x1) { + r->l = x0; + r->r = x1; + } else { + r->l = x1; + r->r = x0; + } + if (y0 < y1) { + r->d = y0; + r->u = y1; + } else { + r->d = y1; + r->u = y0; + } + if (r->l < 0) r->l = 0; + if (r->d < 0) r->d = 0; + if (r->r > hresolu) r->r = hresolu; + if (r->u > vresolu) r->u = vresolu; + if (r->l > r->r) r->l = r->r; + if (r->d > r->u) r->d = r->u; + return(0); +} + + +getinterest(s, direc, vec, mp) /* get area of interest */ +char *s; +int direc; +FVECT vec; +double *mp; +{ + int x, y; + RAY thisray; + register int i; + + if (sscanf(s, "%lf", mp) != 1) + *mp = 1.0; + else if (*mp < -FTINY) /* negative zoom is reduction */ + *mp = -1.0 / *mp; + else if (*mp <= FTINY) { /* too small */ + error(COMMAND, "illegal magnification"); + return(-1); + } + if (sscanf(s, "%*lf %lf %lf %lf", &vec[0], &vec[1], &vec[2]) != 3) { + if (dev->getcur == NULL) + return(-1); + (*dev->comout)("Pick view center\n"); + if ((*dev->getcur)(&x, &y) == ABORT) + return(-1); + viewray(thisray.rorg, thisray.rdir, &ourview, + (x+.5)/hresolu, (y+.5)/vresolu); + if (!direc || ourview.type == VT_PAR) { + rayorigin(&thisray, NULL, PRIMARY, 1.0); + if (!localhit(&thisray, &thescene)) { + error(COMMAND, "not a local object"); + return(-1); + } + } + if (direc) + if (ourview.type == VT_PAR) + for (i = 0; i < 3; i++) + vec[i] = thisray.rop[i] - ourview.vp[i]; + else + VCOPY(vec, thisray.rdir); + else + VCOPY(vec, thisray.rop); + } else if (direc) + for (i = 0; i < 3; i++) + vec[i] -= ourview.vp[i]; + return(0); +} + + float * /* keep consistent with COLOR typedef */ greyof(col) /* convert color to greyscale */ register COLOR col; @@ -34,6 +134,8 @@ paint(p, xmin, ymin, xmax, ymax) /* compute and paint register PNODE *p; int xmin, ymin, xmax, ymax; { + extern long nrays; + static long lastflush = 0; static RAY thisray; double h, v; register int i; @@ -46,9 +148,11 @@ int xmin, ymin, xmax, ymax; } /* jitter ray direction */ p->x = h = xmin + (xmax-xmin)*frandom(); + h /= hresolu; p->y = v = ymin + (ymax-ymin)*frandom(); + v /= vresolu; - rayview(thisray.rorg, thisray.rdir, &ourview, h, v); + viewray(thisray.rorg, thisray.rdir, &ourview, h, v); rayorigin(&thisray, NULL, PRIMARY, 1.0); @@ -59,6 +163,11 @@ int xmin, ymin, xmax, ymax; scalecolor(p->v, exposure); (*dev->paintr)(greyscale?greyof(p->v):p->v, xmin, ymin, xmax, ymax); + + if (dev->flush != NULL && nrays - lastflush >= WFLUSH) { + lastflush = nrays; + (*dev->flush)(); + } } @@ -66,24 +175,25 @@ newimage() /* start a new image */ { /* free old image */ freepkids(&ptrunk); - /* set up frame */ - if (ourview.hresolu > dev->xsiz || ourview.vresolu > dev->ysiz) - error(USER, "resolution mismatch"); + /* compute resolution */ + hresolu = dev->xsiz; + vresolu = dev->ysiz; + normaspect(viewaspect(&ourview), &dev->pixaspect, &hresolu, &vresolu); pframe.l = pframe.d = 0; - pframe.r = ourview.hresolu; pframe.u = ourview.vresolu; + pframe.r = hresolu; pframe.u = vresolu; pdepth = 0; /* clear device */ - (*dev->clear)(ourview.hresolu, ourview.vresolu); + (*dev->clear)(hresolu, vresolu); /* get first value */ - paint(&ptrunk, 0, 0, ourview.hresolu, ourview.vresolu); + paint(&ptrunk, 0, 0, hresolu, vresolu); } redraw() /* redraw the image */ { - (*dev->clear)(ourview.hresolu, ourview.vresolu); + (*dev->clear)(hresolu, vresolu); (*dev->comout)("redrawing...\n"); - repaint(0, 0, ourview.hresolu, ourview.vresolu); + repaint(0, 0, hresolu, vresolu); (*dev->comout)("\n"); } @@ -96,7 +206,7 @@ int xmin, ymin, xmax, ymax; reg.l = xmin; reg.r = xmax; reg.d = ymin; reg.u = ymax; - paintrect(&ptrunk, 0, 0, ourview.hresolu, ourview.vresolu, ®); + paintrect(&ptrunk, 0, 0, hresolu, vresolu, ®); } @@ -107,9 +217,6 @@ register RECT *r; { int mx, my; - if (dev->inpready) - return; /* break for input */ - if (xmax - xmin <= 0 || ymax - ymin <= 0) return; @@ -247,38 +354,41 @@ register VIEW *vp; { char *err; - if (vp->hresolu > dev->xsiz || vp->vresolu > dev->ysiz) { - error(COMMAND, "view not set - resolution mismatch"); - } else if ((err = setview(vp)) != NULL) { + if ((err = setview(vp)) != NULL) { sprintf(errmsg, "view not set - %s", err); error(COMMAND, errmsg); - } else if (bcmp(vp, &ourview, sizeof(VIEW))) { - bcopy(&ourview, &oldview, sizeof(VIEW)); - bcopy(vp, &ourview, sizeof(VIEW)); - newimage(); + } else if (bcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) { + copystruct(&oldview, &ourview); + copystruct(&ourview, vp); + newimage(); /* newimage() calls with vp=&ourview! */ } } -moveview(angle, mag, vc) /* move viewpoint */ -double angle, mag; +moveview(angle, elev, mag, vc) /* move viewpoint */ +double angle, elev, mag; FVECT vc; { extern double sqrt(), dist2(); double d; - FVECT v; + FVECT v1; VIEW nv; register int i; VCOPY(nv.vup, ourview.vup); - nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu; + nv.hoff = ourview.hoff; nv.voff = ourview.voff; spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.)); + if (elev != 0.0) { + fcross(v1, ourview.vup, nv.vdir); + normalize(v1); + spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.)); + } if ((nv.type = ourview.type) == VT_PAR) { nv.horiz = ourview.horiz / mag; nv.vert = ourview.vert / mag; + d = 0.0; /* don't move closer */ for (i = 0; i < 3; i++) - v[i] = vc[i] - ourview.vp[i]; - d = DOT(v, ourview.vdir); /* don't move closer */ + d += (vc[i] - ourview.vp[i])*ourview.vdir[i]; } else { nv.horiz = ourview.horiz; nv.vert = ourview.vert;