home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Peter's Final Project / src / camera.c next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  5.1 KB  |  195 lines  |  [TEXT/KAHL]

  1. /*
  2.  *  Peter's Final Project -- A texture mapping demonstration
  3.  *  © 1995, Peter Mattis
  4.  *
  5.  *  E-mail:
  6.  *  petm@soda.csua.berkeley.edu
  7.  *
  8.  *  Snail-mail:
  9.  *   Peter Mattis
  10.  *   557 Fort Laramie Dr.
  11.  *   Sunnyvale, CA 94087
  12.  *
  13.  *  Avaible from:
  14.  *  http://www.csua.berkeley.edu/~petm/final.html
  15.  *
  16.  *  This program is free software; you can redistribute it and/or modify
  17.  *  it under the terms of the GNU General Public License as published by
  18.  *  the Free Software Foundation; either version 2 of the License, or
  19.  *  (at your option) any later version.
  20.  *
  21.  *  This program is distributed in the hope that it will be useful,
  22.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  23.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24.  *  GNU General Public License for more details.
  25.  *
  26.  *  You should have received a copy of the GNU General Public License
  27.  *  along with this program; if not, write to the Free Software
  28.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29.  */
  30.  
  31. #include <assert.h>
  32. #include "camera.h"
  33. #include "sys.stuff.h"
  34.  
  35. /*
  36.  * Make a camera object and initialize its values to something decent.
  37.  */
  38.  
  39. CAMERA
  40. make_camera ()
  41. {
  42.     CAMERA camera;
  43.  
  44.     camera = (CAMERA) ALLOC (sizeof (_CAMERA));
  45.  
  46.     set_camera_pos_x (camera, NUM_ZERO);
  47.     set_camera_pos_y (camera, NUM_ZERO);
  48.     set_camera_pos_z (camera, NUM_ZERO);
  49.     set_camera_pos_z (camera, NUM_ONE);
  50.  
  51.     set_camera_vpn_x (camera, NUM_ZERO);
  52.     set_camera_vpn_y (camera, NUM_ZERO);
  53.     set_camera_vpn_z (camera, NUM_ZERO);
  54.     set_camera_vpn_z (camera, NUM_ONE);
  55.  
  56.     set_camera_vup_x (camera, NUM_ZERO);
  57.     set_camera_vup_y (camera, NUM_ZERO);
  58.     set_camera_vup_z (camera, NUM_ZERO);
  59.     set_camera_vup_z (camera, NUM_ONE);
  60.  
  61.     set_camera_u_min (camera, NUM_ZERO);
  62.     set_camera_u_max (camera, NUM_ZERO);
  63.     set_camera_v_min (camera, NUM_ZERO);
  64.     set_camera_v_max (camera, NUM_ZERO);
  65.  
  66.     return camera;
  67. }
  68.  
  69. /*
  70.  * Free a camera object.
  71.  */
  72.  
  73. void
  74. free_camera (c)
  75.     CAMERA c;
  76. {
  77.     FREE (c);
  78. }
  79.  
  80. /*
  81.  * Determine a camera's matrices from its "pos", "vpn" and "vup".
  82.  * (This is the meat and potatoes of the camera.)
  83.  */
  84.  
  85. void
  86. camera_determine_matrices (c)
  87.     CAMERA c;
  88. {
  89.     MATRIX trans_pos;
  90.     MATRIX rotate_uvn;
  91.     MATRIX scale;
  92.     MATRIX projection;
  93.     MATRIX map_trans;
  94.     MATRIX map_scale;
  95.     MATRIX matrix_temp;
  96.     VECTOR pos, vpn, vup;
  97.     VECTOR u, v;
  98.  
  99.     /*
  100.      * Copy the "pos", "vpn" and "vup".
  101.      */
  102.     vector_copy (camera_pos (c), pos);
  103.     vector_copy (camera_vpn (c), vpn);
  104.     vector_copy (camera_vup (c), vup);
  105.  
  106.     /*
  107.      * Normalize the "vpn" and "vup" so we have unit vectors.
  108.      */
  109.     vector_normalize (vpn);
  110.     vector_normalize (vup);
  111.  
  112.     /*
  113.      * First we need to translate to the origin.
  114.      */
  115.     matrix_translate (trans_pos, -vector_x (pos), -vector_y (pos), -vector_z (pos));
  116.  
  117.     /*
  118.      * Then we need to determine the "u", "v", "n" coordinate system
  119.      *  of the camera. The "vpn" is the "n" of the coordinate system.
  120.      *  Basically, this is the direction we are looking. The "u" is a
  121.      *  vector pointing to our right. The "v" is a vector pointing up.
  122.      *
  123.      * To find "u" and "v" we do two cross products.
  124.      */
  125.     vector_cross (vup, vpn, u);
  126.     vector_cross (vpn, u, v);
  127.  
  128.     /*
  129.      * Since these are directional vectors, set the "w" coordinate to 0.
  130.      */
  131.     set_vector_w (vpn, NUM_ZERO);
  132.     set_vector_w (u, NUM_ZERO);
  133.     set_vector_w (v, NUM_ZERO);
  134.  
  135.     /*
  136.      * If "u", "v" and "n" define a coordinate system, then a simple
  137.      *  way to create a matrix that transforms a vector to that
  138.      *  coordinate system is to create the matrix that contain "u",
  139.      *  "v" and "n" as the first 3 rows of that matrix (in the proper
  140.      *  order, of course).
  141.      */
  142.     matrix_clear (rotate_uvn);
  143.     vector_copy (u, rotate_uvn[0]);
  144.     vector_copy (v, rotate_uvn[1]);
  145.     vector_copy (vpn, rotate_uvn[2]);
  146.  
  147.     /*
  148.      * Next we scale the view volume is the canonical view volume.
  149.      * Note: This works, but messes up the psuedo-Gourad shading.
  150.      *       So for now we are stuck with a 90 degrees viewing
  151.      *       angle.
  152.      */
  153.     matrix_scale (scale, NUM_ONE, NUM_ONE, NUM_ONE);
  154.  
  155.     /*
  156.      * Compose the matrices to form the "orientation" matrix.
  157.      * Remember, the order of composition is important.
  158.      */
  159.     matrix_compose (rotate_uvn, trans_pos, matrix_temp);
  160.     matrix_compose (scale, matrix_temp, camera_matrix_orientation (c));
  161.  
  162.     /*
  163.      * Create the "projection" matrix.
  164.      * We know the projection plane distance is 1 at this point,
  165.      *  so we can easily set up the matrix.
  166.      */
  167.     matrix_clear (projection);
  168.     set_matrix_element (projection, 3, 2, -NUM_ONE);
  169.     set_matrix_element (projection, 3, 3, 0);
  170.  
  171.     /*
  172.      * Translate the view so that all coordinates lie between
  173.      *  0 and 2 in both x and y.
  174.      */
  175.     matrix_translate (map_trans, NUM_ONE, NUM_ONE, 0);
  176.  
  177.     /*
  178.      * Scale the view so that x values range between 0 and "u_max"
  179.      *  and y values range between 0 and "v_max".
  180.      * The divide by two is present because previously values ranged
  181.      *  between 0 and 2.
  182.      * We want to keep the z value so don't scale in that direction.
  183.      */
  184.     matrix_scale (map_scale,
  185.         (camera_u_max (c) - camera_u_min (c)) / 2,
  186.         (camera_v_max (c) - camera_v_min (c)) / 2,
  187.         NUM_ONE);
  188.  
  189.     /*
  190.      * Compose the matrices to form the "mapping" matrix.
  191.      */
  192.     matrix_compose (map_trans, projection, matrix_temp);
  193.     matrix_compose (map_scale, matrix_temp, camera_matrix_mapping (c));
  194. }
  195.