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