ARGoS  3
A parallel, multi-engine simulator for swarm robotics
plugins/simulator/visualizations/qt-opengl/qtopengl_user_functions.h
Go to the documentation of this file.
00001 
00007 #ifndef QTOPENGL_USER_FUNCTIONS_H
00008 #define QTOPENGL_USER_FUNCTIONS_H
00009 
00010 namespace argos {
00011    class CQTOpenGLUserFunctions;
00012    class CFloorEntity;
00013 }
00014 
00015 class QPainter;
00016 
00017 #include <argos3/plugins/simulator/visualizations/qt-opengl/qtopengl_widget.h>
00018 #include <argos3/core/utility/datatypes/color.h>
00019 #include <argos3/core/utility/math/quaternion.h>
00020 
00021 namespace argos {
00022 
00072    class CQTOpenGLUserFunctions {
00073 
00074    public:
00075 
00079       CQTOpenGLUserFunctions();
00080 
00084       virtual ~CQTOpenGLUserFunctions();
00085 
00089       virtual void Draw(CFloorEntity& c_entity) {}
00090 
00096       virtual void DrawInWorld() {}
00097 
00105       virtual void DrawOverlay(QPainter& c_painter) {}
00106 
00111       inline CQTOpenGLWidget& GetOpenGLWidget() {
00112          return *m_pcQTOpenGLWidget;
00113       }
00114 
00119       inline void SetOpenGLWidget(CQTOpenGLWidget& c_widget) {
00120          m_pcQTOpenGLWidget = &c_widget;
00121       }
00122 
00134       void DrawTriangle(const CVector3& c_center_offset = CVector3::ZERO,
00135                         const CColor& c_color = CColor::RED,
00136                         const bool b_fill = true,
00137                         const CQuaternion& c_orientation = CQuaternion(),
00138                         Real f_base = 0.2f,
00139                         Real f_height = 0.1732050808f);
00140 
00152       void DrawCircle(Real f_radius = 0.1f,
00153                       const CVector3& c_center_offset = CVector3::ZERO,
00154                       const CColor& c_color = CColor::RED,
00155                       const bool b_fill = true,
00156                       const CQuaternion& c_orientation = CQuaternion(),
00157                       GLuint un_vertices = 20);
00158 
00159 
00171       void DrawCylinder(Real f_radius=0.1f,
00172                         Real f_height=0.1f,
00173                         const CVector3& c_center_offset = CVector3::ZERO,
00174                         const CColor& c_color = CColor::RED,
00175                         const CQuaternion& c_orientation = CQuaternion(),
00176                         GLuint un_vertices = 20);
00177 
00178 
00190       void DrawSegment(const CVector3& c_end_point = CVector3(1.0f,0.0f,1.0f),
00191                        const CVector3& c_start_point = CVector3::ZERO,
00192                        const CColor& c_segment_color = CColor::RED,
00193                        const Real& f_line_width = 1.0f,
00194                        bool b_draw_end_point = false,
00195                        bool b_draw_start_point = false,
00196                        const CColor& c_end_point_color = CColor::RED,
00197                        const CColor& c_start_point_color = CColor::RED);
00198 
00205       void DrawPolygon(const std::vector<CVector3>& vec_points,
00206                        const CColor& c_color = CColor::RED);
00207 
00208 
00216       void DrawPoint(const CVector3& c_position = CVector3(1.0f,0.0f,1.0f),
00217                      const CColor& c_color = CColor::RED,
00218                      const Real f_point_diameter  = 5.0);
00219 
00220    private:
00221 
00226       typedef void (CQTOpenGLUserFunctions::*TThunk)(CEntity&);
00227 
00237       template <typename USER_IMPL, typename ENTITY>
00238       void Thunk(CEntity& c_entity);
00239 
00244       class CFunctionHolder {};
00245 
00253       template <typename USER_IMPL, typename ENTITY> class CFunctionHolderImpl : public CFunctionHolder {
00254       public:
00255          typedef void (USER_IMPL::*TFunction)(ENTITY&);
00256          TFunction Function;
00257          CFunctionHolderImpl(TFunction t_function) : Function(t_function) {}
00258       };
00259 
00265       CVTable<CQTOpenGLUserFunctions, CEntity, TThunk> m_cThunks;
00266 
00271       std::vector<CFunctionHolder*> m_vecFunctionHolders;
00272 
00273    public:
00274 
00281       template <typename USER_IMPL, typename ENTITY>
00282       void RegisterUserFunction(void(USER_IMPL::*pt_function)(ENTITY&));
00283 
00288       void Call(CEntity& c_entity);
00289 
00290    private:
00291 
00295       CQTOpenGLWidget* m_pcQTOpenGLWidget;
00296 
00297    };
00298 
00299    /****************************************/
00300    /****************************************/
00301 
00302    template <typename USER_IMPL, typename ENTITY>
00303    void CQTOpenGLUserFunctions::Thunk(CEntity& c_entity) {
00304       /*
00305        * When this method is called, the static type of 'this'
00306        * is CQTOpenGLUserFunctions. Since we want to call
00307        * method in USER_IMPL (subclass of CQTOpenGLUserFunctions),
00308        * we need a cast. The cast is static because we trust
00309        * the user on not doing anything stupid.
00310        * The variable cImpl can be static because the cast is necessary
00311        * only the first time this function is called.
00312        */
00313       static USER_IMPL& cImpl = static_cast<USER_IMPL&>(*this);
00314       /* Cast the argument to the right type */
00315       ENTITY& cEntity = static_cast<ENTITY&>(c_entity);
00316       /* Cast the function holder to its effective type */
00317       CFunctionHolderImpl<USER_IMPL,ENTITY>& cFunctionHolder = static_cast<CFunctionHolderImpl<USER_IMPL,ENTITY>&>(*m_vecFunctionHolders[GetTag<ENTITY,CEntity>()]);
00318       /* Call the user-defined method */
00319       (cImpl.*(cFunctionHolder.Function))(cEntity);
00320    }
00321 
00322    template <typename USER_IMPL, typename ENTITY>
00323    void CQTOpenGLUserFunctions::RegisterUserFunction(void(USER_IMPL::*pt_function)(ENTITY&)) {
00324       /* Add the thunk to the VTable */
00325       m_cThunks.Add<ENTITY>(&CQTOpenGLUserFunctions::Thunk<USER_IMPL,ENTITY>);
00326       /* Add the function holder to the vector, padding gaps with NULL pointers */
00327       size_t unIdx = GetTag<ENTITY,CEntity>();
00328       if(m_vecFunctionHolders.size() <= unIdx) {
00329          m_vecFunctionHolders.resize(unIdx+1, NULL);
00330       }
00331       m_vecFunctionHolders[unIdx] = new CFunctionHolderImpl<USER_IMPL,ENTITY>(pt_function);
00332    }
00333    
00334    /****************************************/
00335    /****************************************/
00336 
00337 }
00338 
00339 /* Definitions useful for dynamic linking of user functions */
00340 #define REGISTER_QTOPENGL_USER_FUNCTIONS(CLASSNAME, LABEL)  \
00341    REGISTER_SYMBOL(CQTOpenGLUserFunctions,                  \
00342                    CLASSNAME,                               \
00343                    LABEL,                                   \
00344                    "undefined",                             \
00345                    "undefined",                             \
00346                    "undefined",                             \
00347                    "undefined",                             \
00348                    "undefined")
00349 
00350 #endif