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

SurfaceWidget.h

Go to the documentation of this file.
00001 //------------------------------------------------------------------------
00002 //
00003 //   Joe Kniss
00004 //     9-9-03
00005 //                   ________    ____   ___ 
00006 //                  |        \  /    | /  /
00007 //                  +---+     \/     |/  /
00008 //                  +--+|  |\    /|     < 
00009 //                  |  ||  | \  / |  |\  \ 
00010 //                  |      |  \/  |  | \  \ 
00011 //                   \_____|      |__|  \__\
00012 //                       Copyright  2003 
00013 //                      Joe Michael Kniss
00014 //                   <<< jmk@cs.utah.edu >>>
00015 //               "All Your Base are Belong to Us"
00016 //-------------------------------------------------------------------------
00017 
00018 /// SurfaceWidget.h
00019 
00020 #ifndef __SURFACE_WIDGET_DOT_H
00021 #define __SURFACE_WIDGET_DOT_H
00022 
00023 #include <signalGutz.h>
00024 #include "WidgetBase.h"
00025 
00026 ///////////////////////////////////////////////////////////////////////////
00027 /// SurfaceWidget, fully constrained to 4 points.
00028 /// Be sure that your concrete implementation checks if
00029 ///  the gutz::RenderEvent is in pick mode, gutz::RenderEvent::picking().
00030 ///  This is important if you are rendering an "invisible" plane
00031 ///  that can be selected, you need to make it visible while picking 
00032 ///  is happening.
00033 /// \code
00034 ///  drawDef(const gutz::RenderEvent &re)
00035 ///  {
00036 ///     if(re.picking())
00037 ///        drawThePlane(...);
00038 ///     else
00039 ///        /// maybe do nothing if invisible
00040 ///  }
00041 /// \endcode
00042 /// You can also optimize the pick procedure, by turning off complicated
00043 ///   shaders and stuff, since it isn't a visible render pass when picking;
00044 ///   you only need to render the surface of the plane.
00045 class SurfaceWidget : public WidgetItem {
00046 public:
00047    
00048    enum SURFACE_W_BEHAVIORS {
00049       PICK = WB_LAST + 1,   ///< only behavior defined is pick (default left mouse)
00050       SW_LAST
00051    };
00052 
00053    SurfaceWidget(WidgetItem *parent, float border = 0, bool drawBorder = false);
00054    virtual ~SurfaceWidget() {}
00055 
00056    ////////////////////////////////////////////
00057    ///@name Clones
00058    ///@{
00059 
00060    /// WidgetItem::clone definition
00061    WidgetItem *clone() const
00062    {  return cloneSurface(); }
00063 
00064    /// Pure virtual cloneSurface(), must be defined in 
00065    ///   (all) concrete SurfaceWidget classes
00066    virtual SurfaceWidget *cloneSurface() const = 0;
00067 
00068    ///@}
00069    ////////////////////////////////////////////
00070 
00071    /// object changed
00072    virtual void setChanged()
00073    {
00074       for(int i=0; i<NODE_LAST; ++i)
00075          pointChanged(i,_corners[i]);
00076    }
00077 
00078    /// assignment operator, just copys position information
00079    SurfaceWidget &operator=(const SurfaceWidget &sw)
00080    {  
00081       for(int i=0; i<NODE_LAST; ++i) setPoint(i,sw.getPoint(i));
00082       return *this;
00083    }
00084 
00085    /// points corresponding to a frame (4point) surface
00086    enum SURFACE_POINTS {
00087       LL,       ///< Lower Left
00088       LR,       ///< Lower Right
00089       UL,       ///< Upper Left
00090       UR,       ///< Upper Right
00091       NODE_LAST ///< also the number of points/nodes
00092    };
00093 
00094    HAS_SLOTS;
00095 
00096    ////////////////////////////////////////////
00097    ///@name set/get Points
00098    ///@{
00099    gutz::vec3f  getPoint(int ptIdx) const                 
00100    { return _manip->getWorldPosLocal(_corners[ptIdx]); }
00101    void         setPoint(int ptIdx, const gutz::vec3f &pt) 
00102    {
00103       _invalidate();
00104       {
00105          _corners[ptIdx] = _manip->getLocalPosWorld(pt); 
00106       }
00107       _update();
00108       pointChanged(ptIdx, getPoint(ptIdx));
00109    }
00110    ///get the plane that defines the surface, see gutz::plane
00111    gutz::planef getPlane() const 
00112    { return gutz::planef(getPoint(LL),
00113                          getPoint(LR),
00114                          getPoint(UL));
00115    }
00116    ///@}
00117    ////////////////////////////////////////////
00118 
00119    ////////////////////////////////////////////
00120    /// @name set specific points (slots):
00121    ///@{
00122    void   setLL(const gutz::vec3f &ll) { setPoint(LL,ll); }
00123    void   setLR(const gutz::vec3f &lr) { setPoint(LR,lr); }
00124    void   setUL(const gutz::vec3f &ul) { setPoint(UL,ul); }
00125    void   setUR(const gutz::vec3f &ur) { setPoint(UR,ur); }
00126    ///@}
00127    ////////////////////////////////////////////
00128 
00129    ////////////////////////////////////////////
00130    ///@name Signals
00131    ///@{
00132 
00133    /// pointChanged(int,vec3f), point index & the point itself
00134    gutz::Signal<int, const gutz::vec3f &> pointChanged;
00135 
00136    /// signal: surfacePicked(const vec3f &pt);
00137    gutz::Signal<const gutz::vec3f &> surfacePicked;
00138 
00139    /// signal: surfacePickMoved(const vec3f &)
00140    gutz::Signal<const gutz::vec3f &> surfacePickMoved;
00141 
00142    ///@}
00143    ////////////////////////////////////////////
00144 
00145    ////////////////////////////////////////////
00146    ///@name Transform Widget
00147    ///@{
00148    virtual void    applyXform(gutz::mat4f xf)
00149    { for(int i=0; i<NODE_LAST; ++i) _corners[i] = xf * _corners[i]; }
00150    ///@}
00151 
00152    /////////////////////////////////////////////////////
00153    ///@name Behaviors from WidgetItem
00154    ///@{
00155    virtual bool mouseDef(const gutz::MouseEvent &me);
00156    virtual bool moveDef(const gutz::MouseMoveEvent &mme);
00157    ///@}
00158    /////////////////////////////////////////////////////
00159 
00160 protected:
00161    gutz::vec3f intersectPlane(const gutz::MouseEvent &me) const;
00162 
00163    /// Copy does not copy/clone content, you need to handle that
00164    ///  yourself.  Do you need to copy signals too? There are a number of
00165    ///  things that make copying content unique, resolve those outside this
00166    ///  class.
00167    SurfaceWidget(const SurfaceWidget &sw)
00168       : WidgetItem(sw)
00169    {
00170       for(int i=0; i<NODE_LAST; ++i)
00171          _corners[i] = sw._corners[i];
00172    }
00173 
00174    /// These points are in LOCAL space
00175    gutz::vec3f  _corners[NODE_LAST];
00176 
00177    /// This point is in WORLD space!!
00178    gutz::vec3f  _lastPick;
00179 
00180 };
00181 typedef gutz::SmartPtr<SurfaceWidget> SurfaceWidgetSP;
00182 
00183 
00184 #endif
00185 
00186 

Send questions, comments, and bug reports to:
jmk