00001 /********************************************************************* 00002 00003 ViewModel.h 00004 00005 GLUI User Interface Toolkit (LGPL) 00006 Copyright (c) 1998 Paul Rademacher 00007 00008 WWW: http://sourceforge.net/projects/glui/ 00009 Forums: http://sourceforge.net/forum/?group_id=92496 00010 00011 This library is free software; you can redistribute it and/or 00012 modify it under the terms of the GNU Lesser General Public 00013 License as published by the Free Software Foundation; either 00014 version 2.1 of the License, or (at your option) any later version. 00015 00016 This library is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 Lesser General Public License for more details. 00020 00021 You should have received a copy of the GNU Lesser General Public 00022 License along with this library; if not, write to the Free Software 00023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 00025 */ 00026 00027 /********************************************************************* 00028 00029 The ViewModel class implements a camera model, minus the perspective 00030 transformation. It maintains the coordinate system of the camera 00031 as three vectors (forward, up, and side), which are themselves 00032 derived from two points (eye and lookat). 00033 00034 Apart from simplifying camera translation, this class provides 00035 three rotation methods: yaw (rotation about the up axis), 00036 roll (about the forward axis), and pitch (about the side axis). 00037 Also, these rotations can take place about the eye (in which 00038 case the eye location is fixed but the lookat point changes - 00039 like rotating your head), or about the lookat point (in which 00040 case your eye rotates around the point of interest). 00041 00042 There is also a routine for rotating the eye about an arbitrary 00043 axis, which is quite useful in conjuction with the world up axis. 00044 00045 This class is heavily-dependent on the vec3 class in 00046 the file algebra3.h. 00047 00048 The function update() sets the side and forward vectors based 00049 on the lookat, eye, and up vectors. Remember to call this 00050 function if you change the side or forward directly. 00051 00052 Sample use: 00053 ViewModel vm; 00054 vm.eye.set( 0.0, 0.0, 20.0 ); 00055 vm.lookat.set( 0.0, 0.0, 0.0 ); 00056 vm.update(); // updates the three vectors 00057 00058 vm.move( 0.0, 2.0, 0.0 ); // Moves the eye and lookat 00059 // by 2 units in the world 00060 // Y direction 00061 vm.roll( 5.0 ); // rolls 5 degrees about the forward axis 00062 vm.lookat_yaw( -25.0 ); // Yaws about the eye (lookat is 00063 // fixed) by -25 degrees 00064 vm.load_to_openGL(); // Sets OpenGL modelview matrix 00065 00066 .. render ... 00067 00068 00069 ---------- List of member functions ----------------------------- 00070 set_distance() - Sets the distance from the eye to the lookat 00071 set_up() - Sets the current up vector 00072 set_eye() - Sets the current eye point 00073 set_lookat() - Sets the current lookat point 00074 roll() - Rolls about forward axis 00075 eye_yaw() - Rotates eye about up vector 00076 eye_yaw_abs() - Rotates eye about arbitrary axis 00077 eye_pitch() - Rotates eye about side vector 00078 lookat_yaw() - Rotates lookat about up vector 00079 lookat_pitch() - Rotates lookat about side vector 00080 reset_up_level() - Resets the up vector (after unwanted rolls), and 00081 sets the eye level with the lookat point 00082 move() - Moves eye and lookat by some amount 00083 move_by_eye() - Moves eye to new position, lookat follows 00084 move_by_lookat() - Moves lookat to new position, eye follows 00085 move_abs() - Moves eye and lookat in world coordinates 00086 rot_about_eye() - Rotates about the eye point by a given 4x4 matrix 00087 rot_about_lookat() - Rotates about the lookat point by a given 4x4 matrix 00088 make_mtx() - Constructs 4x4 matrix, used by load_to_openGL() 00089 load_to_openGL() - Loads current camera description in openGL 00090 load_to_openGL_noident() - Loads camera into OpenGL without first 00091 resetting the OpenGL matrix to identity 00092 reset() - Resets class values 00093 ViewModel() - constructor 00094 update() - Recalculates side and forward based on eye, 00095 lookat, and up 00096 dump() - Prints class contents to a file 00097 00098 00099 1996, Paul Rademacher (rademach@cs.unc.edu) 00100 Oct 2003, Nigel Stewart - GLUI Code Cleaning 00101 00102 *********************************************************************/ 00103 00104 #ifndef GLUI_VIEWMODEL_H 00105 #define GLUI_VIEWMODEL_H 00106 00107 #include "algebra3.h" 00108 00109 class ViewModel 00110 { 00111 public: 00112 vec3 eye, lookat; 00113 vec3 up, side, forward; 00114 mat4 mtx; 00115 float distance; 00116 00117 /******************************* set_distance() ***********/ 00118 /* This readjusts the distance from the eye to the lookat */ 00119 /* (changing the eye point in the process) */ 00120 /* The lookat point is unaffected */ 00121 void set_distance(float new_distance); 00122 00123 /******************************* set_up() ***************/ 00124 void set_up(const vec3 &new_up); 00125 00126 void set_up(float x, float y, float z); 00127 00128 /******************************* set_eye() ***************/ 00129 void set_eye(const vec3 &new_eye ); 00130 00131 void set_eye(float x, float y, float z); 00132 00133 /******************************* set_lookat() ***************/ 00134 void set_lookat(const vec3 &new_lookat); 00135 00136 void set_lookat(float x, float y, float z); 00137 00138 /******************************* roll() *****************/ 00139 /* Rotates about the forward vector */ 00140 /* eye and lookat remain unchanged */ 00141 void roll(float angle); 00142 00143 /******************************* eye_yaw() *********************/ 00144 /* Rotates the eye about the lookat point, using the up vector */ 00145 /* Lookat is unaffected */ 00146 void eye_yaw(float angle); 00147 00148 /******************************* eye_yaw_abs() ******************/ 00149 /* Rotates the eye about the lookat point, with a specific axis */ 00150 /* Lookat is unaffected */ 00151 void eye_yaw_abs(float angle, const vec3 &axis); 00152 00153 00154 /******************************* eye_pitch() ************/ 00155 /* Rotates the eye about the side vector */ 00156 /* Lookat is unaffected */ 00157 void eye_pitch(float angle); 00158 00159 /******************************* lookat_yaw()************/ 00160 /* This assumes the up vector is correct. */ 00161 /* Rotates the lookat about the side vector */ 00162 /* Eye point is unaffected */ 00163 void lookat_yaw(float angle); 00164 00165 /******************************* lookat_pitch() *********/ 00166 /* Rotates the lookat point about the side vector */ 00167 /* This assumes the side vector is correct. */ 00168 /* Eye point is unaffected */ 00169 void lookat_pitch(float angle); 00170 00171 /******************************* reset_up() ******************/ 00172 /* Resets the up vector to a specified axis (0=X, 1=Y, 2=Z) */ 00173 /* Also sets the eye point level with the lookat point, */ 00174 /* along the specified axis */ 00175 void reset_up(int axis_num); 00176 00177 void reset_up(); 00178 00179 /******************************* move() ********************/ 00180 /* Moves a specified distance in the forward, side, and up */ 00181 /* directions. This function does NOT move by world */ 00182 /* coordinates. To move by world coords, use the move_abs */ 00183 /* function. */ 00184 void move(float side_move, float up_move, float forw_move); 00185 00186 void move(const vec3 &v); 00187 00188 /******************************* move_by_eye() ***********/ 00189 /* Sets the eye point, AND moves the lookat point by the */ 00190 /* same amount as the eye is moved. */ 00191 void move_by_eye(const vec3 &new_eye); 00192 00193 /******************************* move_by_lookat() *********/ 00194 /* Sets the lookat point, AND moves the eye point by the */ 00195 /* same amount as the lookat is moved. */ 00196 void move_by_lookat(const vec3 &new_lookat); 00197 00198 /******************************* move_abs() *****************/ 00199 /* Move the eye and lookat in world coordinates */ 00200 void move_abs(const vec3 &v); 00201 00202 /****************************** rot_about_eye() ************/ 00203 /* Rotates the lookat point about the eye, based on a 4x4 */ 00204 /* (pure) rotation matrix */ 00205 void rot_about_eye(const mat4 &rot); 00206 00207 /****************************** rot_about_lookat() ************/ 00208 /* Rotates the lookat point about the lookat, based on a 4x4 */ 00209 /* (pure) rotation matrix */ 00210 void rot_about_lookat(const mat4 &rot); 00211 00212 /******************************* make_mtx() *************/ 00213 /* Constructs a 4x4 matrix - used by load_to_openGL() */ 00214 void make_mtx(); 00215 00216 /******************************* load_to_openGL() ********/ 00217 /* Sets the OpenGL modelview matrix based on the current */ 00218 /* camera coordinates */ 00219 void load_to_openGL(); 00220 00221 /******************************* load_to_openGL_noident() ******/ 00222 /* Multiplies the current camera matrix by the existing openGL */ 00223 /* modelview matrix. This is same as above function, but */ 00224 /* does not set the OpenGL matrix to identity first */ 00225 void load_to_openGL_noident(); 00226 00227 /******************************* reset() ****************/ 00228 /* Resets the parameters of this class */ 00229 void reset(); 00230 00231 /******************************* ViewModel() ************/ 00232 /* Constructor */ 00233 ViewModel(); 00234 00235 /******************************* update() ****************/ 00236 /* updates the view params. Call this after making */ 00237 /* direct changes to the vectors or points of this class */ 00238 void update(); 00239 00240 /******************************* dump() *******************/ 00241 /* Prints the contents of this class to a file, typically */ 00242 /* stdin or stderr */ 00243 void dump(FILE *output) const; 00244 }; 00245 00246 #endif