home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / curve / rotate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  5.3 KB  |  218 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *
  19.  * Rotate.c
  20.  *
  21.  * Part of the "Curve Demo"
  22.  * by Howard Look for Silicon Graphics
  23.  *
  24.  * June, 1989
  25.  *
  26.  * This file contains the routines used for rotating the view volume.
  27.  *
  28.  */
  29.  
  30.  
  31. #include <stdio.h>
  32. #include <gl.h>
  33. #include <device.h>
  34. #include <math.h>
  35. #include "curve.h"
  36. #include "event.h"
  37.  
  38.  
  39. /* Prototypes */
  40. void rotate_view_volume(void);
  41. void update_rotation(void);
  42. Boolean within_cube(void);
  43.  
  44. extern void fake_view_volume(void);
  45. extern void set_three_d_view(void);
  46.  
  47. /* Just your basic, plain, vanilla identity matrix */
  48. Matrix identity_matrix =
  49.     {    {1.0,0.0,0.0,0.0}, 
  50.         {0.0,1.0,0.0,0.0},
  51.         {0.0,0.0,1.0,0.0},
  52.         {0.0,0.0,0.0,1.0}
  53.     };
  54.  
  55.  
  56. /* 
  57.  * This matrix get successively updated as the user rotates the view
  58.  * volume. It represents the transformation to rotate the view volume
  59.  * (and the curve within it) from whatever the current transformation
  60.  * is to the appropriate rotated view.
  61.  */
  62. Matrix rotate_matrix =
  63.     {    {1.0,0.0,0.0,0.0}, 
  64.         {0.0,1.0,0.0,0.0},
  65.         {0.0,0.0,1.0,0.0},
  66.         {0.0,0.0,0.0,1.0}
  67.     };
  68.  
  69.  
  70. /* About the window... */ 
  71. extern int origin_x, origin_y, size_x, size_y;
  72.  
  73.  
  74. /*
  75.  * Routine to rotate the view volume using a trackball-like interface
  76.  * to the mouse.
  77.  * 
  78.  * Called whevever the middle mouse button is pressed AND we are in 3D
  79.  * display mode. Program flow remains here until the middle mouse is
  80.  * released. Successively updates the rotation matrix then calls the
  81.  * drawing routine.
  82.  *
  83.  * How the trackball works:
  84.  * If the user clicks and drags within the bounds of the view volume,
  85.  * the volume is rotated about the world x and y axes, following the
  86.  * motion of the mouse. If the user clicks outside the view volume,
  87.  * then rotation follows the mouse about the z axis.
  88.  *
  89.  * Why the rotation matrix works:
  90.  * Normally, all transformation take place relative to an objects own
  91.  * coordinate system. Therefore when the object rotates, so does its
  92.  * own coordinate system.
  93.  *
  94.  * In this program, we wish for the rotation of the view volume to
  95.  * take place relative to the fixed world coordinate system. That is,
  96.  * when the user drags the mouse in the x direction, we want the
  97.  * rotation to take place about the world y axis, not about the
  98.  * object's y axis (because after a zillion rotations, God only knows
  99.  * where the object's coordinate system is pointing).
  100.  *
  101.  * The rotation matrx is a 'pure' matrix in that it merely accumulates
  102.  * the rotations we wish to make. By starting each time with the
  103.  * identity matrix, computing the rotation for this iteration, and
  104.  * multiplying it to the rotation matrix, we have a transformation
  105.  * matrix that describes pure rotation from the world coordinate
  106.  * system, which does not move.
  107.  *
  108.  * Thanks Thant.
  109.  */
  110.  
  111.  
  112. /* Scaled mouse values (-1.0 to 1.0) */
  113. static float last_x, last_y;
  114.  
  115. /* Did the user click inside the view volume ? */
  116. static Boolean inside;
  117.  
  118. extern Boolean rotating;
  119.  
  120. void rotate_view_volume(void)
  121. {
  122.     long mx, my;
  123.     
  124.     mx = getvaluator(MOUSEX);
  125.     my = getvaluator(MOUSEY);
  126.  
  127.     inside = within_cube(); 
  128.     
  129.     /* Scale mouse values to square around -1.0 to 1.0  */
  130.     last_x = 2.0*((Coord)(mx - origin_x)/size_x - 0.5);
  131.     last_y = 2.0*((Coord)(my - origin_y)/size_y - 0.5);
  132.  
  133.     qdevice(MOUSEX);
  134.     qdevice(MOUSEY);
  135.     
  136.     rotating = TRUE;
  137. }
  138.  
  139.  
  140. void update_rotation(void)
  141. {
  142.     float new_x, new_y, dx, dy, dz;
  143.     long mx, my;
  144.     
  145.     mx = getvaluator(MOUSEX);
  146.     my = getvaluator(MOUSEY);
  147.     dx = dy = dz = 0.0; /* Mouse rotation, in degrees */
  148.  
  149.     if (inside)
  150.     {
  151.         /* rotate about x-y */
  152.         
  153.         /* sweeping the mouse across the width of the screen,
  154.               left to right causes a positive 90 degree rotation
  155.            about the y axis, etc. */
  156.         new_x = 2.0*((Coord)(mx - origin_x)/size_x - 0.5);
  157.         /* mouse y rotation, in degrees */
  158.         dy = 45.0*(new_x-last_x);
  159.         last_x = new_x;
  160.  
  161.         new_y = 2.0*((Coord)(my - origin_y)/size_y - 0.5);
  162.         /* mouse x rotation, in degrees */
  163.         dx = -45.0*(new_y-last_y);
  164.         last_y = new_y;
  165.     }
  166.     else
  167.     {
  168.         /* rotate about z */
  169.  
  170.         new_x = 2.0*((Coord)(mx - origin_x)/size_x - 0.5);
  171.         new_y = 2.0*((Coord)(my - origin_y)/size_y - 0.5);
  172.  
  173.         dz = (fatan2(new_y, new_x) - fatan2(last_y, last_x)) RAD;
  174.                             
  175.         last_x = new_x;
  176.         last_y = new_y;
  177.     }
  178.  
  179.     /* compute and accumulate the rotation matrix */
  180.     pushmatrix();
  181.     loadmatrix(identity_matrix);
  182.     rot(dx, 'x');
  183.     rot(dy, 'y');
  184.     rot(dz, 'z');
  185.     multmatrix(rotate_matrix);
  186.     getmatrix(rotate_matrix);
  187.     popmatrix();
  188. }
  189.  
  190.  
  191.  
  192.  
  193.         
  194. /*
  195.  * Returns TRUE is x and y (in screen coords) are within the boundries
  196.  * of the view volume.
  197.  */
  198. Boolean within_cube(void)
  199. {
  200.     long result;
  201.     short buffer;
  202.  
  203.     picksize(1,1);
  204.     
  205.     initnames();
  206.     pick(&buffer, 1);
  207.     set_three_d_view();
  208.     multmatrix(rotate_matrix);
  209.     fake_view_volume();
  210.     result = endpick(&buffer);
  211.  
  212.     return(buffer == 1);
  213. }
  214.  
  215.  
  216.  
  217.  
  218.