arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

baseManip.h

Go to the documentation of this file.
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 

Send questions, comments, and bug reports to:
jmk