1 /*********************************************************************
2 
3   ViewModel.h
4 
5   GLUI User Interface Toolkit (LGPL)
6   Copyright (c) 1998 Paul Rademacher
7 
8   WWW:    http://sourceforge.net/projects/glui/
9   Forums: http://sourceforge.net/forum/?group_id=92496
10 
11   This library is free software; you can redistribute it and/or
12   modify it under the terms of the GNU Lesser General Public
13   License as published by the Free Software Foundation; either
14   version 2.1 of the License, or (at your option) any later version.
15 
16   This library is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19   Lesser General Public License for more details.
20 
21   You should have received a copy of the GNU Lesser General Public
22   License along with this library; if not, write to the Free Software
23   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 
25 */
26 
27 /*********************************************************************
28 
29   The ViewModel class implements a camera model, minus the perspective
30   transformation.  It maintains the coordinate system of the camera
31   as three vectors (forward, up, and side), which are themselves
32   derived from two points (eye and lookat).
33 
34   Apart from simplifying camera translation, this class provides
35   three rotation methods: yaw (rotation about the up axis),
36   roll (about the forward axis), and pitch (about the side axis).
37   Also, these rotations can take place about the eye (in which
38   case the eye location is fixed but the lookat point changes -
39   like rotating your head), or about the lookat point (in which
40   case your eye rotates around the point of interest).
41 
42   There is also a routine for rotating the eye about an arbitrary
43   axis, which is quite useful in conjuction with the world up axis.
44 
45   This class is heavily-dependent on the vec3 class in
46   the file algebra3.h.
47 
48   The function update() sets the side and forward vectors based
49   on the lookat, eye, and up vectors.  Remember to call this
50   function if you change the side or forward directly.
51 
52   Sample use:
53      ViewModel vm;
54      vm.eye.set( 0.0, 0.0, 20.0 );
55      vm.lookat.set( 0.0, 0.0, 0.0 );
56      vm.update();  // updates the three vectors
57 
58      vm.move( 0.0, 2.0, 0.0 );  // Moves the eye and lookat
59                                 //   by 2 units in the world
60                                 //   Y direction
61      vm.roll( 5.0 );            //   rolls 5 degrees about the forward axis
62      vm.lookat_yaw( -25.0 );    // Yaws about the eye (lookat is
63 				                //   fixed) by -25 degrees
64      vm.load_to_openGL();       // Sets OpenGL modelview matrix
65 
66      .. render ...
67 
68 
69   ---------- List of member functions -----------------------------
70   set_distance()   - Sets the distance from the eye to the lookat
71   set_up()         - Sets the current up vector
72   set_eye()        - Sets the current eye point
73   set_lookat()     - Sets the current lookat point
74   roll()           - Rolls about forward axis
75   eye_yaw()        - Rotates eye about up vector
76   eye_yaw_abs()    - Rotates eye about arbitrary axis
77   eye_pitch()      - Rotates eye about side vector
78   lookat_yaw()     - Rotates lookat about up vector
79   lookat_pitch()   - Rotates lookat about side vector
80   reset_up_level() - Resets the up vector (after unwanted rolls), and
81                        sets the eye level with the lookat point
82   move()           - Moves eye and lookat by some amount
83   move_by_eye()    - Moves eye to new position, lookat follows
84   move_by_lookat() - Moves lookat to new position, eye follows
85   move_abs()       - Moves eye and lookat in world coordinates
86   rot_about_eye()  - Rotates about the eye point by a given 4x4 matrix
87   rot_about_lookat() - Rotates about the lookat point by a given 4x4 matrix
88   make_mtx()       - Constructs 4x4 matrix, used by load_to_openGL()
89   load_to_openGL() - Loads current camera description in openGL
90   load_to_openGL_noident() - Loads camera into OpenGL without first
91                      resetting the OpenGL matrix to identity
92   reset()          - Resets class values
93   ViewModel()      - constructor
94   update()         - Recalculates side and forward based on eye,
95                      lookat, and up
96   dump()           - Prints class contents to a file
97 
98 
99       1996, Paul Rademacher (rademach@cs.unc.edu)
100   Oct 2003, Nigel Stewart - GLUI Code Cleaning
101 
102 *********************************************************************/
103 
104 #ifndef GLUI_VIEWMODEL_H
105 #define GLUI_VIEWMODEL_H
106 
107 #include "algebra3.h"
108 
109 class ViewModel
110 {
111 public:
112   vec3    eye, lookat;
113   vec3    up, side, forward;
114   mat4    mtx;
115   float   distance;
116 
117   /******************************* set_distance() ***********/
118   /* This readjusts the distance from the eye to the lookat */
119   /* (changing the eye point in the process)                */
120   /* The lookat point is unaffected                         */
121   void set_distance(float new_distance);
122 
123   /******************************* set_up() ***************/
124   void set_up(const vec3 &new_up);
125 
126   void set_up(float x, float y, float z);
127 
128   /******************************* set_eye() ***************/
129   void set_eye(const vec3 &new_eye );
130 
131   void set_eye(float x, float y, float z);
132 
133   /******************************* set_lookat() ***************/
134   void set_lookat(const vec3 &new_lookat);
135 
136   void set_lookat(float x, float y, float z);
137 
138   /******************************* roll() *****************/
139   /* Rotates about the forward vector                     */
140   /* eye and lookat remain unchanged                      */
141   void roll(float angle);
142 
143   /******************************* eye_yaw() *********************/
144   /* Rotates the eye about the lookat point, using the up vector */
145   /* Lookat is unaffected                                        */
146   void eye_yaw(float angle);
147 
148   /******************************* eye_yaw_abs() ******************/
149   /* Rotates the eye about the lookat point, with a specific axis */
150   /* Lookat is unaffected                                         */
151   void eye_yaw_abs(float angle, const vec3 &axis);
152 
153 
154   /******************************* eye_pitch() ************/
155   /* Rotates the eye about the side vector                */
156   /* Lookat is unaffected                                 */
157   void eye_pitch(float angle);
158 
159   /******************************* lookat_yaw()************/
160   /* This assumes the up vector is correct.               */
161   /* Rotates the lookat about the side vector             */
162   /* Eye point is unaffected                              */
163   void lookat_yaw(float angle);
164 
165   /******************************* lookat_pitch() *********/
166   /* Rotates the lookat point about the side vector       */
167   /* This assumes the side vector is correct.             */
168   /* Eye point is unaffected                              */
169   void lookat_pitch(float angle);
170 
171   /******************************* reset_up() ******************/
172   /* Resets the up vector to a specified axis (0=X, 1=Y, 2=Z)  */
173   /* Also sets the eye point level with the lookat point,      */
174   /* along the specified axis                                  */
175   void reset_up(int axis_num);
176 
177   void reset_up();
178 
179   /******************************* move() ********************/
180   /* Moves a specified distance in the forward, side, and up */
181   /* directions.  This function does NOT move by world       */
182   /* coordinates.  To move by world coords, use the move_abs */
183   /* function.                                               */
184   void move(float side_move, float up_move, float forw_move);
185 
186   void move(const vec3 &v);
187 
188   /******************************* move_by_eye() ***********/
189   /* Sets the eye point, AND moves the lookat point by the */
190   /* same amount as the eye is moved.                      */
191   void move_by_eye(const vec3 &new_eye);
192 
193   /******************************* move_by_lookat() *********/
194   /* Sets the lookat point, AND moves the eye point by the  */
195   /* same amount as the lookat is moved.                    */
196   void move_by_lookat(const vec3 &new_lookat);
197 
198   /******************************* move_abs() *****************/
199   /* Move the eye and lookat in world coordinates             */
200   void move_abs(const vec3 &v);
201 
202   /****************************** rot_about_eye() ************/
203   /* Rotates the lookat point about the eye, based on a 4x4  */
204   /* (pure) rotation matrix                                  */
205   void rot_about_eye(const mat4 &rot);
206 
207   /****************************** rot_about_lookat() ************/
208   /* Rotates the lookat point about the lookat, based on a 4x4  */
209   /* (pure) rotation matrix                                  */
210   void rot_about_lookat(const mat4 &rot);
211 
212   /******************************* make_mtx() *************/
213   /* Constructs a 4x4 matrix - used by load_to_openGL()   */
214   void make_mtx();
215 
216   /******************************* load_to_openGL() ********/
217   /* Sets the OpenGL modelview matrix based on the current */
218   /* camera coordinates                                    */
219   void load_to_openGL();
220 
221   /******************************* load_to_openGL_noident() ******/
222   /* Multiplies the current camera matrix by the existing openGL */
223   /* modelview matrix.  This is same as above function, but      */
224   /* does not set the OpenGL matrix to identity first            */
225   void load_to_openGL_noident();
226 
227   /******************************* reset() ****************/
228   /* Resets the parameters of this class                  */
229   void reset();
230 
231   /******************************* ViewModel() ************/
232   /* Constructor                                          */
233   ViewModel();
234 
235   /******************************* update() ****************/
236   /* updates the view params.  Call this after making      */
237   /* direct changes to the vectors or points of this class */
238   void update();
239 
240   /******************************* dump() *******************/
241   /* Prints the contents of this class to a file, typically */
242   /* stdin or stderr                                        */
243   void dump(FILE *output) const;
244 };
245 
246 #endif
247