diff --git a/CMakeModules/FindCDBAPP.cmake b/CMakeModules/FindCDBAPP.cmake new file mode 100644 index 00000000..2cd2ddfd --- /dev/null +++ b/CMakeModules/FindCDBAPP.cmake @@ -0,0 +1,40 @@ +FIND_PATH(CDBAPP_INCLUDE_DIR cdbapp/ApplicationDatabaseInterface.h + PATHS + $ENV{CDBAPP_HOME} + NO_DEFAULT_PATH + PATH_SUFFIXES include +) + +FIND_PATH(CDBAPP_INCLUDE_DIR cdbapp/ApplicationDatabaseInterface.h + PATHS + /usr/local/include + /usr/include + /sw/include # Fink + /opt/local/include # DarwinPorts + /opt/csw/include # Blastwave + /opt/include +) + +FIND_LIBRARY(CDBAPP_LIBRARY + NAMES cdbapp + PATHS $ENV{CDBAPP_HOME} + NO_DEFAULT_PATH + PATH_SUFFIXES lib64 lib +) +FIND_LIBRARY(CDBAPP_LIBRARY + NAMES cdbapp + PATHS + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt + /usr/freeware + PATH_SUFFIXES lib64 lib +) + +SET(CDBAPP_FOUND "NO") +IF(CDBAPP_LIBRARY AND CDBAPP_INCLUDE_DIR) + SET(CDBAPP_FOUND "YES") +ENDIF(CDBAPP_LIBRARY AND CDBAPP_INCLUDE_DIR) diff --git a/include/cvrKernel/CalVR.h b/include/cvrKernel/CalVR.h index 9bf1ff39..6f03fd34 100644 --- a/include/cvrKernel/CalVR.h +++ b/include/cvrKernel/CalVR.h @@ -27,6 +27,7 @@ class MenuManager; class FileHandler; class PluginManager; class ThreadedLoader; +class StateManager; /** * @addtogroup kernel cvrKernel @@ -124,6 +125,7 @@ class CVRKERNEL_EXPORT CalVR FileHandler * _file; PluginManager * _plugins; ThreadedLoader * _threadedLoader; + StateManager * _stateManager; }; /** diff --git a/include/cvrKernel/DatabaseHandler.h b/include/cvrKernel/DatabaseHandler.h new file mode 100644 index 00000000..6ebdd675 --- /dev/null +++ b/include/cvrKernel/DatabaseHandler.h @@ -0,0 +1,71 @@ +/* + * DatabaseHandler.h + * + * Used to send and receive states between a collaboration server and CalVR. + * + * Created on: Apr 29, 2012 + * Author: John Mangan + * + * CalVR Port: Jul 16, 2013 + * Author: John Mangan + */ + +#ifndef DATABASE_HANDLER_H_ +#define DATABASE_HANDLER_H_ + +#include +#include +#include +#include + +#include +#include + +namespace cvr { + +class DatabaseHandler : public Listener +{ +public: + + void + Connect(std::string const& connectionAddress); + + void + Disconnect(void); + + bool + LoadStateChanges( std::list< std::string >& loadedStates ); + + void + SendHeardStates(void); + +protected: + + /* Hearing CvrStates (External concepts): + * - Store CvrState as a JSON string to be passed to the the collaboration server (database). + */ + void + Hear(CvrState* cvrState); + + cdb::ApplicationDatabaseInterface mDatabase; + uint64_t mLastLoadTimestep; + std::map< std::string, std::string > mHeardStates; + +}; + +inline void +DatabaseHandler::Connect(std::string const& connectionAddress) +{ + mDatabase.Connect(connectionAddress); + mLastLoadTimestep = 0; +} + +inline void +DatabaseHandler::Disconnect(void) +{ + mDatabase.Disconnect(); +} + +} + +#endif /* DATABASE_HANDLER_H_ */ diff --git a/include/cvrKernel/FileHandler.h b/include/cvrKernel/FileHandler.h index 1089fabb..c59232f7 100644 --- a/include/cvrKernel/FileHandler.h +++ b/include/cvrKernel/FileHandler.h @@ -14,6 +14,9 @@ namespace cvr { +class SceneObject; +class MetadataState; + class CVRKERNEL_EXPORT FileLoadCallback; // TODO: add unload function call @@ -38,14 +41,25 @@ class CVRKERNEL_EXPORT FileHandler /** * @brief try to load a file - * @param file file to load - * @return true if file is loaded + * @param file filepath of file to load + * @return NULL if file could not be loaded, SceneObject* otherwise that is neither registered nor attached to the scene * * Will determine if the extension is registered with a callback and attempt * to load with it. If callback not present, or fails, osg readNodeFile is tried - * and the result is attached to the object root. + * and the result is attached to a SceneObject. */ - bool loadFile(std::string file); + SceneObject* loadFile(std::string file); + + /** + * @brief try to load a file + * @param metadata MetadataState containing data of the file to load + * @return NULL if file could not be loaded, SceneObject* otherwise that is neither registered nor attached to the scene + * + * Will determine if the extension is registered with a callback and attempt + * to load with it. If callback not present, or fails, osg readNodeFile is tried + * and the result is attached to a SceneObject. + */ + SceneObject* loadFile(MetadataState* metadata); /** * @brief register a callback for when a file with a certain extension is loaded @@ -71,12 +85,14 @@ class CVRKERNEL_EXPORT FileHandler static FileHandler * _myPtr; ///< static self pointer + SceneObject* loadFileDriver(std::string file); + std::map _extMap; ///< map of file extension to callback }; /** * @brief Interface class to receive a callback from the FileHandler when a file with a certain - * extension is being loaded + * extension is being loaded. */ class CVRKERNEL_EXPORT FileLoadCallback { @@ -90,9 +106,9 @@ class CVRKERNEL_EXPORT FileLoadCallback virtual ~FileLoadCallback(); /** - * @brief function called when a file with a registered extension is loaded + * @brief function called when a file with a registered extension is loaded. It is expected that the returned SceneObject is neither registered nor attached to the scene. */ - virtual bool loadFile(std::string file) = 0; + virtual SceneObject* loadFile(std::string file) = 0; private: std::vector _exts; ///< list of extensions registed to this callback }; diff --git a/include/cvrKernel/SceneManager.h b/include/cvrKernel/SceneManager.h index 6278cf3e..6e0d818d 100644 --- a/include/cvrKernel/SceneManager.h +++ b/include/cvrKernel/SceneManager.h @@ -7,6 +7,9 @@ #include #include +#include +#include +#include #include #include @@ -58,7 +61,7 @@ template class VectorWithPosition : public std::vector /** * @brief Creates and manages the main scenegraph */ -class CVRKERNEL_EXPORT SceneManager +class CVRKERNEL_EXPORT SceneManager : public Listener { friend class CVRViewer; friend class CVRPlugin; @@ -284,6 +287,9 @@ class CVRKERNEL_EXPORT SceneManager bool getPointOnTiledWall(const osg::Matrix & mat, osg::Vec3 & wallPoint); + friend SceneObject* FileHandler::loadFile(std::string); + friend SceneObject* FileHandler::loadFile(MetadataState*); + protected: SceneManager(); @@ -305,6 +311,8 @@ class CVRKERNEL_EXPORT SceneManager void preDraw(); void postDraw(); + void Hear(CvrState* cvrstate); + static SceneManager * _myPtr; ///< static self pointer bool _showAxis; ///< should debug axis be shown @@ -337,6 +345,9 @@ class CVRKERNEL_EXPORT SceneManager bool _uniqueMapInUse; std::map > _pluginObjectMap; ///< set of all registered SceneObjects grouped by plugin name + std::map< std::string, SceneObject* > _metadataToSceneObjects; + std::map< std::string, std::set< std::string > > _metaOrphans; + float _menuScale; float _menuMinDistance; float _menuMaxDistance; diff --git a/include/cvrKernel/SceneObject.h b/include/cvrKernel/SceneObject.h index 9652c455..051d320e 100644 --- a/include/cvrKernel/SceneObject.h +++ b/include/cvrKernel/SceneObject.h @@ -9,12 +9,15 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include @@ -23,6 +26,9 @@ namespace cvr class MenuCheckbox; class MenuRangeValue; +class MetadataState; +class SpatialState; +class CollaborationState; /** * @addtogroup kernel @@ -34,7 +40,7 @@ class MenuRangeValue; * * Handles movement, navigation and interaction. These objects can be nested. */ -class CVRKERNEL_EXPORT SceneObject : public MenuCallback +class CVRKERNEL_EXPORT SceneObject : public MenuCallback, public Listener { friend class SceneManager; public: @@ -95,6 +101,17 @@ class CVRKERNEL_EXPORT SceneObject : public MenuCallback */ void setMovable(bool mov); + + /** + * @brief Get if this object shoudl be collaborated. + */ + bool getCollaborate(); + + /** + * @brief Set if this object shoudl be collaborated. + */ + void setCollaborate(bool collab); + /** * @brief Get if this object is clippable */ @@ -271,6 +288,18 @@ class CVRKERNEL_EXPORT SceneObject : public MenuCallback */ void removeNavigationMenuItem(); + /** + * @brief Add a MenuCheckbox to this object's context menu that toggles + * if this object is collaborative + * @param label Label to use for the MenuItem + */ + void addCollaborateMenuItem(std::string label = "Collaborate"); + + /** + * @brief Remove collaborate MenuCheckbox if it has been added to the context menu + */ + void removeCollaborateMenuItem(); + /** * @brief Add a MenuRangeValue to this object's context menu that controls the scale * of the object @@ -394,6 +423,16 @@ class CVRKERNEL_EXPORT SceneObject : public MenuCallback */ void closeMenu(); + void addCvrState( CvrState* const state ); + + void removeCvrState( CvrState* const state ); + + std::set< CvrState* > getCvrStatesByType( std::string type ); + + MetadataState* getMetadataState(void); + SpatialState* getSpatialState(void); + CollaborationState* getCollaborationState(void); + protected: bool getRegistered() { @@ -426,6 +465,17 @@ class CVRKERNEL_EXPORT SceneObject : public MenuCallback void updateBoundsGeometry(); void updateMatrices(); void splitMatrix(); + void checkAndUpdateNavigation(); + void checkAndUpdateCollaboration(); + + /** + * @brief If it hears it's own SpatialState, it overrides all spatial + * with the newly heard state. + */ + void Hear(CvrState* cvrstate); + + SpatialState* getOrCreateSpatialState(void); + CollaborationState* getOrCreateCollaborationState(void); void interactionCountInc(); void interactionCountDec(); @@ -435,7 +485,6 @@ class CVRKERNEL_EXPORT SceneObject : public MenuCallback osg::ref_ptr _boundsTransform; osg::ref_ptr _boundsGeode; osg::ref_ptr _boundsGeodeActive; - osg::Matrix _transMat, _scaleMat; osg::Matrix _obj2root, _root2obj; osg::Matrix _invTransform; @@ -443,10 +492,10 @@ class CVRKERNEL_EXPORT SceneObject : public MenuCallback PopupMenu * _myMenu; MenuCheckbox * _moveMenuItem; MenuCheckbox * _navMenuItem; + MenuCheckbox * _collabMenuItem; MenuRangeValue * _scaleMenuItem; std::string _name; - bool _navigation; bool _movable; bool _clip; bool _contextMenu; @@ -454,6 +503,7 @@ class CVRKERNEL_EXPORT SceneObject : public MenuCallback bool _registered; bool _attached; bool _eventActive; + bool _collaborated; int _moveButton; int _menuButton; @@ -474,6 +524,8 @@ class CVRKERNEL_EXPORT SceneObject : public MenuCallback SceneObject * _parent; int _interactionCount; + + std::map< std::string, std::set< CvrState* > > _cvrStates; }; /** diff --git a/include/cvrKernel/ScreenBase.h b/include/cvrKernel/Screens/ScreenBase.h similarity index 100% rename from include/cvrKernel/ScreenBase.h rename to include/cvrKernel/Screens/ScreenBase.h diff --git a/include/cvrKernel/ScreenFixedViewer.h b/include/cvrKernel/Screens/ScreenFixedViewer.h similarity index 97% rename from include/cvrKernel/ScreenFixedViewer.h rename to include/cvrKernel/Screens/ScreenFixedViewer.h index 76ff05c5..22e16c5b 100644 --- a/include/cvrKernel/ScreenFixedViewer.h +++ b/include/cvrKernel/Screens/ScreenFixedViewer.h @@ -5,7 +5,7 @@ #ifndef CALVR_SCREEN_FIXED_VIEWER_H #define CALVR_SCREEN_FIXED_VIEWER_H -#include +#include namespace cvr { diff --git a/include/cvrKernel/ScreenHMD.h b/include/cvrKernel/Screens/ScreenHMD.h similarity index 98% rename from include/cvrKernel/ScreenHMD.h rename to include/cvrKernel/Screens/ScreenHMD.h index b435b839..4f76c0bf 100644 --- a/include/cvrKernel/ScreenHMD.h +++ b/include/cvrKernel/Screens/ScreenHMD.h @@ -5,7 +5,7 @@ #ifndef CALVR_SCREEN_HMD_H #define CALVR_SCREEN_HMD_H -#include +#include #include #include diff --git a/include/cvrKernel/ScreenInterlacedTopBottom.h b/include/cvrKernel/Screens/ScreenInterlacedTopBottom.h similarity index 98% rename from include/cvrKernel/ScreenInterlacedTopBottom.h rename to include/cvrKernel/Screens/ScreenInterlacedTopBottom.h index b5dd2121..9cb84008 100644 --- a/include/cvrKernel/ScreenInterlacedTopBottom.h +++ b/include/cvrKernel/Screens/ScreenInterlacedTopBottom.h @@ -5,7 +5,7 @@ #ifndef CALVR_SCREEN_INTERLACED_TOP_BOTTOM_H #define CALVR_SCREEN_INTERLACED_TOP_BOTTOM_H -#include +#include #include #include diff --git a/include/cvrKernel/ScreenLenticular.h b/include/cvrKernel/Screens/ScreenLenticular.h similarity index 98% rename from include/cvrKernel/ScreenLenticular.h rename to include/cvrKernel/Screens/ScreenLenticular.h index 75bc226d..9e367be2 100644 --- a/include/cvrKernel/ScreenLenticular.h +++ b/include/cvrKernel/Screens/ScreenLenticular.h @@ -7,7 +7,7 @@ #include -#include +#include #include #include diff --git a/include/cvrKernel/ScreenMVCullVisitor.h b/include/cvrKernel/Screens/ScreenMVCullVisitor.h similarity index 100% rename from include/cvrKernel/ScreenMVCullVisitor.h rename to include/cvrKernel/Screens/ScreenMVCullVisitor.h diff --git a/include/cvrKernel/ScreenMVMaster.h b/include/cvrKernel/Screens/ScreenMVMaster.h similarity index 97% rename from include/cvrKernel/ScreenMVMaster.h rename to include/cvrKernel/Screens/ScreenMVMaster.h index c6e99534..c469cd3d 100644 --- a/include/cvrKernel/ScreenMVMaster.h +++ b/include/cvrKernel/Screens/ScreenMVMaster.h @@ -5,7 +5,7 @@ #ifndef CALVR_SCREEN_MV_MASTER_H #define CALVR_SCREEN_MV_MASTER_H -#include +#include namespace cvr { diff --git a/include/cvrKernel/ScreenMVShader.h b/include/cvrKernel/Screens/ScreenMVShader.h similarity index 99% rename from include/cvrKernel/ScreenMVShader.h rename to include/cvrKernel/Screens/ScreenMVShader.h index bb468cfa..1905a942 100644 --- a/include/cvrKernel/ScreenMVShader.h +++ b/include/cvrKernel/Screens/ScreenMVShader.h @@ -6,7 +6,7 @@ #define GL_GLEXT_PROTOTYPES -#include +#include #include #include diff --git a/include/cvrKernel/ScreenMVSimulator.h b/include/cvrKernel/Screens/ScreenMVSimulator.h similarity index 98% rename from include/cvrKernel/ScreenMVSimulator.h rename to include/cvrKernel/Screens/ScreenMVSimulator.h index 0a093608..dec6fcae 100644 --- a/include/cvrKernel/ScreenMVSimulator.h +++ b/include/cvrKernel/Screens/ScreenMVSimulator.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include namespace cvr diff --git a/include/cvrKernel/ScreenMVStencil.h b/include/cvrKernel/Screens/ScreenMVStencil.h similarity index 99% rename from include/cvrKernel/ScreenMVStencil.h rename to include/cvrKernel/Screens/ScreenMVStencil.h index fe1652b4..c4fd9319 100644 --- a/include/cvrKernel/ScreenMVStencil.h +++ b/include/cvrKernel/Screens/ScreenMVStencil.h @@ -5,7 +5,7 @@ #ifndef CALVR_SCREEN_MV_STENCIL_H #define CALVR_SCREEN_MV_STENCIL_H -#include +#include #include #include diff --git a/include/cvrKernel/ScreenMVZones.h b/include/cvrKernel/Screens/ScreenMVZones.h similarity index 99% rename from include/cvrKernel/ScreenMVZones.h rename to include/cvrKernel/Screens/ScreenMVZones.h index 30a74c26..088d6674 100644 --- a/include/cvrKernel/ScreenMVZones.h +++ b/include/cvrKernel/Screens/ScreenMVZones.h @@ -8,8 +8,8 @@ #include #include -#include -#include +#include +#include #include namespace cvr diff --git a/include/cvrKernel/ScreenMono.h b/include/cvrKernel/Screens/ScreenMono.h similarity index 97% rename from include/cvrKernel/ScreenMono.h rename to include/cvrKernel/Screens/ScreenMono.h index 0b898180..77e7d19d 100644 --- a/include/cvrKernel/ScreenMono.h +++ b/include/cvrKernel/Screens/ScreenMono.h @@ -5,7 +5,7 @@ #ifndef CALVR_SCREEN_MONO_H #define CALVR_SCREEN_MONO_H -#include +#include namespace cvr { diff --git a/include/cvrKernel/ScreenStereo.h b/include/cvrKernel/Screens/ScreenStereo.h similarity index 98% rename from include/cvrKernel/ScreenStereo.h rename to include/cvrKernel/Screens/ScreenStereo.h index 45114542..4b3600a0 100644 --- a/include/cvrKernel/ScreenStereo.h +++ b/include/cvrKernel/Screens/ScreenStereo.h @@ -5,7 +5,7 @@ #ifndef CALVR_SCREEN_STEREO_H #define CALVR_SCREEN_STEREO_H -#include +#include #include #include diff --git a/include/cvrKernel/StateManager.h b/include/cvrKernel/StateManager.h new file mode 100644 index 00000000..7868d3a0 --- /dev/null +++ b/include/cvrKernel/StateManager.h @@ -0,0 +1,114 @@ +/* + * StateManager.h + * + * Rules and Concepts of State Management: + * - Listener classes can be registered to the StateManager to hear alerted CvrStates. + * - Any CvrState can be passed to AlertListeners(). This is to give Registered Listeners a chance to hear about new CvrStates. + * - Any Listener that wants to hear updates about a heard/alerted CvrState should add themselves to the CvrState's local listener list [ cvrstate->AddListener(listener/this) ]. + * - If a listener hears a CvrState for the first time and wishes to see it stored, it should Register the CvrState with StateManager before the Hear() function returns. + * + Any Listener that Registers a CvrState is expected to Unregister it at some point, to allow deallocation. + * + The StateManager is in charge of keeping Registered states in memory. + * - StateManager will never hold interest in whether or not a CvrState is "valid". + * - To toggle a CvrState for collaboration use CollaborateState(string:uuid, bool:enable_collaboration) + * + The CvrState being Collaborated must be Registered. + * + Once marked for Collaboration, all Shouts thereafter will be heard by the DatabaseHandler, which will store it to be sent to the database. + * - The StateManager should only be dealt with on the main thread. + * - The StateManager owns CvrState memory once the CvrState is registered. Listeners that wish to store CvrStates should retain a UUID and grab the State from the StateManager as needed. + * + * Created on: Apr 29, 2012 + * Author: John Mangan + * David Srour + * + * CalVR Port: Jul 15, 2013 + * Author: John Mangan + */ + +#ifndef STATE_MANAGER_H_ +#define STATE_MANAGER_H_ + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +namespace cvr { + +class StateManager : public Listener +{ +public: + friend class CalVR; + + static StateManager* + instance(void); + + void + AlertListeners(CvrState* cvrstate); + + void + CollaborateState(std::string const& uuid, bool const collaborate); + + void + Connect(std::string const& connectionAddress); + + void + Disconnect(void); + + void + Register(Listener* listener); + + void + Register(CvrState* cvrstate); + + CvrState* + StateFromUuid(std::string const& uuid) const; + + void + Unregister(Listener* listener); + + void + Unregister(CvrState* cvrstate); + + void + UpdateLocalStates(void); + + void + UpdateServerStates(void); + +protected: + static StateManager* mInstance; + + StateManager(); + + virtual + ~StateManager(); + + // NOTE: May want to split into multiple maps in the future for efficiency, as necc. + typedef std::map< std::string, osg::ref_ptr > CvrStateMap; // uuid -> cvrstate + + /* Hearing CvrStates (External concepts): + * - Registered CvrState Exists? (matching UUID) + * + Update local State's variables to match incoming State's variables + */ + void + Hear(CvrState* cvrstate); + + void + LoadStateChanges(std::list< std::string >& returned_states); + + bool mNotConnected; + DatabaseHandler mDatabaseHandler; + // TODO: make Registered states contain a reference count, so multiple systems can Register/Unregister + CvrStateMap mStates; + Shouter::Listeners mListeners; +}; + +} + +#endif /* STATE_MANAGER_H_ */ diff --git a/include/cvrKernel/States/CollaborationState.h b/include/cvrKernel/States/CollaborationState.h new file mode 100644 index 00000000..ddec5d3f --- /dev/null +++ b/include/cvrKernel/States/CollaborationState.h @@ -0,0 +1,53 @@ +/* + * CollaborationState.h + * + * Vars (type = "spatial"): + * - "collaborate": bool + * - "metadata": "metadata_state_uuid" + * + * Created on: Sep 10, 2012 + * Author: John Mangan + */ + +#ifndef COLLABORATIONSTATE_H_ +#define COLLABORATIONSTATE_H_ + +#include + +namespace cvr { + +class CollaborationState : public CvrState +{ +public: + static std::string const TYPE; + + CollaborationState(void); + + static void + Register(void); + + bool const + Collaboration(void); + + void + Collaboration(bool const collaboration); + + std::string const + Metadata(void); + + void + Metadata(std::string const& metadata); + +protected: + static CvrState* + Adapter( State const& state ); + + CollaborationState(State const& state); + + virtual + ~CollaborationState(void); +}; + +} + +#endif /* COLLABORATIONSTATE_H_ */ diff --git a/include/cvrKernel/States/CvrState.h b/include/cvrKernel/States/CvrState.h new file mode 100644 index 00000000..a725200f --- /dev/null +++ b/include/cvrKernel/States/CvrState.h @@ -0,0 +1,69 @@ +/* + * CvrState.h + * + * Base state for CalVR. Has a type variable. + * It also derives Shouter. + * + * Created on: Apr 29, 2012 + * Authors: David Srour , + * John Mangan + * + * CalVR Port: Jul 15, 2013 + * Author: John Mangan + */ + +#ifndef CVRSTATE_H_ +#define CVRSTATE_H_ + +#include +#include +#include + +#include + +#include + +namespace cvr { + +class CvrState : public cdb::State, public Shouter, public osg::Referenced +{ +public: + /* + * Returns a CvrState* to the appropriate subclass implementation registered + * to the given State's type, or NULL if none exist. + */ + static CvrState* + AdaptToDerivedCvrState(cdb::State& state); + + std::string const + Type(void); + + bool const + Valid(void); + + void + Valid(bool const valid); + +protected: + typedef CvrState* (*STATIC_ADAPTER)(cdb::State const&); + + static void + Register(std::string const& type, STATIC_ADAPTER staticAdapter); + + // To be used for new states + CvrState(std::string const& type); + + // To be used for adapters + CvrState(cdb::State const& state); + + virtual + ~CvrState(void); + +private: + typedef std::map< std::string, STATIC_ADAPTER > TypeAdapterMap; + static TypeAdapterMap mTypeAdapters; +}; + +} + +#endif /* CVRSTATE_H_ */ diff --git a/include/cvrKernel/States/MetadataState.h b/include/cvrKernel/States/MetadataState.h new file mode 100644 index 00000000..2d2b2d9f --- /dev/null +++ b/include/cvrKernel/States/MetadataState.h @@ -0,0 +1,58 @@ +/* + * MetadataState.h + * + * Vars (type = "metadata"): + * - "path": "path/to/data" + * - "volume": [width, height, depth] + * + * Created on: Apr 29, 2012 + * Authors: David Srour , + * John Mangan + * + * CalVR Port: Jul 22, 2013 + * Author: John Mangan + */ + +#ifndef METADATASTATE_H_ +#define METADATASTATE_H_ + +#include +#include + +namespace cvr { + +class MetadataState : public CvrState +{ +public: + static std::string const TYPE; + + MetadataState(void); + + static void + Register(void); + + std::string const + Path(void); + + void + Path(std::string const& path); + + osg::Vec3 const + Volume(void); + + void + Volume(osg::Vec3 const& volume); + +protected: + static CvrState* + Adapter( State const& state ); + + MetadataState(State const& state); + + virtual + ~MetadataState(void); +}; + +} + +#endif /* METADATASTATE_H_ */ diff --git a/include/cvrKernel/States/SpatialState.h b/include/cvrKernel/States/SpatialState.h new file mode 100644 index 00000000..51ff3c3b --- /dev/null +++ b/include/cvrKernel/States/SpatialState.h @@ -0,0 +1,85 @@ +/* + * SpatialState.h + * + * Vars (type = "spatial"): + * - "position": [x, y, z] + * - "rotation": [x, y, z, w] + * - "scale" : [x, y, z] + * - "metadata": "metadata_state_uuid" + * + * Created on: Apr 29, 2012 + * Authors: David Srour , + * John Mangan + * + * CalVR Port: Sep 3, 2013 + * Author: John Mangan + */ + +#ifndef SPATIALSTATE_H_ +#define SPATIALSTATE_H_ + +#include +#include +#include + +namespace cvr { + +class SpatialState : public CvrState +{ +public: + static std::string const TYPE; + + SpatialState(void); + + static void + Register(void); + + osg::Vec3 const + Position(void); + + void + Position(osg::Vec3 const& position); + + osg::Quat const + Rotation(void); + + void + Rotation(osg::Quat const& rotation); + + osg::Vec3 const + Scale(void); + + void + Scale(osg::Vec3 const& scale); + + bool const + Navigation(void); + + void + Navigation(bool const navigation); + + std::string const + Metadata(void); + + void + Metadata(std::string const& metadata); + + std::string const + Parent(void); + + void + Parent(std::string const& spatial); + +protected: + static CvrState* + Adapter( State const& state ); + + SpatialState(State const& state); + + virtual + ~SpatialState(void); +}; + +} + +#endif /* SPATIALSTATE_H_ */ diff --git a/include/cvrUtil/Listener.h b/include/cvrUtil/Listener.h new file mode 100644 index 00000000..80448925 --- /dev/null +++ b/include/cvrUtil/Listener.h @@ -0,0 +1,28 @@ +/* + * Listener.h + * + * Created on: Apr 16, 2012 + * Author: John Mangan + */ + +#ifndef LISTENER_H_ +#define LISTENER_H_ + +#include "Shouter.hpp" + +template +class Listener +{ + friend void + Shouter::Shout(Listener* ignoreListener); + + friend void + Shouter::ShoutAt(Listener* target); + +protected: + virtual void + Hear(T* shouter) = 0; +}; + +#endif /*LISTENER_H_*/ + diff --git a/include/cvrUtil/Shouter.hpp b/include/cvrUtil/Shouter.hpp new file mode 100644 index 00000000..36842a24 --- /dev/null +++ b/include/cvrUtil/Shouter.hpp @@ -0,0 +1,87 @@ +/* + * Shouter.h + * + * Created on: Apr 16, 2012 + * Author: John Mangan + */ + +#ifndef SHOUTER_H_ +#define SHOUTER_H_ + +#include +#include + +template +class Listener; + +template +class Shouter +{ +public: + typedef std::set< Listener* > Listeners; + + void AddListener(Listener* listener); + void RemoveListener(Listener* listener); + void Shout(Listener* ignoreListener = NULL); + void ShoutAt(Listener* target); + +protected: + virtual ~Shouter() {} + +private: + Listeners mToAdd; + Listeners mToRemove; + Listeners mListeners; +}; + +#include "Listener.h" + +template +void +Shouter::AddListener(Listener* listener) +{ + assert(listener != NULL); + mToRemove.erase(listener); + mToAdd.insert(listener); +} + +template +void +Shouter::RemoveListener(Listener* listener) +{ + assert(listener != NULL); + mToAdd.erase(listener); + mToRemove.insert(listener); +} + +template +void +Shouter::Shout(Listener* ignoreListener /*= NULL*/) +{ + typename Listeners::iterator current; + + // Update mListeners + // Note: Should be less overhead to iterate over mToRemove instead of using set_difference, assuming removals are rare + for (current = mToRemove.begin(); current != mToRemove.end(); ++current) + mListeners.erase( *current ); + mToRemove.clear(); + + mListeners.insert(mToAdd.begin(), mToAdd.end()); + mToAdd.clear(); + + // Iterate over and ShoutAt mListeners + for (current = mListeners.begin(); current != mListeners.end(); ++current) + if (*current != ignoreListener) + ShoutAt( *current ); +} + +template +void +Shouter::ShoutAt(Listener* target) +{ + assert(target != NULL); + target->Hear(static_cast(this)); +} + +#endif /*SHOUTER_H_*/ + diff --git a/src/cvrKernel/CMakeLists.txt b/src/cvrKernel/CMakeLists.txt index ef5e73df..ea221be7 100644 --- a/src/cvrKernel/CMakeLists.txt +++ b/src/cvrKernel/CMakeLists.txt @@ -8,22 +8,29 @@ ENDIF(WIN32) SET(LIB_NAME cvrKernel) SET(HEADER_PATH ${CalVR_SOURCE_DIR}/include/${LIB_NAME}) +SET(SCREEN_HEADER_PATH ${HEADER_PATH}/Screens) +SET(STATE_HEADER_PATH ${HEADER_PATH}/States) SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/CalVR.h ${HEADER_PATH}/ScreenConfig.h - ${HEADER_PATH}/ScreenBase.h - ${HEADER_PATH}/ScreenMono.h - ${HEADER_PATH}/ScreenStereo.h - ${HEADER_PATH}/ScreenInterlacedTopBottom.h - ${HEADER_PATH}/ScreenLenticular.h - ${HEADER_PATH}/ScreenMVShader.h - ${HEADER_PATH}/ScreenMVCullVisitor.h - ${HEADER_PATH}/ScreenMVMaster.h - ${HEADER_PATH}/ScreenMVSimulator.h - ${HEADER_PATH}/ScreenMVZones.h - ${HEADER_PATH}/ScreenFixedViewer.h - ${HEADER_PATH}/ScreenHMD.h - ${HEADER_PATH}/ScreenMVStencil.h + ${SCREEN_HEADER_PATH}/ScreenBase.h + ${SCREEN_HEADER_PATH}/ScreenMono.h + ${SCREEN_HEADER_PATH}/ScreenStereo.h + ${SCREEN_HEADER_PATH}/ScreenInterlacedTopBottom.h + ${SCREEN_HEADER_PATH}/ScreenLenticular.h + ${SCREEN_HEADER_PATH}/ScreenMVShader.h + ${SCREEN_HEADER_PATH}/ScreenMVCullVisitor.h + ${SCREEN_HEADER_PATH}/ScreenMVMaster.h + ${SCREEN_HEADER_PATH}/ScreenMVSimulator.h + ${SCREEN_HEADER_PATH}/ScreenMVZones.h + ${SCREEN_HEADER_PATH}/ScreenFixedViewer.h + ${SCREEN_HEADER_PATH}/ScreenHMD.h + ${SCREEN_HEADER_PATH}/ScreenMVStencil.h + ${HEADER_PATH}/StateManager.h + ${STATE_HEADER_PATH}/CvrState.h + ${STATE_HEADER_PATH}/CollaborationState.h + ${STATE_HEADER_PATH}/MetadataState.h + ${STATE_HEADER_PATH}/SpatialState.h ${HEADER_PATH}/ComController.h ${HEADER_PATH}/CVRViewer.h ${HEADER_PATH}/SceneManager.h @@ -40,6 +47,7 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/InteractionEvent.h ${HEADER_PATH}/CVRStatsHandler.h ${HEADER_PATH}/Export.h + ${HEADER_PATH}/DatabaseHandler.h ) SET(EXTRA_SOURCE) @@ -49,11 +57,11 @@ IF(WIN32) IF(GLEW_FOUND) SET(LIB_EXTERNAL_INCLUDES ${LIB_EXTERNAL_INCLUDES} ${GLEW_INCLUDE_DIR}) SET(LIB_EXTERNAL_LIBRARIES ${LIB_EXTERNAL_LIBRARIES} ${GLEW_LIBRARY}) - SET(EXTRA_SOURCE ${EXTRA_SOURCE} ScreenMVShader.cpp) + SET(EXTRA_SOURCE ${EXTRA_SOURCE} Screens/ScreenMVShader.cpp) ADD_DEFINITIONS(-DWITH_SCREEN_MULTI_VIEWER) ENDIF(GLEW_FOUND) ELSE(WIN32) - SET(EXTRA_SOURCE ${EXTRA_SOURCE} ScreenMVShader.cpp) + SET(EXTRA_SOURCE ${EXTRA_SOURCE} Screens/ScreenMVShader.cpp) ADD_DEFINITIONS(-DWITH_SCREEN_MULTI_VIEWER) ENDIF(WIN32) @@ -69,17 +77,22 @@ SET(LIB_SRC_FILES ${EXTRA_SOURCE} CalVR.cpp ScreenConfig.cpp - ScreenBase.cpp - ScreenMono.cpp - ScreenStereo.cpp - ScreenInterlacedTopBottom.cpp - ScreenMVCullVisitor.cpp - ScreenMVMaster.cpp - ScreenMVSimulator.cpp - ScreenMVZones.cpp - ScreenFixedViewer.cpp - ScreenHMD.cpp - ScreenMVStencil.cpp + Screens/ScreenBase.cpp + Screens/ScreenMono.cpp + Screens/ScreenStereo.cpp + Screens/ScreenInterlacedTopBottom.cpp + Screens/ScreenMVCullVisitor.cpp + Screens/ScreenMVMaster.cpp + Screens/ScreenMVSimulator.cpp + Screens/ScreenMVZones.cpp + Screens/ScreenFixedViewer.cpp + Screens/ScreenHMD.cpp + Screens/ScreenMVStencil.cpp + StateManager.cpp + States/CvrState.cpp + States/CollaborationState.cpp + States/MetadataState.cpp + States/SpatialState.cpp ComController.cpp CVRViewer.cpp SceneManager.cpp @@ -94,16 +107,19 @@ SET(LIB_SRC_FILES TiledWallSceneObject.cpp InteractionEvent.cpp CVRStatsHandler.cpp + DatabaseHandler.cpp ) SET(LIB_EXTERNAL_INCLUDES ${LIB_EXTERNAL_INCLUDES} ${MXML_INCLUDE_DIR} ${OSG_INCLUDE_DIR} + ${CDBAPP_INCLUDE_DIR} ) SET(LIB_EXTERNAL_LIBRARIES ${LIB_EXTERNAL_LIBRARIES} ${MXML_LIBRARY} ${OSG_LIBRARIES} + ${CDBAPP_LIBRARY} ) SET(LIB_INTERNAL_LIBRARIES diff --git a/src/cvrKernel/CVRViewer.cpp b/src/cvrKernel/CVRViewer.cpp index 439894fb..81ca819d 100644 --- a/src/cvrKernel/CVRViewer.cpp +++ b/src/cvrKernel/CVRViewer.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/cvrKernel/CalVR.cpp b/src/cvrKernel/CalVR.cpp index 6af62dab..acfb3869 100644 --- a/src/cvrKernel/CalVR.cpp +++ b/src/cvrKernel/CalVR.cpp @@ -8,12 +8,15 @@ #include #include #include +#include #include +#include #include #include #include #include #include +#include #include @@ -53,6 +56,7 @@ CalVR::CalVR() _file = NULL; _plugins = NULL; _threadedLoader = NULL; + _stateManager = NULL; _myPtr = this; } @@ -102,6 +106,10 @@ CalVR::~CalVR() { delete _tracking; } + if(_stateManager) + { + delete _stateManager; + } if(_communication) { delete _communication; @@ -190,6 +198,11 @@ bool CalVR::init(osg::ArgumentParser & args, std::string home) } } + _stateManager = StateManager::instance(); + + if (ConfigManager::getBool("CollaborationServer", false)) + _stateManager->Connect( ConfigManager::getEntry("value","CollaborationServer.Address","tcp://localhost:5570") ); + _tracking = cvr::TrackingManager::instance(); _tracking->init(); @@ -255,7 +268,13 @@ bool CalVR::init(osg::ArgumentParser & args, std::string home) for(int i = 0; i < fileList.size(); i++) { - cvr::FileHandler::instance()->loadFile(fileList[i]); + SceneObject* so = cvr::FileHandler::instance()->loadFile(fileList[i]); + + if (so) + { + PluginHelper::registerSceneObject(so,"CommandLine"); + so->attachToScene(); + } } return true; @@ -287,9 +306,11 @@ void CalVR::run() _screens->computeViewProj(); _screens->updateCamera(); _collaborative->update(); + _stateManager->UpdateLocalStates(); _threadedLoader->update(); _plugins->preFrame(); _viewer->updateTraversal(); + _stateManager->UpdateServerStates(); _viewer->renderingTraversals(); if(_communication->getIsSyncError()) diff --git a/src/cvrKernel/ComController.cpp b/src/cvrKernel/ComController.cpp index 3a9cdd38..3906885e 100644 --- a/src/cvrKernel/ComController.cpp +++ b/src/cvrKernel/ComController.cpp @@ -416,7 +416,7 @@ bool ComController::setupConnections() else { std::cerr << "Running Cleanup Script: " << cleanup << std::endl; - system(cleanup.c_str()); + int no_warning = system(cleanup.c_str()); _listenSocket = new MultiListenSocket(baseport,_numSlaves); if(!_listenSocket->setup()) { @@ -488,7 +488,7 @@ bool ComController::setupConnections() it != _startupMap.end(); it++) { std::cerr << it->second << std::endl; - system((it->second + " &").c_str()); + int no_warning = system((it->second + " &").c_str()); } bool ok = true; diff --git a/src/cvrKernel/DatabaseHandler.cpp b/src/cvrKernel/DatabaseHandler.cpp new file mode 100644 index 00000000..54dc41c3 --- /dev/null +++ b/src/cvrKernel/DatabaseHandler.cpp @@ -0,0 +1,62 @@ +/* + * DatabaseHandler.cpp + * + * Used to send and receive states between a collaboration server and the Statemanager. + * + * Created on: Apr 29, 2012 + * Author: John Mangan + * + * CalVR Port: Jul 16, 2013 + * Author: John Mangan + */ + +#include +#include + +using namespace cvr; + +bool +DatabaseHandler::LoadStateChanges(std::list< std::string >& loadedStates) +{ + uint64_t time_back; // To validate load + + // Load new/changed states + mDatabase.SendLoadMsg(mLastLoadTimestep, time_back, loadedStates); + + // time_back of 0 implies nothing loaded - sanity check to ensure time is continuous + if (time_back > mLastLoadTimestep) + { + mLastLoadTimestep = time_back; + return true; // database returned latest status + } + + return false; +} + +void +DatabaseHandler::Hear( CvrState* cvrState ) +{ + mHeardStates[ cvrState->Uuid() ] = cvrState->Write(); +} + +void +DatabaseHandler::SendHeardStates(void) +{ + // skip if we have nothing to do + if (mHeardStates.empty()) + return; + + // populate a list of string representations for database + std::list< std::string > states; + + std::map< std::string, std::string >::iterator it; + for (it = mHeardStates.begin(); it != mHeardStates.end(); ++it) + states.push_back( it->second ); + + // send string representations of states to the database + mDatabase.SendSaveMsg( states ); + + // clear to-be-sent map + mHeardStates.clear(); +} + diff --git a/src/cvrKernel/FileHandler.cpp b/src/cvrKernel/FileHandler.cpp index 49336c6e..9f5fa589 100644 --- a/src/cvrKernel/FileHandler.cpp +++ b/src/cvrKernel/FileHandler.cpp @@ -1,5 +1,11 @@ #include +#include +#include #include +#include +#include +#include +#include #include @@ -27,7 +33,86 @@ FileHandler * FileHandler::instance() return _myPtr; } -bool FileHandler::loadFile(std::string file) +SceneObject* FileHandler::loadFile(std::string file) +{ + SceneObject* sceneObject = loadFileDriver(file); + + if (sceneObject) + { + MetadataState* metadata = new MetadataState; + std::string meta_uuid = metadata->Uuid(); + metadata->Path(file); + //TODO: state->Volume(osg::Vec3) + sceneObject->addCvrState( metadata ); + SceneManager::instance()->_metadataToSceneObjects[ meta_uuid ] = sceneObject; + + SpatialState* spatial = sceneObject->getSpatialState(); + if (spatial) + spatial->Metadata( meta_uuid ); + + CollaborationState* collab = sceneObject->getCollaborationState(); + if (collab) + collab->Metadata( meta_uuid ); + + std::map< std::string, std::set< std::string > >::iterator mo + = SceneManager::instance()->_metaOrphans.find( meta_uuid ); + if (SceneManager::instance()->_metaOrphans.end() != mo) + { + std::set< std::string >::iterator oit; + for (oit = mo->second.begin(); mo->second.end() != oit; ++oit) + { + osg::ref_ptr< CvrState > orphan = StateManager::instance()->StateFromUuid( *oit ); + orphan->ShoutAt( sceneObject ); + } + + SceneManager::instance()->_metaOrphans.erase( mo ); + } + } + + return sceneObject; +} + +SceneObject* FileHandler::loadFile(MetadataState* metadata) +{ + SceneObject* sceneObject = loadFileDriver( metadata->Path() ); + + if (sceneObject) + { + std::string meta_uuid = metadata->Uuid(); + + osg::ref_ptr meta = metadata; // Hold a reference to avoid deletion + StateManager::instance()->Unregister(metadata); + + sceneObject->addCvrState( metadata ); + SceneManager::instance()->_metadataToSceneObjects[ meta_uuid ] = sceneObject; + + SpatialState* spatial = sceneObject->getSpatialState(); + if (spatial) + spatial->Metadata( meta_uuid ); + + CollaborationState* collab = sceneObject->getCollaborationState(); + if (collab) + collab->Metadata( meta_uuid ); + + std::map< std::string, std::set< std::string > >::iterator mo + = SceneManager::instance()->_metaOrphans.find( meta_uuid ); + if (SceneManager::instance()->_metaOrphans.end() != mo) + { + std::set< std::string >::iterator oit; + for (oit = mo->second.begin(); mo->second.end() != oit; ++oit) + { + osg::ref_ptr< CvrState > orphan = StateManager::instance()->StateFromUuid( *oit ); + orphan->ShoutAt( sceneObject ); + } + + SceneManager::instance()->_metaOrphans.erase( mo ); + } + } + + return sceneObject; +} + +SceneObject* FileHandler::loadFileDriver(std::string file) { std::string filext; // get file ext @@ -55,27 +140,29 @@ bool FileHandler::loadFile(std::string file) std::transform(filext.begin(),filext.end(),filext.begin(),::tolower); - if(_extMap.find(filext) != _extMap.end()) + SceneObject* sceneObject = NULL; + + std::map< std::string, FileLoadCallback* >::iterator emit = _extMap.find(filext); + if(_extMap.end() != emit) + sceneObject = emit->second->loadFile(file); + if (NULL == sceneObject) // if all else fails { - if(_extMap[filext]->loadFile(file)) + osg::ref_ptr < osg::Node > loadedModel = osgDB::readNodeFile(file); + + if(!loadedModel) { - return true; + std::cerr << "Unable to load file " << file << std::endl; + return NULL; } - } - // if all else fails - - osg::ref_ptr < osg::Node > loadedModel = osgDB::readNodeFile(file); - - if(loadedModel) - { - SceneManager::instance()->getObjectsRoot()->addChild(loadedModel); - return true; + sceneObject = new SceneObject(file, true, false, false, true, false); + sceneObject->addMoveMenuItem(); + sceneObject->addNavigationMenuItem(); + sceneObject->addChild( loadedModel ); + PluginHelper::registerSceneObject(sceneObject, "FileHandler-OSG"); } - std::cerr << "Unable to load file " << file << std::endl; - - return false; + return sceneObject; } void FileHandler::registerExt(std::string ext, FileLoadCallback * flc) diff --git a/src/cvrKernel/InteractionManager.cpp b/src/cvrKernel/InteractionManager.cpp index 64371c91..1b17c0db 100644 --- a/src/cvrKernel/InteractionManager.cpp +++ b/src/cvrKernel/InteractionManager.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/cvrKernel/SceneManager.cpp b/src/cvrKernel/SceneManager.cpp index b3956f98..9cde785a 100644 --- a/src/cvrKernel/SceneManager.cpp +++ b/src/cvrKernel/SceneManager.cpp @@ -9,6 +9,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -155,6 +160,11 @@ bool SceneManager::init() b = ConfigManager::getBool("HidePointer",false); setHidePointer(b); + StateManager::instance()->Register(this); + MetadataState::Register(); + SpatialState::Register(); // TODO: Find a better place to Register the SpatialState class. + CollaborationState::Register(); + return true; } @@ -1504,3 +1514,80 @@ void SceneManager::postDraw() _depthPartitionRight->removeNodesFromCameras(); } } + +void SceneManager::Hear(CvrState* cvrstate) +{ + std::string type = cvrstate->Type(); + std::string uuid = cvrstate->Uuid(); + + if (MetadataState::TYPE == type) + { + MetadataState* metadata = static_cast< MetadataState* >(cvrstate); + + std::map< std::string, SceneObject* >::iterator mo + = _metadataToSceneObjects.find( uuid ); + + // Invalid Metadata leads to SceneObject deletion + if (!metadata->Valid()) + { + if (mo != _metadataToSceneObjects.end()) + { + unregisterSceneObject(mo->second); + + if (mo->second) + delete mo->second; + + _metadataToSceneObjects.erase( mo ); + StateManager::instance()->Unregister( metadata ); + } + + return; + } + + // New Metadata leads to registration and sceneobject loading. + if (mo == _metadataToSceneObjects.end()) + { + StateManager::instance()->Register( metadata ); + SceneObject* so = FileHandler::instance()->loadFile( metadata ); + registerSceneObject(so,"HeardBySceneManager"); + return; + } + } + else if (CollaborationState::TYPE == type) + { + CollaborationState* collab = static_cast< CollaborationState* >(cvrstate); + + std::string meta_uuid = collab->Metadata(); + + if (_metadataToSceneObjects.end() != _metadataToSceneObjects.find (meta_uuid)) + return; + + std::map< std::string, std::set< std::string > >::iterator it + = _metaOrphans.find( meta_uuid ); + if (_metaOrphans.end() != it) + if (it->second.end() != it->second.find( uuid )) + return; + + StateManager::instance()->Register(collab); + _metaOrphans[ meta_uuid ].insert( uuid ); + } + else if (SpatialState::TYPE == type) + { + SpatialState* spatial = static_cast< SpatialState* >(cvrstate); + + std::string meta_uuid = spatial->Metadata(); + + if (_metadataToSceneObjects.end() != _metadataToSceneObjects.find (meta_uuid)) + return; + + std::map< std::string, std::set< std::string > >::iterator it + = _metaOrphans.find( meta_uuid ); + if (_metaOrphans.end() != it) + if (it->second.end() != it->second.find( uuid )) + return; + + StateManager::instance()->Register(spatial); + _metaOrphans[ meta_uuid ].insert( uuid ); + } +} + diff --git a/src/cvrKernel/SceneObject.cpp b/src/cvrKernel/SceneObject.cpp index 45b430c0..ad21e806 100644 --- a/src/cvrKernel/SceneObject.cpp +++ b/src/cvrKernel/SceneObject.cpp @@ -5,6 +5,11 @@ #include #include +#include +#include +#include +#include + #include #include #include @@ -15,7 +20,7 @@ using namespace cvr; SceneObject::SceneObject(std::string name, bool navigation, bool movable, bool clip, bool contextMenu, bool showBounds) : - _name(name), _navigation(navigation), _movable(movable), _clip(clip), _contextMenu( + _name(name), _movable(movable), _clip(clip), _contextMenu( contextMenu), _showBounds(showBounds) { _registered = false; @@ -42,6 +47,7 @@ SceneObject::SceneObject(std::string name, bool navigation, bool movable, _moveMenuItem = NULL; _navMenuItem = NULL; _scaleMenuItem = NULL; + _collabMenuItem = NULL; _root = new osg::MatrixTransform(); _clipRoot = new osg::ClipNode(); @@ -65,10 +71,24 @@ SceneObject::SceneObject(std::string name, bool navigation, bool movable, _menuButton = SceneManager::instance()->_menuDefaultOpenButton; _activeHand = -2; + + StateManager::instance()->Register(this); + setNavigationOn(navigation); // Will create & shout a SpatialState + CollaborationState* collab = getOrCreateCollaborationState(); + collab->Shout(); } SceneObject::~SceneObject() { + std::set< CvrState* > cvr_states; + std::map< std::string, std::set< CvrState* > >::iterator mit; + for (mit = _cvrStates.begin(); _cvrStates.end() != mit; ++mit) + cvr_states.insert(mit->second.begin(), mit->second.end()); + + std::set< CvrState* >::iterator sit; + for (sit = cvr_states.begin(); cvr_states.end() != sit; ++sit) + removeCvrState( *sit ); + if(_attached) { detachFromScene(); @@ -86,26 +106,32 @@ SceneObject::~SceneObject() if(_moveMenuItem) { - delete _moveMenuItem; - _moveMenuItem = NULL; + delete _moveMenuItem; + _moveMenuItem = NULL; } if(_navMenuItem) { - delete _navMenuItem; - _navMenuItem = NULL; + delete _navMenuItem; + _navMenuItem = NULL; } if(_scaleMenuItem) { - delete _scaleMenuItem; - _scaleMenuItem = NULL; + delete _scaleMenuItem; + _scaleMenuItem = NULL; + } + + if(_collabMenuItem) + { + delete _collabMenuItem; + _collabMenuItem = NULL; } if(_myMenu) { - delete _myMenu; - _myMenu = NULL; + delete _myMenu; + _myMenu = NULL; } } @@ -113,7 +139,7 @@ bool SceneObject::getNavigationOn() { if(!_parent) { - return _navigation; + return getOrCreateSpatialState()->Navigation(); } else { @@ -123,37 +149,16 @@ bool SceneObject::getNavigationOn() void SceneObject::setNavigationOn(bool nav) { - if(nav == _navigation) - { + if (_parent) return; - } - if(_attached) - { - if(nav) - { - SceneManager::instance()->getScene()->removeChild(_root); - SceneManager::instance()->getObjectsRoot()->addChild(_root); - _root->setMatrix( - _root->getMatrix() - * PluginHelper::getWorldToObjectTransform()); - } - else - { - SceneManager::instance()->getObjectsRoot()->removeChild(_root); - SceneManager::instance()->getScene()->addChild(_root); - _root->setMatrix( - _root->getMatrix() - * PluginHelper::getObjectToWorldTransform()); - } - splitMatrix(); - } + SpatialState* spatial = getOrCreateSpatialState(); - _navigation = nav; - if(_navMenuItem) - { - _navMenuItem->setValue(_navigation); - } + if (nav == spatial->Navigation()) + return; + + spatial->Navigation(nav); + spatial->Shout(); } void SceneObject::setMovable(bool mov) @@ -173,12 +178,50 @@ void SceneObject::setMovable(bool mov) } _movable = mov; + if(_moveMenuItem) { _moveMenuItem->setValue(_movable); } } +bool SceneObject::getCollaborate() +{ + if(!_parent) + { + return getOrCreateCollaborationState()->Collaboration(); + } + else + { + return _parent->getCollaborate(); + } +} + +void SceneObject::setCollaborate(bool collab) +{ + CollaborationState* collaboration = getOrCreateCollaborationState(); + + if (collaboration->Collaboration() == collab) + return; + + collaboration->Collaboration(collab); + + collaboration->Shout(); + + if (collab) + { + std::map< std::string, std::set< CvrState* > >::iterator mit; + std::set< CvrState* >::iterator sit; + for (mit = _cvrStates.begin(); _cvrStates.end() != mit; ++mit) + { + for (sit = mit->second.begin(); mit->second.end() != sit; ++sit) + { + (*sit)->Shout(); + } + } + } +} + void SceneObject::setClipOn(bool clip) { if(_clip == clip) @@ -228,24 +271,26 @@ void SceneObject::setShowBounds(bool bounds) osg::Vec3 SceneObject::getPosition() { - return _transMat.getTrans(); + return getOrCreateSpatialState()->Position(); } void SceneObject::setPosition(osg::Vec3 pos) { - _transMat.setTrans(pos); - updateMatrices(); + SpatialState* spatial = getOrCreateSpatialState(); + spatial->Position(pos); + spatial->Shout(); } osg::Quat SceneObject::getRotation() { - return _transMat.getRotate(); + return getOrCreateSpatialState()->Rotation(); } void SceneObject::setRotation(osg::Quat rot) { - _transMat.setRotate(rot); - updateMatrices(); + SpatialState* spatial = getOrCreateSpatialState(); + spatial->Rotation(rot); + spatial->Shout(); } osg::Matrix SceneObject::getTransform() @@ -261,17 +306,15 @@ void SceneObject::setTransform(osg::Matrix m) float SceneObject::getScale() { - return _scaleMat.getScale().x(); + return getOrCreateSpatialState()->Scale().x(); } void SceneObject::setScale(float scale) { - _scaleMat.makeScale(osg::Vec3(scale,scale,scale)); - updateMatrices(); - if(_scaleMenuItem) - { - _scaleMenuItem->setValue(scale); - } + SpatialState* spatial = getOrCreateSpatialState(); + spatial->Scale( osg::Vec3(scale,scale,scale) ); + + spatial->Shout(); } void SceneObject::attachToScene() @@ -295,7 +338,7 @@ void SceneObject::attachToScene() return; } - if(_navigation) + if(getNavigationOn()) { SceneManager::instance()->getObjectsRoot()->addChild(_root); } @@ -321,7 +364,7 @@ void SceneObject::detachFromScene() SceneManager::instance()->closeOpenObjectMenu(); } - if(_navigation) + if(getNavigationOn()) { SceneManager::instance()->getObjectsRoot()->removeChild(_root); } @@ -393,6 +436,14 @@ void SceneObject::addChild(SceneObject * so) _root->addChild(so->_root); } + std::set< CvrState* > child_spatials = so->getCvrStatesByType( SpatialState::TYPE ); + if (!child_spatials.empty()) + { + SpatialState* spatial = dynamic_cast< SpatialState* >( *child_spatials.begin() ); + if (NULL != spatial) + spatial->Parent( getOrCreateSpatialState()->Uuid() ); + } + so->_parent = this; _childrenObjects.push_back(so); so->updateMatrices(); @@ -414,7 +465,15 @@ void SceneObject::removeChild(SceneObject * so) { if((*it) == so) { - SceneManager::instance()->removeNestedObject(*it); + std::set< CvrState* > child_spatials = (*it)->getCvrStatesByType( SpatialState::TYPE ); + if (!child_spatials.empty()) + { + SpatialState* spatial = dynamic_cast< SpatialState* >( *child_spatials.begin() ); + if (NULL != spatial) + spatial->Parent(""); + } + + SceneManager::instance()->removeNestedObject(*it); (*it)->_parent = NULL; _childrenObjects.erase(it); break; @@ -487,10 +546,10 @@ void SceneObject::addNavigationMenuItem(std::string label) { if(!_navMenuItem) { - _navMenuItem = new MenuCheckbox(label,_navigation); + _navMenuItem = new MenuCheckbox(label,getNavigationOn()); _navMenuItem->setCallback(this); } - _navMenuItem->setValue(_navigation); + _navMenuItem->setValue(getNavigationOn()); _myMenu->removeMenuItem(_navMenuItem); _myMenu->addMenuItem(_navMenuItem); } @@ -504,6 +563,27 @@ void SceneObject::removeNavigationMenuItem() } } +void SceneObject::addCollaborateMenuItem(std::string label) +{ + if (_myMenu) + { + if (!_collabMenuItem) + { + _collabMenuItem = new MenuCheckbox(label,getCollaborate()); + _collabMenuItem->setCallback(this); + } + _collabMenuItem->setValue(getCollaborate()); + _myMenu->removeMenuItem(_collabMenuItem); + _myMenu->addMenuItem(_collabMenuItem); + } +} + +void SceneObject::removeCollaborateMenuItem() +{ + if (_myMenu && _collabMenuItem) + _myMenu->removeMenuItem(_collabMenuItem); +} + void SceneObject::addScaleMenuItem(std::string label, float min, float max, float value) { @@ -671,11 +751,11 @@ bool SceneObject::processEvent(InteractionEvent * ie) osg::Matrix menuRot; - // point towards viewer if not on tiled wall - if(!ie->asPointerEvent()) - { - menuRot.makeRotate(osg::Vec3(0,-1,0),viewerDir); - } + // point towards viewer if not on tiled wall + if(!ie->asPointerEvent()) + { + menuRot.makeRotate(osg::Vec3(0,-1,0),viewerDir); + } osg::Matrix m; m.makeTranslate(menuPoint); @@ -733,17 +813,15 @@ void SceneObject::menuCallback(MenuItem * item) { if(item == _moveMenuItem) { - if(_moveMenuItem->getValue() != _movable) - { - setMovable(_moveMenuItem->getValue()); - } + setMovable(_moveMenuItem->getValue()); } else if(item == _navMenuItem) { - if(_navMenuItem->getValue() != _navigation) - { - setNavigationOn(_navMenuItem->getValue()); - } + setNavigationOn(_navMenuItem->getValue()); + } + else if(item == _collabMenuItem) + { + setCollaborate(_collabMenuItem->getValue()); } else if(item == _scaleMenuItem) { @@ -834,6 +912,9 @@ void SceneObject::setRegistered(bool reg) detachFromScene(); } _registered = reg; + + //TODO: clean up this hack of reshouting + getOrCreateSpatialState()->ShoutAt(this); } void SceneObject::processMove(osg::Matrix & mat) @@ -1230,7 +1311,18 @@ void SceneObject::updateBoundsGeometry() void SceneObject::updateMatrices() { - _root->setMatrix(_scaleMat * _transMat); + osg::Matrix scale_mat, trans_mat; + + float scale = getScale(); + scale_mat.makeScale( osg::Vec3(scale,scale,scale) ); + + if(_scaleMenuItem) + _scaleMenuItem->setValue(scale); + + trans_mat = osg::Matrix::rotate( getRotation() ) * + osg::Matrix::translate( getPosition() ); + + _root->setMatrix(scale_mat * trans_mat); _invTransform = osg::Matrix::inverse(_root->getMatrix()); if(!_parent) @@ -1258,10 +1350,12 @@ void SceneObject::splitMatrix() _root->getMatrix().decompose(trans,rot,scale,so); - _transMat = osg::Matrix::rotate(rot) * osg::Matrix::translate(trans); - _scaleMat = osg::Matrix::scale(scale); + SpatialState* spatial = getOrCreateSpatialState(); + spatial->Position(trans); + spatial->Scale(scale); + spatial->Rotation(rot); - updateMatrices(); + spatial->Shout(); } void SceneObject::interactionCountInc() @@ -1283,3 +1377,203 @@ void SceneObject::interactionCountDec() _boundsTransform->addChild(_boundsGeode); } } + +void SceneObject::addCvrState( CvrState* const state ) +{ + _cvrStates[ state->Type() ].insert( state ); + StateManager::instance()->Register(state); + state->AddListener(this); +} + +void SceneObject::removeCvrState( CvrState* const state ) +{ + std::map< std::string, std::set< CvrState* > >::iterator it; + it = _cvrStates.find( state->Type() ); + + if (_cvrStates.end() != it) + it->second.erase( state ); +} + +std::set< CvrState* > SceneObject::getCvrStatesByType( std::string type ) +{ + std::map< std::string, std::set< CvrState* > >::iterator it; + it = _cvrStates.find( type ); + + if (_cvrStates.end() == it) + return std::set< CvrState* >(); + + return it->second; +} + +void SceneObject::Hear(CvrState* cvrstate) +{ + std::string type = cvrstate->Type(); + + if (SpatialState::TYPE == type) + { + SpatialState* spatial = static_cast(cvrstate); + MetadataState* metadata = getMetadataState(); + SpatialState* my_spatial = getOrCreateSpatialState(); + + if (my_spatial->Uuid() != spatial->Uuid() + && (!metadata || metadata->Uuid() != spatial->Metadata())) + return; + + if (_registered) + { + if (spatial->Valid()) + attachToScene(); + else + detachFromScene(); + } + + // Caution: Handle Navigation specially: checkAndUpdate will put the + // root in the correct scenegraph. Then, update all the variables of + // the spatial state. Finally, update the matrices. + my_spatial->Navigation( spatial->Navigation() ); + checkAndUpdateNavigation(); + + if (my_spatial->Navigation()) + my_spatial->Variables( spatial->Variables() ); + updateMatrices(); + } + else if (CollaborationState::TYPE == type) + { + CollaborationState* collab = static_cast(cvrstate); + CollaborationState* my_collab = getOrCreateCollaborationState(); + MetadataState* metadata = getMetadataState(); + + if (my_collab->Uuid() != collab->Uuid() + && (!metadata || metadata->Uuid() != collab->Metadata())) + return; + + my_collab->Variables( collab->Variables() ); + checkAndUpdateCollaboration(); + } +} + +MetadataState* SceneObject::getMetadataState(void) +{ + std::set< CvrState* > metadata = getCvrStatesByType( MetadataState::TYPE ); + + if (!metadata.empty()) + return dynamic_cast< MetadataState* >( *metadata.begin() ); + return NULL; +} + +SpatialState* SceneObject::getSpatialState(void) +{ + std::set< CvrState* > spatial = getCvrStatesByType( SpatialState::TYPE ); + + if (!spatial.empty()) + return dynamic_cast< SpatialState* >( *spatial.begin() ); + return NULL; +} + +CollaborationState* SceneObject::getCollaborationState(void) +{ + std::set< CvrState* > collaboration = getCvrStatesByType( CollaborationState::TYPE ); + + if (!collaboration.empty()) + return dynamic_cast< CollaborationState* >( *collaboration.begin() ); + return NULL; +} + +SpatialState* SceneObject::getOrCreateSpatialState(void) +{ + SpatialState* spatial = getSpatialState(); + + if (spatial) + return spatial; + + spatial = new SpatialState(); + addCvrState(spatial); + + setTransform(osg::Matrix::identity()); + + return spatial; +} + +CollaborationState* SceneObject::getOrCreateCollaborationState(void) +{ + CollaborationState* collab = getCollaborationState(); + + if (collab) + return collab; + + collab = new CollaborationState(); + addCvrState(collab); + + // TODO: set default collaboration state + + return collab; +} + +void SceneObject::checkAndUpdateNavigation() +{ + if (!_attached) + return; + + if (_parent) + return; + + bool nav = getNavigationOn(); + + // Expectation: nav == true IFF _root is a under getObjectsRoot + // (nav EQUALS _root under getScene) IMPLIES inconsistency + bool under_scene = SceneManager::instance()->getScene()->getChildIndex(_root) != SceneManager::instance()->getScene()->getNumChildren(); + + if (nav != under_scene) + return; + + if(nav) + { + SceneManager::instance()->getScene()->removeChild(_root); + SceneManager::instance()->getObjectsRoot()->addChild(_root); + _root->setMatrix( + _root->getMatrix() + * PluginHelper::getWorldToObjectTransform()); + } + else + { + SceneManager::instance()->getObjectsRoot()->removeChild(_root); + SceneManager::instance()->getScene()->addChild(_root); + _root->setMatrix( + _root->getMatrix() + * PluginHelper::getObjectToWorldTransform()); + } + + if(_navMenuItem) + _navMenuItem->setValue(nav); + + splitMatrix(); +} + +void SceneObject::checkAndUpdateCollaboration() +{ + bool collab = getCollaborate(); + + if (_collabMenuItem && _collaborated == collab) + return; + + _collaborated = collab; + + std::map< std::string, std::set< CvrState* > >::iterator mit; + std::set< CvrState* >::iterator sit; + for (mit = _cvrStates.begin(); _cvrStates.end() != mit; ++mit) + { + for (sit = mit->second.begin(); mit->second.end() != sit; ++sit) + { + StateManager::instance()->CollaborateState((*sit)->Uuid(), collab); + } + } + + if (getOrCreateCollaborationState()->Valid()) + addCollaborateMenuItem(); + else + removeCollaborateMenuItem(); + + if (_collabMenuItem) + _collabMenuItem->setValue(collab); +} + diff --git a/src/cvrKernel/ScreenConfig.cpp b/src/cvrKernel/ScreenConfig.cpp index 9094086e..fa09e94f 100644 --- a/src/cvrKernel/ScreenConfig.cpp +++ b/src/cvrKernel/ScreenConfig.cpp @@ -1,13 +1,13 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -22,7 +22,7 @@ #include #ifdef WITH_INTERLEAVER -#include +#include #endif #ifdef WIN32 diff --git a/src/cvrKernel/ScreenBase.cpp b/src/cvrKernel/Screens/ScreenBase.cpp similarity index 99% rename from src/cvrKernel/ScreenBase.cpp rename to src/cvrKernel/Screens/ScreenBase.cpp index 8cb7e6db..fdb11dcf 100644 --- a/src/cvrKernel/ScreenBase.cpp +++ b/src/cvrKernel/Screens/ScreenBase.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/cvrKernel/ScreenFixedViewer.cpp b/src/cvrKernel/Screens/ScreenFixedViewer.cpp similarity index 96% rename from src/cvrKernel/ScreenFixedViewer.cpp rename to src/cvrKernel/Screens/ScreenFixedViewer.cpp index 87801fb3..56f3acaf 100644 --- a/src/cvrKernel/ScreenFixedViewer.cpp +++ b/src/cvrKernel/Screens/ScreenFixedViewer.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/cvrKernel/ScreenHMD.cpp b/src/cvrKernel/Screens/ScreenHMD.cpp similarity index 99% rename from src/cvrKernel/ScreenHMD.cpp rename to src/cvrKernel/Screens/ScreenHMD.cpp index 3d075bbd..22fd8761 100644 --- a/src/cvrKernel/ScreenHMD.cpp +++ b/src/cvrKernel/Screens/ScreenHMD.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/cvrKernel/ScreenInterlacedTopBottom.cpp b/src/cvrKernel/Screens/ScreenInterlacedTopBottom.cpp similarity index 99% rename from src/cvrKernel/ScreenInterlacedTopBottom.cpp rename to src/cvrKernel/Screens/ScreenInterlacedTopBottom.cpp index ac7d9304..64941888 100644 --- a/src/cvrKernel/ScreenInterlacedTopBottom.cpp +++ b/src/cvrKernel/Screens/ScreenInterlacedTopBottom.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/src/cvrKernel/ScreenLenticular.cpp b/src/cvrKernel/Screens/ScreenLenticular.cpp similarity index 99% rename from src/cvrKernel/ScreenLenticular.cpp rename to src/cvrKernel/Screens/ScreenLenticular.cpp index decc0256..75d99316 100644 --- a/src/cvrKernel/ScreenLenticular.cpp +++ b/src/cvrKernel/Screens/ScreenLenticular.cpp @@ -1,6 +1,6 @@ #ifdef WITH_INTERLEAVER -#include +#include #include #include #include diff --git a/src/cvrKernel/ScreenMVCullVisitor.cpp b/src/cvrKernel/Screens/ScreenMVCullVisitor.cpp similarity index 99% rename from src/cvrKernel/ScreenMVCullVisitor.cpp rename to src/cvrKernel/Screens/ScreenMVCullVisitor.cpp index 42f36449..c71e21b1 100644 --- a/src/cvrKernel/ScreenMVCullVisitor.cpp +++ b/src/cvrKernel/Screens/ScreenMVCullVisitor.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/cvrKernel/ScreenMVMaster.cpp b/src/cvrKernel/Screens/ScreenMVMaster.cpp similarity index 98% rename from src/cvrKernel/ScreenMVMaster.cpp rename to src/cvrKernel/Screens/ScreenMVMaster.cpp index aab5d02f..c702925a 100644 --- a/src/cvrKernel/ScreenMVMaster.cpp +++ b/src/cvrKernel/Screens/ScreenMVMaster.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include diff --git a/src/cvrKernel/ScreenMVShader.cpp b/src/cvrKernel/Screens/ScreenMVShader.cpp similarity index 99% rename from src/cvrKernel/ScreenMVShader.cpp rename to src/cvrKernel/Screens/ScreenMVShader.cpp index 97a4d44f..e06372f5 100644 --- a/src/cvrKernel/ScreenMVShader.cpp +++ b/src/cvrKernel/Screens/ScreenMVShader.cpp @@ -4,10 +4,10 @@ #pragma comment(lib, "Opengl32.lib") #endif -#include +#include #include #include -#include +#include #include #include diff --git a/src/cvrKernel/ScreenMVSimulator.cpp b/src/cvrKernel/Screens/ScreenMVSimulator.cpp similarity index 96% rename from src/cvrKernel/ScreenMVSimulator.cpp rename to src/cvrKernel/Screens/ScreenMVSimulator.cpp index 13a64c68..4f223667 100644 --- a/src/cvrKernel/ScreenMVSimulator.cpp +++ b/src/cvrKernel/Screens/ScreenMVSimulator.cpp @@ -1,4 +1,4 @@ -#include +#include using namespace cvr; diff --git a/src/cvrKernel/ScreenMVStencil.cpp b/src/cvrKernel/Screens/ScreenMVStencil.cpp similarity index 99% rename from src/cvrKernel/ScreenMVStencil.cpp rename to src/cvrKernel/Screens/ScreenMVStencil.cpp index 2da432b6..9ba0ffc4 100644 --- a/src/cvrKernel/ScreenMVStencil.cpp +++ b/src/cvrKernel/Screens/ScreenMVStencil.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/cvrKernel/ScreenMVZones.cpp b/src/cvrKernel/Screens/ScreenMVZones.cpp similarity index 99% rename from src/cvrKernel/ScreenMVZones.cpp rename to src/cvrKernel/Screens/ScreenMVZones.cpp index 6875b2e3..37624fe2 100644 --- a/src/cvrKernel/ScreenMVZones.cpp +++ b/src/cvrKernel/Screens/ScreenMVZones.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/cvrKernel/ScreenMVZones.txt b/src/cvrKernel/Screens/ScreenMVZones.txt similarity index 100% rename from src/cvrKernel/ScreenMVZones.txt rename to src/cvrKernel/Screens/ScreenMVZones.txt diff --git a/src/cvrKernel/ScreenMono.cpp b/src/cvrKernel/Screens/ScreenMono.cpp similarity index 97% rename from src/cvrKernel/ScreenMono.cpp rename to src/cvrKernel/Screens/ScreenMono.cpp index 87aa9de5..ec23777e 100644 --- a/src/cvrKernel/ScreenMono.cpp +++ b/src/cvrKernel/Screens/ScreenMono.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/cvrKernel/ScreenStereo.cpp b/src/cvrKernel/Screens/ScreenStereo.cpp similarity index 98% rename from src/cvrKernel/ScreenStereo.cpp rename to src/cvrKernel/Screens/ScreenStereo.cpp index 86abb83e..0a5d6602 100644 --- a/src/cvrKernel/ScreenStereo.cpp +++ b/src/cvrKernel/Screens/ScreenStereo.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/cvrKernel/StateManager.cpp b/src/cvrKernel/StateManager.cpp new file mode 100644 index 00000000..f9126cf8 --- /dev/null +++ b/src/cvrKernel/StateManager.cpp @@ -0,0 +1,259 @@ +/* + * StateManager.cpp + * + * Used to send and receive states between the DatabaseHandler and CalVR. + * + * Created on: Apr 29, 2012 + * Author: John Mangan + * + * CalVR Port: Jul 15, 2013 + * Author: John Mangan + */ + +#include +#include + +#include + +#include +#include +#include + +using namespace cvr; + +/*static*/ StateManager* StateManager::mInstance = NULL; + +/*static*/ StateManager* +StateManager::instance(void) +{ + if (NULL == mInstance) + mInstance = new StateManager; + + return mInstance; +} + +StateManager::StateManager() +{ + mNotConnected = true; +} + +StateManager::~StateManager() +{ + Disconnect(); + mStates.clear(); // will unref automatically +} + +void +StateManager::AlertListeners(CvrState* cvrstate) +{ + assert(cvrstate != NULL); + osg::ref_ptr< CvrState > safety = cvrstate; // So that Listeners do not delete accidently + + // alert all registered listeners -- store iterators prior to iterating to avoid corrupted iterating + Shouter::Listeners::iterator begin = mListeners.begin(), + end = mListeners.end(), current; + + for (current = begin; current != end; ++current) + cvrstate->ShoutAt(*current); +} + +void +StateManager::CollaborateState(std::string const& uuid, bool const collaborate) +{ + if (!cvr::ComController::instance()->isMaster()) + return; + + CvrState* state = StateFromUuid(uuid); + + if (!state) + { + std::cerr << "StateManager::CollaborateState(-) received an unregistered CvrState uuid. (ignoring)" << std::endl; + return; + } + + if (collaborate) + state->AddListener(&mDatabaseHandler); + else + state->RemoveListener(&mDatabaseHandler); +} + +void +StateManager::Connect(std::string const& connectionAddress) +{ + mNotConnected = false; + + if (cvr::ComController::instance()->isMaster()) + mDatabaseHandler.Connect( connectionAddress ); +} + +void +StateManager::Disconnect(void) +{ + mNotConnected = true; + + if (cvr::ComController::instance()->isMaster()) + mDatabaseHandler.Disconnect(); +} + +void +StateManager::Hear(CvrState* cvrstate) +{ + // At this point, expect StateManager to already know about the state + CvrState* registered = StateFromUuid( cvrstate->Uuid() ); + + if (!registered) + return; + + if (registered != cvrstate) // Optimization via pointer comparison + registered->Variables( cvrstate->Variables() ); +} + +void +StateManager::Register(Listener* listener) +{ + if (!listener) + { + std::cerr << "StateManager::Register(Listener*) passed NULL parameter. (ignoring)" << std::endl; + return; + } + + mListeners.insert(listener); +} + +void +StateManager::Register(CvrState* cvrstate) +{ + if (!cvrstate) + { + std::cerr << "StateManager::Register(CvrState*) passed NULL parameter. (ignoring)" << std::endl; + return; + } + + // Validate that the CvrState is currently unregistered + if (StateFromUuid( cvrstate->Uuid() )) + { + std::cerr << "StateManager::Register(CvrState*) received a non-new CvrState. (ignoring)" << std::endl; + return; + } + + mStates[cvrstate->Uuid()] = cvrstate; + cvrstate->AddListener(this); +} + +CvrState* +StateManager::StateFromUuid(std::string const& uuid) const +{ + CvrStateMap::const_iterator it = mStates.find( uuid ); + if (it != mStates.end()) + return it->second; + + return NULL; +} + +void +StateManager::Unregister(Listener* listener) +{ + if (!listener) + { + std::cerr << "StateManager::Unregister(Listener*) received a NULL listener*. (ignoring)" << std::endl; + return; + } + + mListeners.erase(listener); +} + + +void +StateManager::Unregister(CvrState* cvrstate) +{ + if (!cvrstate) + { + std::cerr << "StateManager::Unregister(CvrState*) received a NULL CvrState*. (ignoring)" << std::endl; + return; + } + + std::string uuid = cvrstate->Uuid(); + + osg::ref_ptr registered = StateFromUuid(uuid); + if (!registered) + { + std::cerr << "StateManager::Unregister(CvrState*) received an unregistered CvrState. (ignoring)" << std::endl; + return; + } + + mStates.erase(uuid); +} + +void +StateManager::UpdateLocalStates(void) +{ + if (mNotConnected) + return; + + std::list< std::string > returned_states; + + LoadStateChanges(returned_states); + + std::list< std::string >::iterator it; + for (it = returned_states.begin(); it != returned_states.end(); ++it) + { + cdb::State state = cdb::State::Read( *it ); + osg::ref_ptr cvrstate = CvrState::AdaptToDerivedCvrState( state ); + + if (cvrstate) + { + cvrstate->ShoutAt(this); + AlertListeners(cvrstate); + } + } +} + +void +StateManager::UpdateServerStates(void) +{ + if (mNotConnected) + return; + + if (cvr::ComController::instance()->isMaster()) + mDatabaseHandler.SendHeardStates(); +} + +/**** BEGIN PROTECTED FUNCTIONS ****/ + + +void +StateManager::LoadStateChanges(std::list< std::string >& returnedStates) +{ + std::string json_array_of_states = ""; + int file_size = 0; + char *cArray; + + if (cvr::ComController::instance()->isMaster()) + { + mDatabaseHandler.LoadStateChanges( returnedStates ); + cdb::State::ConvertStringsToJsonStateArray( returnedStates, json_array_of_states ); + file_size = json_array_of_states.length(); + + cvr::ComController::instance()->sendSlaves(&file_size, sizeof(file_size)); + + if (file_size > 0) + { + cvr::ComController::instance()->sendSlaves((void*)json_array_of_states.c_str(), sizeof(char)*file_size); + } + } + else // Slave Node + { + cvr::ComController::instance()->readMaster(&file_size, sizeof(file_size)); + if (file_size > 0) + { + cArray = new char[file_size]; + cvr::ComController::instance()->readMaster(cArray, sizeof(char)*file_size); + json_array_of_states = cArray; + delete[] cArray; + + cdb::State::ConvertJsonStateArrayToStrings(json_array_of_states, returnedStates); + } + } +} + + diff --git a/src/cvrKernel/States/CollaborationState.cpp b/src/cvrKernel/States/CollaborationState.cpp new file mode 100644 index 00000000..2f040794 --- /dev/null +++ b/src/cvrKernel/States/CollaborationState.cpp @@ -0,0 +1,73 @@ +/* + * CollaborationState.cpp + * + */ + +#include + +using namespace cvr; + +/*static*/ std::string const CollaborationState::TYPE = "collaboration"; + +CollaborationState::CollaborationState() : CvrState(TYPE) +{ + Collaboration(false); + Metadata(""); +} + +/*static*/ CvrState* +CollaborationState::Adapter( State const& state ) +{ + return new CollaborationState( state ); +} + +/*static*/ void +CollaborationState::Register(void) +{ + static bool FIRST_ONE = true; + if (FIRST_ONE) + { + FIRST_ONE = false; + CvrState::Register(TYPE, &Adapter); + } +} + +bool const +CollaborationState::Collaboration(void) +{ + bool collaboration; + GetVariable("collaboration", collaboration); + + return collaboration; +} + +void +CollaborationState::Collaboration(bool const collaboration) +{ + SetVariable("collaboration", collaboration); +} + +std::string const +CollaborationState::Metadata(void) +{ + std::string meta_uuid; + GetVariable("metadata", meta_uuid); + + return meta_uuid; +} + +void +CollaborationState::Metadata(std::string const& metadata) +{ + SetVariable("metadata", metadata); +} + +// PROTECTED FUNCTIONS + +CollaborationState::CollaborationState(State const& state) : CvrState(state) +{} + +/*virtual*/ +CollaborationState::~CollaborationState() +{} + diff --git a/src/cvrKernel/States/CvrState.cpp b/src/cvrKernel/States/CvrState.cpp new file mode 100644 index 00000000..5a420bb6 --- /dev/null +++ b/src/cvrKernel/States/CvrState.cpp @@ -0,0 +1,93 @@ +/* + * CvrState.cpp + * + */ + +#include +#include +#include + +using namespace cvr; + +// static member fields +/*static*/ CvrState::TypeAdapterMap CvrState::mTypeAdapters; + +/*static*/ CvrState* +CvrState::AdaptToDerivedCvrState(State& state) +{ + std::string type; + if (State::NO_ERROR != state.GetVariable("type", type)) + { + std::cerr << "CvrState::AdaptToDerivedCvrState passed a State without" + << " a type variable." << std::endl; + return NULL; + } + + TypeAdapterMap::iterator tamit = mTypeAdapters.find(type); + if (mTypeAdapters.end() == tamit) + { + std::cerr << "CvrState::AdaptToDerivedState passed a State with unknown" + << " type \'" << type << "\'." << std::endl; + return NULL; + } + + return tamit->second(state); +} + +std::string const +CvrState::Type() +{ + std::string type; + State::ErrorType error = GetVariable("type", type); + assert( State::NO_ERROR == error ); + + return type; +} + +bool const +CvrState::Valid() +{ + bool valid; + State::ErrorType error = GetVariable("valid",valid); + assert( State::NO_ERROR == error ); + + return valid; +} + +void +CvrState::Valid(bool const valid) +{ + SetVariable("valid", valid); +} + +/////// BEING PROTECTED FUNCTIONS ////////// + +CvrState::CvrState(std::string const& type) +{ + SetVariable("type", type); + Valid(true); +} + +CvrState::CvrState(State const& state) : State(state.Variables(), state.Uuid()) +{} + +/*static*/ void +CvrState::Register(std::string const& type, STATIC_ADAPTER staticAdapter) +{ + TypeAdapterMap::iterator tamit = mTypeAdapters.find(type); + if (mTypeAdapters.end() == tamit) + { + std::pair< std::string, STATIC_ADAPTER > adapter(type, staticAdapter); + mTypeAdapters.insert(tamit, adapter ); + } + else if (tamit->second != staticAdapter) + { + std::cerr << "Warning: Differing Adapter functions provided for derived" + << " CvrState of type \'" << type << "\'." << std::endl; + } +} + +/*virtual*/ +CvrState::~CvrState() +{} + diff --git a/src/cvrKernel/States/MetadataState.cpp b/src/cvrKernel/States/MetadataState.cpp new file mode 100644 index 00000000..975be5cf --- /dev/null +++ b/src/cvrKernel/States/MetadataState.cpp @@ -0,0 +1,84 @@ +/* + * MetadataState.cpp + * + */ + +#include +#include +#include + +using namespace cvr; + +std::string const MetadataState::TYPE = "metadata"; + +MetadataState::MetadataState() : CvrState(TYPE) +{ + osg::Vec3 default_vec; + + Volume(default_vec); + Path(""); + + Register(); +} + +/*static*/ CvrState* +MetadataState::Adapter(State const& state) +{ + return new MetadataState(state); +} + +/*static*/ void +MetadataState::Register(void) +{ + static bool FIRST_ONE = true; + if (FIRST_ONE) + { + FIRST_ONE = false; + CvrState::Register(TYPE, &Adapter); + } +} + +std::string const +MetadataState::Path(void) +{ + std::string path; + GetVariable("path", path); + + return path; +} + +void +MetadataState::Path(std::string const& path) +{ + SetVariable("path", path); +} + +osg::Vec3 const +MetadataState::Volume(void) +{ + std::vector volume; + GetVariable("volume", volume); + + return osg::Vec3(volume[0], volume[1], volume[2]); +} + +void +MetadataState::Volume(osg::Vec3 const& volume) +{ + std::vector vec3; + vec3.push_back(volume.x()); + vec3.push_back(volume.y()); + vec3.push_back(volume.z()); + SetVariable("volume", vec3); +} + +// PROTECTED FUNCTIONS + +MetadataState::MetadataState(State const& state) : CvrState(state) +{ +} + +/*virtual*/ +MetadataState::~MetadataState() +{} + diff --git a/src/cvrKernel/States/SpatialState.cpp b/src/cvrKernel/States/SpatialState.cpp new file mode 100644 index 00000000..326f4242 --- /dev/null +++ b/src/cvrKernel/States/SpatialState.cpp @@ -0,0 +1,159 @@ +/* + * SpatialState.cpp + * + */ + +#include +#include + +using namespace cvr; + +/*static*/ std::string const SpatialState::TYPE = "spatial"; + +SpatialState::SpatialState() : CvrState(TYPE) +{ + osg::Vec3 default_vec3; + osg::Quat default_vec4; + + Position(default_vec3); + Scale(default_vec3); + Rotation(default_vec4); + + Navigation(false); + + Metadata(""); + Parent(""); +} + +/*static*/ CvrState* +SpatialState::Adapter( State const& state ) +{ + return new SpatialState( state ); +} + +/*static*/ void +SpatialState::Register(void) +{ + static bool FIRST_ONE = true; + if (FIRST_ONE) + { + FIRST_ONE = false; + CvrState::Register(TYPE, &Adapter); + } +} + +osg::Vec3 const +SpatialState::Position(void) +{ + std::vector pos; + GetVariable("position", pos); + + return osg::Vec3(pos[0], pos[1], pos[2]); +} + +void +SpatialState::Position(osg::Vec3 const& position) +{ + std::vector vec3; + vec3.push_back(position.x()); + vec3.push_back(position.y()); + vec3.push_back(position.z()); + + SetVariable("position", vec3); +} + +osg::Quat const +SpatialState::Rotation(void) +{ + std::vector vec4; + GetVariable("rotation", vec4); + + return osg::Quat( osg::Vec4d(vec4[0], vec4[1], vec4[2], vec4[3]) ); +} + +void +SpatialState::Rotation(osg::Quat const& rotation) +{ + std::vector vec4; + vec4.push_back(rotation.x()); + vec4.push_back(rotation.y()); + vec4.push_back(rotation.z()); + vec4.push_back(rotation.w()); + + SetVariable("rotation", vec4); +} + +osg::Vec3 const +SpatialState::Scale(void) +{ + std::vector scale; + GetVariable("scale", scale); + + return osg::Vec3(scale[0], scale[1], scale[2]); +} + +void +SpatialState::Scale(osg::Vec3 const& scale) +{ + std::vector vec3; + vec3.push_back(scale.x()); + vec3.push_back(scale.y()); + vec3.push_back(scale.z()); + + SetVariable("scale", vec3); +} + +bool const +SpatialState::Navigation(void) +{ + bool navigation; + GetVariable("navigation", navigation); + + return navigation; +} + +void +SpatialState::Navigation(bool const navigation) +{ + SetVariable("navigation", navigation); +} + +std::string const +SpatialState::Metadata(void) +{ + std::string meta_uuid; + GetVariable("metadata", meta_uuid); + + return meta_uuid; +} + +void +SpatialState::Metadata(std::string const& metadata) +{ + SetVariable("metadata", metadata); +} + +std::string const +SpatialState::Parent(void) +{ + std::string parent_uuid; + GetVariable("parent", parent_uuid); + + return parent_uuid; +} + +void +SpatialState::Parent(std::string const& spatial) +{ + SetVariable("parent", spatial); +} + +// PROTECTED FUNCTIONS + +SpatialState::SpatialState(State const& state) : CvrState(state) +{} + +/*virtual*/ +SpatialState::~SpatialState() +{} + diff --git a/src/cvrKernel/ThreadedLoader.cpp b/src/cvrKernel/ThreadedLoader.cpp index 0807b60e..afbb238d 100644 --- a/src/cvrKernel/ThreadedLoader.cpp +++ b/src/cvrKernel/ThreadedLoader.cpp @@ -591,7 +591,7 @@ void ThreadedLoader::LoaderThread::run() { if(_job->strs.size()) { - system(_job->strs[0].c_str()); + int no_warning = system(_job->strs[0].c_str()); } break; } @@ -601,7 +601,7 @@ void ThreadedLoader::LoaderThread::run() { if(_job->strs.size()) { - system(_job->strs[0].c_str()); + int no_warning = system(_job->strs[0].c_str()); } } break;