00001 /////////////////////////////////////////////////////////////////////////// 00002 // _____________ ______________________ __ __ _____ 00003 // / ________ | | ___ ________ / | \ / \ | 00004 // | | | |_ | |_ | | / / \__ | | 00005 // | | ___ | || | || | | / / | | | 00006 // | | | \ | || | || | | / / \__/ \__/ __|__ 00007 // | | |_@ || || | || | | / / Institute 00008 // | |___/ || ||_| || | | / /_____________________ 00009 // \_______/ \______/ | |__| /___________________________ 00010 // | |__| | 00011 // \______/ 00012 // University of Utah 00013 // 2002 00014 /////////////////////////////////////////////////////////////////////////// 00015 00016 //baseManip.h 00017 00018 00019 #ifndef __BASE_MANIP_DOT_H 00020 #define __BASE_MANIP_DOT_H 00021 00022 00023 #include <map> 00024 #include <mathGutz.h> 00025 #include "../eventGutz/gutzKeyMouse.h" 00026 #include <iostream> 00027 #include <smartptr.h> 00028 00029 #pragma warning(disable:4786) //dissable stl identifier too long warnings 00030 00031 namespace gutz { 00032 00033 /// forward decl 00034 class MouseEvent; 00035 class MouseMoveEvent; 00036 class Camera; 00037 00038 //////////////////////////////////////////////////////////////////////////// 00039 /// Common functionality between manipulators, including cameras and 00040 /// lights. 00041 /// 00042 /// Manipulators and Cameras handle transformations and interactions with 00043 /// objects/camera. We define several important spaces: 00044 /// - SCREEN SPACE: xdim = (0-SX) ydim = (0-SY) zdim=(0-1) 00045 /// - PROJECTION SPACE: the cannonical view volume (-1,1)(-1,1)(-1,1) 00046 /// - EYE SPACE: Pre-projection, center at (0,0,0) view direction = Z AXIS, up = Y AXIS 00047 /// - WORLD SPACE: Pre-view matrix, the "reference space" independent of view 00048 /// - MODEL/LOCAL SPACE: Space objects are defined in, defined by a Transform Chain 00049 /// 00050 /// Here is how a MODEL/LOCAL space point is projected to the screen: reads 00051 /// from right to left\n 00052 /// SCREEN<-(divide w)PROJECTION(camera)<-EYE(camera/view)<-WORLD<-MANIP(s...)<-point \n 00053 /// That is, the point is multiplied by all Manip objects in chain to get 00054 /// it into WORLD space, then it is multiplied by the camera's view matrix to 00055 /// get it into EYE space, then it is multiplied by the camera's projection 00056 /// matrix to get it into PROJECTION space, finally a Viewport transform is 00057 /// applied to get it into SCREEN space. The inverse of this transform takes 00058 /// a screen space point into world space. Notice that after we apply the 00059 /// projection matrix we must divide all components by the "w" component of the 00060 /// resulting position, only then can we apply the screen transform. You should 00061 /// notice that in the Transform functions you can get the total transform from 00062 /// "LOCAL" space to "PROJECTION" space but not to "SCREEN" space, this is because 00063 /// you need to divide by "w" to get into projection space. This is why you 00064 /// can only get the matrix from SCREEN<-PROJECTION and visa/versa; you have two 00065 /// steps for a transformation from SCREEN<-LOCAL: 00066 /// \code 00067 /// vec3f myPt = ....; /// transform a local point to the screen 00068 /// myPt = getProjectionTransform() * myPt; /// apply PROJECTION<-LOCAL 00069 /// myPt /= myPt.w /// divide by w 00070 /// myPt = getScreenTransform() * myPt; /// apply SCREEN<-PROJECTION 00071 /// /// now myPt is in screen space 00072 /// \endcode 00073 /// The same process works for going from screen space to local. 00074 /// 00075 /// Transformation chains are constructed by setting a manipulators parent to 00076 /// be another BaseManip, that means that the manipulator "lives" in it's 00077 /// parents space. Its parent could either be another manipulator or a Camera. 00078 /// Cameras can only be attached at the top of a transformation chain. See 00079 /// gutz::Manip for the interface for managing chains. 00080 //////////////////////////////////////////////////////////////////////////// 00081 00082 class BaseManip : public Counted { 00083 public: 00084 00085 typedef gutz::SmartPtr<BaseManip> BaseManipSP; 00086 00087 virtual ~BaseManip(){} 00088 00089 //////////////////////////////////////////////////////////// 00090 ///@name RTTI (Run-Time Type Information) 00091 ///@{ 00092 virtual bool isCamera() const = 0; 00093 virtual bool isManip() const = 0; 00094 ///@} 00095 //////////////////////////////////////////////////////////// 00096 00097 //////////////////////////////////////////////////////////// 00098 ///Tranformation chains (for Manip) interface 00099 /// Manip basically implements a linked list of manipulators that 00100 /// can be strung together. If you set your parent to be 0, 00101 /// then you effectively nuke the chain above this manipulator. 00102 /// Cameras are special, there can only be one, and it is always 00103 /// at the very top of the chain (ie has no parent). 00104 /// See gutz::Manip for the rest of this interface 00105 virtual gutz::SmartPtr<BaseManip> getParent() const 00106 { return gutz::SmartPtr<BaseManip>(0); } 00107 virtual void setParent(const BaseManipSP parent) {} 00108 virtual void insertParent(const BaseManipSP parent){} 00109 virtual Camera* getCamera() const = 0; 00110 //////////////////////////////////////////////////////////// 00111 00112 //////////////////////////////////////////////////////////// 00113 ///@name Screen size functions 00114 /// Valid (non zero) only if this object is a Camera, or 00115 /// if this is a Manip, the Camera has either been set 00116 /// during a mouse event or by the user. 00117 //@{ 00118 virtual gutz::vec2ui getScreen() const = 0; 00119 virtual unsigned int getScreenX() const = 0; 00120 virtual unsigned int getScreenY() const = 0; 00121 //@} 00122 //////////////////////////////////////////////////////////// 00123 00124 //////////////////////////////////////////////////////////// 00125 ///@name Transformations 00126 ///@{ 00127 00128 /// get the projection transform, PROJECTION<-LOCAL 00129 virtual gutz::mat4f getProjectTransform() const = 0; 00130 /// get the inverse projection transform, PROJECTION->LOCAL 00131 virtual gutz::mat4f getInvProjectTransform() const = 0; 00132 /// get the screen transform, SCREEN<-PROJECT 00133 /// this is weird because you must apply the Project transform, 00134 /// then divide by w, then apply the screen transform. 00135 virtual gutz::mat4f getScreenTransform() const = 0; 00136 /// get the inverse screen transform, SCREEN->PROJECT 00137 virtual gutz::mat4f getInvScreenTransform() const = 0; 00138 /// get the eye transform, EYE<-LOCAL, 00139 virtual gutz::mat4f getEyeTransform() const = 0; 00140 /// get the inverse eye transform: EYE->LOCAL 00141 virtual gutz::mat4f getInvEyeTransform() const = 0; 00142 /// get the world transform, WORLD<-LOCAL 00143 virtual gutz::mat4f getWorldTransform() const = 0; 00144 /// get the inverse world transform: WORLD->LOCAL 00145 virtual gutz::mat4f getInvWorldTransform() const = 0; 00146 /// get the LOCAL transform that this manipulator defines 00147 virtual gutz::mat4f getLocalTransform() const = 0; 00148 /// get the inverse transform that this manipulator defines 00149 virtual gutz::mat4f getInvLocalTransform() const = 0; 00150 /// get the projection matrix currently associated with this transform chain 00151 virtual gutz::mat4f getProjection() const = 0; 00152 /// get the inverse projection matrix (inverse of getProjection()) 00153 virtual gutz::mat4f getInvProjection() const = 0; 00154 /// get the quaternion that expresses the total rotation: EYE<-LOCAL 00155 virtual gutz::quatf getEyeQuat() const = 0; 00156 /// get the inverse quaternion for rotation: EYE->LOCAL 00157 virtual gutz::quatf getInvEyeQuat() const = 0; 00158 /// get the quaternion for rotation: WORLD<-LOCAL 00159 virtual gutz::quatf getWorldQuat() const = 0; 00160 /// get the inverse quaternion for rotation: WORLD->LOCAL 00161 virtual gutz::quatf getInvWorldQuat() const = 0; 00162 /// get the local quaternion for rotation 00163 virtual gutz::quatf getLocalQuat() const = 0; 00164 /// get the inverse local quaterinion for rotation 00165 virtual gutz::quatf getInvLocalQuat() const = 0; 00166 00167 ///@} 00168 //////////////////////////////////////////////////////////// 00169 00170 //////////////////////////////////////////////////////////// 00171 ///@name Position & orientation 00172 ///@{ 00173 virtual gutz::vec3f getLocalPos() const = 0; 00174 virtual void setLocalPos(const vec3f &pos) = 0; 00175 virtual gutz::mat3f getLocalOrient() const = 0; 00176 virtual void setLocalQuat(const quatf &lq) = 0; 00177 gutz::vec3f getWorldPos() const 00178 { if( getParent() ) return getParent()->getWorldPosLocal( getLocalPos() ); 00179 return getLocalPos(); 00180 } 00181 virtual void setWorldPos(const vec3f &wpos) 00182 { 00183 if( getParent() ) 00184 { setLocalPos( getParent()->getLocalPosWorld(wpos) ); return; } 00185 setLocalPos( wpos ); 00186 } 00187 gutz::mat3f getWorldOrient() const 00188 { return mat3f(getWorldQuat()) * getLocalOrient(); } 00189 ///@} 00190 //////////////////////////////////////////////////////////// 00191 00192 //////////////////////////////////////////////////////////// 00193 ///@name Events 00194 /// Maps buttons & modifiers to actions, speed determines 00195 /// the rate of the action for that button, state combo. 00196 /// Concrete class, camera, object, light etc... will 00197 /// define valid actions. 00198 ///@{ 00199 virtual bool mouse(const MouseEvent &me) = 0; 00200 virtual bool move(const MouseMoveEvent &mme) = 0; 00201 ///@} 00202 ///////////////////////////////////////////////////////////// 00203 00204 //////////////////////////////////////////////////////////// 00205 ///@name Tumble. 00206 /// enable/disable rotations with inertia 00207 ///@{ 00208 void setTumble(bool on){ _tumble = on;} 00209 bool getTumble() const { return _tumble; } 00210 /// Update tumble "speed" amout 00211 virtual void tumble(float speed = 1){} 00212 ///@} 00213 ///////////////////////////////////////////////////////////// 00214 00215 //////////////////////////////////////////////////////////// 00216 ///@name Projections: Mapping a point from one space to another 00217 /// Given either a "WORLD", "EYE", "SCREEN", or "LOCAL" space pos. 00218 /// Read it like this: get{A}Pos{B} means "map a 00219 /// point to space {A} from space {B} (ie A<-B)" 00220 ///@{ 00221 00222 /// WORLD->LOCAL, You have a point in WORLD space and now you want it in LOCAL space 00223 virtual gutz::vec3f getLocalPosWorld(const gutz::vec3f &wpos) const = 0; 00224 /// WORLD->LOCAL dir, You have a vector (direction) in WORLD, you want it in LOCAL 00225 virtual gutz::vec3f getLocalDirWorld(const gutz::vec3f &wdir) const = 0; 00226 /// WORLD<-LOCAL, You have a LOCAL point and you want it in WORLD space 00227 virtual gutz::vec3f getWorldPosLocal(const gutz::vec3f &lpos) const = 0; 00228 /// WORLD<-LOCAL dir, You have a vector (direction) in WORLD, you want it in LOCAL 00229 virtual gutz::vec3f getWorldDirLocal(const gutz::vec3f &ldir) const = 0; 00230 /// EYE->LOCAL, You have an EYE space point and want it in LOCAL space 00231 virtual gutz::vec3f getLocalPosEye(const gutz::vec3f &epos) const = 0; 00232 /// EYE<-LOCAL, You have a LOCAL space point and want it in EYE space 00233 virtual gutz::vec3f getEyePosLocal(const gutz::vec3f &lpos) const = 0; 00234 /// SCREEN->LOCAL, You have a point in SCREEN space and now you want it in "this" space 00235 virtual gutz::vec3f getLocalPosScreen(const gutz::vec3f &spos) const = 0; 00236 /// SCREEN<-LOCAL, You have a point in LOCAL space and want it in SCREEN space 00237 virtual gutz::vec3f getScreenPosLocal(const gutz::vec3f &lpos) const = 0; 00238 00239 ///@} 00240 00241 ///////////////////////////////////////////////////////////// 00242 ///@name Vectors 00243 /// Simmilar to Projections, but rather than projecting a 00244 /// point you are projecting/deriving a direction vector. 00245 /// This is needed since our Camera class supports both perspective 00246 /// and orthographic projections, this affects how we view rays 00247 /// "from the eye" through any other point, in ortho the direction 00248 /// is always the same, in perspective, the direction depends on 00249 /// the eye's position. 00250 ///@{ 00251 00252 /// get a LOCAL direction (ray) through a LOCAL point from the eye 00253 virtual gutz::vec3f getLocalEyeRayLocal(const gutz::vec3f &lpos) const = 0; 00254 /// get a LOCAL direction through a SCREEN point from the eye 00255 virtual gutz::vec3f getLocalEyeRayScreen(const gutz::vec3f &spos) const = 0; 00256 /// get a World direction through a Screen point from the eye 00257 virtual gutz::vec3f getWorldEyeRayScreen(const gutz::vec3f &spos) const = 0; 00258 /// get a World direction through a World point from the eye 00259 virtual gutz::vec3f getWorldEyeRayWorld(const gutz::vec3f &wpos) const = 0; 00260 /// get the View direction in LOCAL space 00261 virtual gutz::vec3f getLocalViewDir() const = 0; 00262 00263 ///@} 00264 ///////////////////////////////////////////////////////////// 00265 00266 //////////////////////////////////////////////////////////// 00267 ///@name Serialization. returns true if fail, false if success 00268 ///@{ 00269 00270 /// write. 00271 virtual bool serialize(std::ostream &os, const std::string indent = std::string("")); 00272 /// read. 00273 virtual bool unserialize(std::istream &is); 00274 /// specific parts of this object 00275 /// serialize the data parts of this guy for momentos & transmission 00276 virtual bool serialData(std::ostream &os, const std::string indent = std::string("")); 00277 virtual bool unserialData(std::istream &is); 00278 ///@} 00279 //////////////////////////////////////////////////////////// 00280 00281 protected: 00282 00283 BaseManip() 00284 : _tumble(false) 00285 {} 00286 /// copy constructor copies data & behavior 00287 BaseManip(const BaseManip &bm) 00288 : _tumble(bm._tumble) 00289 {} 00290 /// assignment doesn't copy behavior, just data! 00291 BaseManip &operator=(const BaseManip &bm) 00292 { return *this; } 00293 00294 //////////////////////////////////////////////////////////// 00295 // protected data 00296 //////////////////////////////////////////////////////////// 00297 00298 //bool _on; ///< Drawing on??? 00299 bool _tumble; ///< Tumble on??? 00300 00301 //unsigned int _currentButtons; ///< Currently active buttons 00302 00303 unsigned int _currentMode; ///< Current mode 00304 float _currentSpeed; ///< Current speed 00305 00306 //float _lastX, _lastY; ///< Last mouse positions 00307 float _lastd; ///< Last distance traveled 00308 00309 }; 00310 00311 typedef gutz::SmartPtr<BaseManip> BaseManipSP; 00312 00313 } //end namespace gutz 00314 00315 #endif 00316