home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsiii / panorama.c < prev    next >
C/C++ Source or Header  |  1992-10-05  |  6KB  |  193 lines

  1. /*
  2.  * Panoramic virtual screen implementation code fragment.
  3.  *
  4.  * Copyright (C) 1991, F. Kenton Musgrave 
  5.  * All rights reserved.
  6.  *
  7.  * This code is an extension of Rayshade 4.0
  8.  * Copyright (C) 1989, 1991, Craig E. Kolb, Rod G. Bogart
  9.  * All rights reserved.
  10.  */
  11.  
  12. /* Various declarations and vector routines are a part of Rayshade; most are
  13.  * easy enough to do yourself.
  14.  */
  15.  
  16. RSViewing()
  17. {
  18.     Float magnitude;
  19.     RSMatrix trans;
  20.     Vector eyeOffset;
  21.     int x, y;
  22.  
  23.     VecSub(Camera.lookp, Camera.pos, &Camera.dir);
  24.     Screen.firstray = Camera.dir;
  25.  
  26.     Camera.lookdist = VecNormalize(&Camera.dir);
  27.     if (VecNormCross(&Camera.dir, &Camera.up, &Screen.scrni) == 0.)
  28.         RLerror(RL_PANIC,
  29.             "The view and up directions are identical?\n");
  30.     (void)VecNormCross(&Screen.scrni, &Camera.dir, &Screen.scrnj);
  31.  
  32.     /* construct screen "x" (horizontal) direction vector */
  33.     if (!Options.panorama) {
  34.         /* standard virtual screen setup */
  35.         magnitude = 2.*Camera.lookdist * tan(deg2rad(0.5*Camera.hfov)) /
  36.                     Screen.xres;
  37.         VecScale(magnitude, Screen.scrni, &Screen.scrnx);
  38.     } else {
  39.         /* For panorama option, we need an array of screen "x" vectors
  40.          * which we will build later in the code.  At this point, we
  41.          * just construct the required rotation matrix (rotations being
  42.          * about the "up" vector) and point the "scrnx" vector to the
  43.          * edge of the screen.
  44.          */
  45.         Camera.lookdist = 1.;
  46.         magnitude = -deg2rad(Camera.hfov);
  47.         Screen.hincr = magnitude / Screen.xres;
  48.         Screen.scrnx = Camera.dir;
  49.             RotationMatrix( Camera.up.x, Camera.up.y, Camera.up.z,
  50.                 -0.5*magnitude, &trans );
  51.         VecTransform( &Screen.scrnx, &trans );
  52.     }
  53.  
  54.     /* construct screen "y" (vertical) direction vector */
  55.     magnitude = 2.*Camera.lookdist * tan(deg2rad(0.5*Camera.vfov)) /
  56.                 Screen.yres;
  57.     VecScale(magnitude, Screen.scrnj, &Screen.scrny);
  58.  
  59.     if (!Options.panorama) {
  60.         /* Construct ray direction for standard virtual screen */
  61.         Screen.firstray.x -= 0.5*(Screen.xres*Screen.scrnx.x +
  62.                            Screen.yres*Screen.scrny.x);
  63.         Screen.firstray.y -= 0.5*(Screen.xres*Screen.scrnx.y +
  64.                            Screen.yres*Screen.scrny.y);
  65.         Screen.firstray.z -= 0.5*(Screen.xres*Screen.scrnx.z +
  66.                            Screen.yres*Screen.scrny.z);
  67.     } else {
  68.         /* Panorama option: requires that we allocate & fill horizontal
  69.          * and vertical direction arrays.
  70.          */
  71.         Screen.horizdir = (Vector *)Malloc((Screen.xres+1) *
  72.                            sizeof(Vector));
  73.  
  74.         /* Set eye separation for stereo rendering */
  75.         if (Options.stereo) {
  76.             if (Options.eyesep == UNSET)
  77.                 RLerror(RL_PANIC,
  78.                       "No eye separation specified.\n");
  79.             Screen.eyepts = (Vector *)Malloc((Screen.xres+1) *
  80.                                 sizeof(Vector));
  81.             if (Options.stereo == LEFT)
  82.                 magnitude = .5 * Options.eyesep;
  83.             else
  84.                 magnitude =  -.5 * Options.eyesep;
  85.             eyeOffset.x = magnitude * Screen.scrni.x;
  86.             eyeOffset.y = magnitude * Screen.scrni.y;
  87.             eyeOffset.z = magnitude * Screen.scrni.z;
  88.         }
  89.  
  90.         /* Fill the array of horizontal directions and, if stereo
  91.          * rendering, eyepoints.
  92.          * The horizontal ("x") direction array contains rotations of
  93.          * "scrnx".  Each entry requires construction of an appropriate
  94.          * rotation matrix; rotation again being around the "up" vector.
  95.          */
  96.         for ( x=0; x<=Screen.xres; x++ ) {
  97.             Screen.horizdir[x] = Screen.scrnx;
  98.                 RotationMatrix( Camera.up.x, Camera.up.y, Camera.up.z,
  99.                     x*Screen.hincr, &trans );
  100.             VecTransform( &Screen.horizdir[x], &trans );
  101.             /* Offset the eyepoints for stereo panorama */
  102.             if (Options.stereo) {
  103.                 Screen.eyepts[x] = eyeOffset;
  104.                 VecTransform( &Screen.eyepts[x], &trans );
  105.                 VecAdd( Screen.eyepts[x], Camera.pos,
  106.                     &Screen.eyepts[x] );
  107.             }
  108.         }
  109.  
  110.         /* The vertical ("y") array varies as the tangent of "scrny". */
  111.         Screen.vertdir = (Vector *)Malloc((Screen.yres+1) *
  112.                           sizeof(Vector));
  113.         for ( y=0; y<=Screen.yres; y++ ) {
  114.             Screen.vertdir[y] = Screen.scrny;
  115.             magnitude = 0.5*Camera.vfov -
  116.                     Camera.vfov * ((Float)y/Screen.yres);
  117.             magnitude = tan(deg2rad(magnitude));
  118.             VecScale(-magnitude, Screen.scrnj, &Screen.vertdir[y]);
  119.         }
  120.     }
  121.  
  122. } /* RSViewing() */
  123.  
  124.  
  125. SampleScreen(x, y, ray, color)
  126. Float x, y;        /* Screen position to sample */
  127. Ray *ray;        /* ray, with origin and medium properly set */
  128. Pixel *color;        /* resulting color */
  129. {
  130.     Float dist;
  131.     HitList hitlist;
  132.     Color ctmp, fullintens;
  133.     extern void ShadeRay();
  134.     int ix, iy;
  135.  
  136.     /*
  137.      * Calculate ray direction.
  138.      */
  139.     Stats.EyeRays++;
  140.     if (Options.panorama) {
  141.         /* Construct ray direction from vectors in tables, 
  142.          * using linear interpolation for jittering.
  143.          */
  144.         ix = (int)x;
  145.         iy = (int)y;
  146.         if (Options.stereo)
  147.             ray->origin = Screen.eyepts[ix];
  148.         ray->dir.x = Screen.horizdir[ix].x +
  149.                  (Screen.horizdir[ix+1].x - Screen.horizdir[ix].x)
  150.                  * (x-ix) +
  151.                  Screen.vertdir[iy].x +
  152.                  (Screen.horizdir[iy+1].x - Screen.horizdir[iy].x)
  153.                  * (y-iy);
  154.         ray->dir.y = Screen.horizdir[ix].y +
  155.                  (Screen.horizdir[ix+1].y - Screen.horizdir[ix].y)
  156.                  * (x-ix) +
  157.                  Screen.vertdir[iy].y +
  158.                  (Screen.horizdir[iy+1].y - Screen.horizdir[iy].y)
  159.                  * (y-iy);
  160.         ray->dir.z = Screen.horizdir[ix].z +
  161.                  (Screen.horizdir[ix+1].z - Screen.horizdir[ix].z)
  162.                  * (x-ix) +
  163.                  Screen.vertdir[iy].z +
  164.                  (Screen.horizdir[iy+1].z - Screen.horizdir[iy].z)
  165.                  * (y-iy);
  166.     } else {
  167.         ray->dir.x = Screen.firstray.x + x*Screen.scrnx.x +
  168.                     y*Screen.scrny.x;
  169.         ray->dir.y = Screen.firstray.y + x*Screen.scrnx.y +
  170.                     y*Screen.scrny.y;
  171.         ray->dir.z = Screen.firstray.z + x*Screen.scrnx.z +
  172.                     y*Screen.scrny.z;
  173.     } 
  174.  
  175.     (void)VecNormalize(&ray->dir);
  176.  
  177.     /*
  178.      * Do the actual ray trace.
  179.      */
  180.     fullintens.r = fullintens.g = fullintens.b = 1.;
  181.     dist = FAR_AWAY;
  182.     hitlist.nodes = 0;
  183.     (void)TraceRay(ray, &hitlist, EPSILON, &dist);
  184.     ShadeRay(&hitlist, ray, dist, &Screen.background, &ctmp, &fullintens);
  185.     color->r = ctmp.r;
  186.     color->g = ctmp.g;
  187.     color->b = ctmp.b;
  188.  
  189. } /* SampleScreen() */
  190.  
  191.  
  192.  
  193.