home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / radsrc22 / src / rt / rview / rv3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-02  |  9.3 KB  |  444 lines

  1. /* Copyright (c) 1987 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)rv3.c 2.3 10/2/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  rv3.c - miscellaneous routines for rview.
  9.  *
  10.  *     5/11/87
  11.  */
  12.  
  13. #include  "ray.h"
  14.  
  15. #include  "octree.h"
  16.  
  17. #include  "rpaint.h"
  18.  
  19. #include  "random.h"
  20.  
  21. #ifndef WFLUSH
  22. #define WFLUSH        30        /* flush after this many rays */
  23. #endif
  24.  
  25. #ifdef  SMLFLT
  26. #define  sscanvec(s,v)    (sscanf(s,"%f %f %f",v,v+1,v+2)==3)
  27. #else
  28. #define  sscanvec(s,v)    (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3)
  29. #endif
  30.  
  31.  
  32. getrect(s, r)                /* get a box */
  33. char  *s;
  34. register RECT  *r;
  35. {
  36.     int  x0, y0, x1, y1;
  37.  
  38.     if (*s && !strncmp(s, "all", strlen(s))) {
  39.         r->l = r->d = 0;
  40.         r->r = hresolu;
  41.         r->u = vresolu;
  42.         return(0);
  43.     }
  44.     if (sscanf(s, "%d %d %d %d", &x0, &y0, &x1, &y1) != 4) {
  45.         if (dev->getcur == NULL)
  46.             return(-1);
  47.         (*dev->comout)("Pick first corner\n");
  48.         if ((*dev->getcur)(&x0, &y0) == ABORT)
  49.             return(-1);
  50.         (*dev->comout)("Pick second corner\n");
  51.         if ((*dev->getcur)(&x1, &y1) == ABORT)
  52.             return(-1);
  53.     }
  54.     if (x0 < x1) {
  55.         r->l = x0;
  56.         r->r = x1;
  57.     } else {
  58.         r->l = x1;
  59.         r->r = x0;
  60.     }
  61.     if (y0 < y1) {
  62.         r->d = y0;
  63.         r->u = y1;
  64.     } else {
  65.         r->d = y1;
  66.         r->u = y0;
  67.     }
  68.     if (r->l < 0) r->l = 0;
  69.     if (r->d < 0) r->d = 0;
  70.     if (r->r > hresolu) r->r = hresolu;
  71.     if (r->u > vresolu) r->u = vresolu;
  72.     if (r->l > r->r) r->l = r->r;
  73.     if (r->d > r->u) r->d = r->u;
  74.     return(0);
  75. }
  76.  
  77.  
  78. getinterest(s, direc, vec, mp)        /* get area of interest */
  79. char  *s;
  80. int  direc;
  81. FVECT  vec;
  82. double  *mp;
  83. {
  84.     int  x, y;
  85.     RAY  thisray;
  86.     register int  i;
  87.  
  88.     if (sscanf(s, "%lf", mp) != 1)
  89.         *mp = 1.0;
  90.     else if (*mp < -FTINY)        /* negative zoom is reduction */
  91.         *mp = -1.0 / *mp;
  92.     else if (*mp <= FTINY) {    /* too small */
  93.         error(COMMAND, "illegal magnification");
  94.         return(-1);
  95.     }
  96.     if (!sscanvec(sskip(s), vec)) {
  97.         if (dev->getcur == NULL)
  98.             return(-1);
  99.         (*dev->comout)("Pick view center\n");
  100.         if ((*dev->getcur)(&x, &y) == ABORT)
  101.             return(-1);
  102.         if (viewray(thisray.rorg, thisray.rdir, &ourview,
  103.                 (x+.5)/hresolu, (y+.5)/vresolu) < 0) {
  104.             error(COMMAND, "not on image");
  105.             return(-1);
  106.         }
  107.         if (!direc || ourview.type == VT_PAR) {
  108.             rayorigin(&thisray, NULL, PRIMARY, 1.0);
  109.             if (!localhit(&thisray, &thescene)) {
  110.                 error(COMMAND, "not a local object");
  111.                 return(-1);
  112.             }
  113.         }
  114.         if (direc)
  115.             if (ourview.type == VT_PAR)
  116.                 for (i = 0; i < 3; i++)
  117.                     vec[i] = thisray.rop[i] - ourview.vp[i];
  118.             else
  119.                 VCOPY(vec, thisray.rdir);
  120.         else
  121.             VCOPY(vec, thisray.rop);
  122.     } else if (direc)
  123.             for (i = 0; i < 3; i++)
  124.                 vec[i] -= ourview.vp[i];
  125.     return(0);
  126. }
  127.  
  128.  
  129. float *        /* keep consistent with COLOR typedef */
  130. greyof(col)                /* convert color to greyscale */
  131. register COLOR  col;
  132. {
  133.     static COLOR  gcol;
  134.     double  b;
  135.  
  136.     b = bright(col);
  137.     setcolor(gcol, b, b, b);
  138.     return(gcol);
  139. }
  140.  
  141.  
  142. paint(p, xmin, ymin, xmax, ymax)    /* compute and paint a rectangle */
  143. register PNODE  *p;
  144. int  xmin, ymin, xmax, ymax;
  145. {
  146.     extern long  nrays;
  147.     static long  lastflush = 0;
  148.     static RAY  thisray;
  149.     double  h, v;
  150.  
  151.     if (xmax - xmin <= 0 || ymax - ymin <= 0) {    /* empty */
  152.         p->x = xmin;
  153.         p->y = ymin;
  154.         setcolor(p->v, 0.0, 0.0, 0.0);
  155.         return;
  156.     }
  157.                         /* jitter ray direction */
  158.     h = xmin + (xmax-xmin)*frandom();
  159.     v = ymin + (ymax-ymin)*frandom();
  160.     
  161.     if (viewray(thisray.rorg, thisray.rdir, &ourview,
  162.             h/hresolu, v/vresolu) < 0) {
  163.         setcolor(thisray.rcol, 0.0, 0.0, 0.0);
  164.     } else {
  165.         rayorigin(&thisray, NULL, PRIMARY, 1.0);
  166.         samplendx++;
  167.         rayvalue(&thisray);
  168.     }
  169.  
  170.     p->x = h;
  171.     p->y = v;
  172.     copycolor(p->v, thisray.rcol);
  173.     scalecolor(p->v, exposure);
  174.  
  175.     (*dev->paintr)(greyscale?greyof(p->v):p->v, xmin, ymin, xmax, ymax);
  176.  
  177.     if (dev->flush != NULL && nrays - lastflush >= WFLUSH) {
  178.         lastflush = nrays;
  179.         (*dev->flush)();
  180.     }
  181. }
  182.  
  183.  
  184. newimage()                /* start a new image */
  185. {
  186.                         /* free old image */
  187.     freepkids(&ptrunk);
  188.                         /* save reserve memory */
  189.     fillreserves();
  190.                         /* compute resolution */
  191.     hresolu = dev->xsiz;
  192.     vresolu = dev->ysiz;
  193.     normaspect(viewaspect(&ourview), &dev->pixaspect, &hresolu, &vresolu);
  194.     pframe.l = pframe.d = 0;
  195.     pframe.r = hresolu; pframe.u = vresolu;
  196.     pdepth = 0;
  197.                         /* clear device */
  198.     (*dev->clear)(hresolu, vresolu);
  199.                         /* get first value */
  200.     paint(&ptrunk, 0, 0, hresolu, vresolu);
  201. }
  202.  
  203.  
  204. redraw()                /* redraw the image */
  205. {
  206.     (*dev->clear)(hresolu, vresolu);
  207.     (*dev->comout)("redrawing...\n");
  208.     repaint(0, 0, hresolu, vresolu);
  209.     (*dev->comout)("\n");
  210. }
  211.  
  212.  
  213. repaint(xmin, ymin, xmax, ymax)            /* repaint a region */
  214. int  xmin, ymin, xmax, ymax;
  215. {
  216.     RECT  reg;
  217.  
  218.     reg.l = xmin; reg.r = xmax;
  219.     reg.d = ymin; reg.u = ymax;
  220.  
  221.     paintrect(&ptrunk, 0, 0, hresolu, vresolu, ®);
  222. }
  223.  
  224.  
  225. paintrect(p, xmin, ymin, xmax, ymax, r)        /* paint picture rectangle */
  226. register PNODE  *p;
  227. int  xmin, ymin, xmax, ymax;
  228. register RECT  *r;
  229. {
  230.     int  mx, my;
  231.  
  232.     if (xmax - xmin <= 0 || ymax - ymin <= 0)
  233.         return;
  234.  
  235.     if (p->kid == NULL) {
  236.         (*dev->paintr)(greyscale?greyof(p->v):p->v,
  237.                 xmin, ymin, xmax, ymax);    /* do this */
  238.         return;
  239.     }
  240.     mx = (xmin + xmax) >> 1;                /* do kids */
  241.     my = (ymin + ymax) >> 1;
  242.     if (mx > r->l) {
  243.         if (my > r->d)
  244.             paintrect(p->kid+DL, xmin, ymin, mx, my, r);
  245.         if (my < r->u)
  246.             paintrect(p->kid+UL, xmin, my, mx, ymax, r);
  247.     }
  248.     if (mx < r->r) {
  249.         if (my > r->d)
  250.             paintrect(p->kid+DR, mx, ymin, xmax, my, r);
  251.         if (my < r->u)
  252.             paintrect(p->kid+UR, mx, my, xmax, ymax, r);
  253.     }
  254. }
  255.  
  256.  
  257. PNODE *
  258. findrect(x, y, p, r, pd)        /* find a rectangle */
  259. int  x, y;
  260. register PNODE  *p;
  261. register RECT  *r;
  262. int  pd;
  263. {
  264.     int  mx, my;
  265.  
  266.     while (p->kid != NULL && pd--) {
  267.  
  268.         mx = (r->l + r->r) >> 1;
  269.         my = (r->d + r->u) >> 1;
  270.  
  271.         if (x < mx) {
  272.             r->r = mx;
  273.             if (y < my) {
  274.                 r->u = my;
  275.                 p = p->kid+DL;
  276.             } else {
  277.                 r->d = my;
  278.                 p = p->kid+UL;
  279.             }
  280.         } else {
  281.             r->l = mx;
  282.             if (y < my) {
  283.                 r->u = my;
  284.                 p = p->kid+DR;
  285.             } else {
  286.                 r->d = my;
  287.                 p = p->kid+UR;
  288.             }
  289.         }
  290.     }
  291.     return(p);
  292. }
  293.  
  294.  
  295. scalepict(p, sf)            /* scale picture values */
  296. register PNODE  *p;
  297. double  sf;
  298. {
  299.     scalecolor(p->v, sf);        /* do this node */
  300.  
  301.     if (p->kid == NULL)
  302.         return;
  303.                     /* do children */
  304.     scalepict(p->kid+DL, sf);
  305.     scalepict(p->kid+DR, sf);
  306.     scalepict(p->kid+UL, sf);
  307.     scalepict(p->kid+UR, sf);
  308. }
  309.  
  310.  
  311. getpictcolrs(yoff, scan, p, xsiz, ysiz)    /* get scanline from picture */
  312. int  yoff;
  313. register COLR  *scan;
  314. register PNODE  *p;
  315. int  xsiz, ysiz;
  316. {
  317.     register int  mx;
  318.     int  my;
  319.  
  320.     if (p->kid == NULL) {            /* do this node */
  321.         setcolr(scan[0], colval(p->v,RED),
  322.                 colval(p->v,GRN),
  323.                 colval(p->v,BLU));
  324.         for (mx = 1; mx < xsiz; mx++)
  325.             copycolr(scan[mx], scan[0]);
  326.         return;
  327.     }
  328.                         /* do kids */
  329.     mx = xsiz >> 1;
  330.     my = ysiz >> 1;
  331.     if (yoff < my) {
  332.         getpictcolrs(yoff, scan, p->kid+DL, mx, my);
  333.         getpictcolrs(yoff, scan+mx, p->kid+DR, xsiz-mx, my);
  334.     } else {
  335.         getpictcolrs(yoff-my, scan, p->kid+UL, mx, ysiz-my);
  336.         getpictcolrs(yoff-my, scan+mx, p->kid+UR, xsiz-mx, ysiz-my);
  337.     }
  338. }
  339.  
  340.  
  341. pcopy(p1, p2)                /* copy paint node p1 into p2 */
  342. register PNODE  *p1, *p2;
  343. {
  344.     copycolor(p2->v, p1->v);
  345.     p2->x = p1->x;
  346.     p2->y = p1->y;
  347. }
  348.  
  349.  
  350. freepkids(p)                /* free pnode's children */
  351. register PNODE  *p;
  352. {
  353.     if (p->kid == NULL)
  354.         return;
  355.     freepkids(p->kid+DL);
  356.     freepkids(p->kid+DR);
  357.     freepkids(p->kid+UL);
  358.     freepkids(p->kid+UR);
  359.     free((char *)p->kid);
  360.     p->kid = NULL;
  361. }
  362.  
  363.  
  364. newview(vp)                /* change viewing parameters */
  365. register VIEW  *vp;
  366. {
  367.     char  *err;
  368.  
  369.     if ((err = setview(vp)) != NULL) {
  370.         sprintf(errmsg, "view not set - %s", err);
  371.         error(COMMAND, errmsg);
  372.     } else if (bcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) {
  373.         copystruct(&oldview, &ourview);
  374.         copystruct(&ourview, vp);
  375.         newimage();
  376.     }
  377. }
  378.  
  379.  
  380. moveview(angle, elev, mag, vc)            /* move viewpoint */
  381. double  angle, elev, mag;
  382. FVECT  vc;
  383. {
  384.     double  d;
  385.     FVECT  v1;
  386.     VIEW  nv;
  387.     register int  i;
  388.  
  389.     VCOPY(nv.vup, ourview.vup);
  390.     nv.hoff = ourview.hoff; nv.voff = ourview.voff;
  391.     spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
  392.     if (elev != 0.0) {
  393.         fcross(v1, ourview.vup, nv.vdir);
  394.         normalize(v1);
  395.         spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
  396.     }
  397.     if ((nv.type = ourview.type) == VT_PAR) {
  398.         nv.horiz = ourview.horiz / mag;
  399.         nv.vert = ourview.vert / mag;
  400.         d = 0.0;            /* don't move closer */
  401.         for (i = 0; i < 3; i++)
  402.             d += (vc[i] - ourview.vp[i])*ourview.vdir[i];
  403.     } else {
  404.         nv.horiz = ourview.horiz;
  405.         nv.vert = ourview.vert;
  406.         d = sqrt(dist2(ourview.vp, vc)) / mag;
  407.     }
  408.     for (i = 0; i < 3; i++)
  409.         nv.vp[i] = vc[i] - d*nv.vdir[i];
  410.     newview(&nv);
  411. }
  412.  
  413.  
  414. zoomview(vp, zf)            /* zoom in our out */
  415. register VIEW  *vp;
  416. double  zf;
  417. {
  418.     switch (vp->type) {
  419.     case VT_PAR:                /* parallel view */
  420.     case VT_ANG:                /* angular fisheye */
  421.         vp->horiz /= zf;
  422.         vp->vert /= zf;
  423.         return;
  424.     case VT_PER:                /* perspective view */
  425.         vp->horiz = atan(tan(vp->horiz*(PI/180./2.))/zf) /
  426.                 (PI/180./2.);
  427.         vp->vert = atan(tan(vp->vert*(PI/180./2.))/zf) /
  428.                 (PI/180./2.);
  429.         return;
  430.     case VT_HEM:                /* hemispherical fisheye */
  431.         vp->horiz = sin(vp->horiz*(PI/180./2.))/zf;
  432.         if (vp->horiz >= 1.0-FTINY)
  433.             vp->horiz = 180.;
  434.         else
  435.             vp->horiz = asin(vp->horiz) / (PI/180./2.);
  436.         vp->vert = sin(vp->vert*(PI/180./2.))/zf;
  437.         if (vp->vert >= 1.0-FTINY)
  438.             vp->vert = 180.;
  439.         else
  440.             vp->vert = asin(vp->vert) / (PI/180./2.);
  441.         return;
  442.     }
  443. }
  444.