2020-05-01 19:37:01 +00:00
# ifndef OPENXR_MENU_HPP
# define OPENXR_MENU_HPP
# include <map>
# include <set>
# include <regex>
2020-05-12 20:13:01 +00:00
# include <MyGUI_Widget.h>
2020-05-01 19:37:01 +00:00
# include <osg/Geometry>
# include <osg/TexMat>
# include <osg/Texture2D>
# include <osg/Camera>
# include <osg/PositionAttitudeTransform>
2020-05-24 16:00:42 +00:00
# include "vrview.hpp"
# include "openxrmanager.hpp"
2020-05-01 19:37:01 +00:00
namespace MyGUI
{
class Widget ;
class Window ;
}
namespace MWGui
{
class Layout ;
class WindowBase ;
}
struct XrCompositionLayerQuad ;
namespace MWVR
{
class GUICamera ;
class VRGUIManager ;
enum class TrackingMode
{
2020-05-12 20:13:01 +00:00
Menu , //!< Menu quads with fixed position based on head tracking.
HudLeftHand , //!< Hud quads tracking the left hand every frame
HudRightHand , //!< Hud quads tracking the right hand every frame
} ;
// Some UI elements should occupy predefined geometries
// Others should grow/shrink freely
enum class SizingMode
{
Auto ,
Fixed
2020-05-01 19:37:01 +00:00
} ;
struct LayerConfig
{
2020-05-12 20:13:01 +00:00
int priority ; //!< Higher priority shows over lower priority windows.
bool sideBySide ; //!< Resize layer window to occupy full quad
2020-05-01 19:37:01 +00:00
osg : : Vec4 backgroundColor ; //!< Background color of layer
osg : : Vec3 offset ; //!< Offset from tracked node in meters
2020-05-12 20:13:01 +00:00
osg : : Vec2 center ; //!< Model space centerpoint of menu geometry. All menu geometries have model space lengths of 1 in each dimension. Use this to affect how geometries grow with changing size.
osg : : Vec2 extent ; //!< Spatial extent of the layer in meters when using Fixed sizing mode
int spatialResolution ; //!< Pixels when using the Auto sizing mode. \note Meters per pixel of the GUI viewport, not the RTT texture.
osg : : Vec2i pixelResolution ; //!< Pixel resolution of the RTT texture
osg : : Vec2 myGUIViewSize ; //!< Resizable elements are resized to this (fraction of full view)
SizingMode sizingMode ; //!< How to size the layer
2020-05-01 19:37:01 +00:00
TrackingMode trackingMode ; //!< Tracking mode
2020-05-17 14:25:51 +00:00
std : : string extraLayers ; //!< Additional layers to draw (list separated by any non-alphabetic)
2020-05-12 20:13:01 +00:00
bool operator < ( const LayerConfig & rhs ) const { return priority < rhs . priority ; }
2020-05-01 19:37:01 +00:00
} ;
class VRGUILayer
{
public :
VRGUILayer (
osg : : ref_ptr < osg : : Group > geometryRoot ,
osg : : ref_ptr < osg : : Group > cameraRoot ,
2020-05-17 14:25:51 +00:00
std : : string layerName ,
2020-05-01 19:37:01 +00:00
LayerConfig config ,
VRGUIManager * parent ) ;
~ VRGUILayer ( ) ;
osg : : Camera * camera ( ) ;
osg : : ref_ptr < osg : : Texture2D > menuTexture ( ) ;
2020-05-12 20:13:01 +00:00
void setAngle ( float angle ) ;
void updateTracking ( const Pose & headPose = { } ) ;
2020-05-01 19:37:01 +00:00
void updatePose ( ) ;
2020-05-12 20:13:01 +00:00
void updateRect ( ) ;
2020-05-01 19:37:01 +00:00
void update ( ) ;
2020-05-12 20:13:01 +00:00
void insertWidget ( MWGui : : Layout * widget ) ;
void removeWidget ( MWGui : : Layout * widget ) ;
int widgetCount ( ) { return mWidgets . size ( ) ; }
bool operator < ( const VRGUILayer & rhs ) const { return mConfig . priority < rhs . mConfig . priority ; }
2020-05-01 19:37:01 +00:00
public :
Pose mTrackedPose { } ;
LayerConfig mConfig ;
2020-05-17 14:25:51 +00:00
std : : string mLayerName ;
2020-05-12 20:13:01 +00:00
std : : vector < MWGui : : Layout * > mWidgets ;
2020-05-01 19:37:01 +00:00
osg : : ref_ptr < osg : : Group > mGeometryRoot ;
osg : : ref_ptr < osg : : Geometry > mGeometry { new osg : : Geometry } ;
osg : : ref_ptr < osg : : PositionAttitudeTransform > mTransform { new osg : : PositionAttitudeTransform } ;
osg : : ref_ptr < osg : : Group > mCameraRoot ;
osg : : ref_ptr < GUICamera > mGUICamera ;
2020-05-12 20:13:01 +00:00
osg : : ref_ptr < osg : : Camera > mMyGUICamera { nullptr } ;
MyGUI : : FloatRect mRealRect { } ;
osg : : Quat mRotation { 0 , 0 , 0 , 1 } ;
2020-05-01 19:37:01 +00:00
} ;
class VRGUILayerUserData : public osg : : Referenced
{
public :
2020-05-12 20:13:01 +00:00
VRGUILayerUserData ( std : : shared_ptr < VRGUILayer > layer ) : mLayer ( layer ) { } ;
2020-05-01 19:37:01 +00:00
2020-05-12 20:13:01 +00:00
std : : weak_ptr < VRGUILayer > mLayer ;
2020-05-01 19:37:01 +00:00
} ;
class VRGUIManager
{
public :
VRGUIManager (
osg : : ref_ptr < osgViewer : : Viewer > viewer ) ;
~ VRGUIManager ( void ) ;
void setVisible ( MWGui : : Layout * , bool visible ) ;
2020-05-12 20:13:01 +00:00
void updateSideBySideLayers ( ) ;
void insertLayer ( const std : : string & name ) ;
void insertWidget ( MWGui : : Layout * widget ) ;
void removeLayer ( const std : : string & name ) ;
void removeWidget ( MWGui : : Layout * widget ) ;
void updateTracking ( void ) ;
2020-05-17 14:25:51 +00:00
bool updateFocus ( ) ;
2020-05-01 19:37:01 +00:00
void setFocusLayer ( VRGUILayer * layer ) ;
2020-05-12 20:13:01 +00:00
osg : : Vec2i guiCursor ( ) { return mGuiCursor ; } ;
2020-05-01 19:37:01 +00:00
private :
2020-05-12 20:13:01 +00:00
void computeGuiCursor ( osg : : Vec3 hitPoint ) ;
2020-05-01 19:37:01 +00:00
osg : : ref_ptr < osgViewer : : Viewer > mOsgViewer { nullptr } ;
osg : : ref_ptr < osg : : Group > mGUIGeometriesRoot { new osg : : Group } ;
osg : : ref_ptr < osg : : Group > mGUICamerasRoot { new osg : : Group } ;
2020-05-12 20:13:01 +00:00
std : : map < std : : string , std : : shared_ptr < VRGUILayer > > mLayers ;
std : : vector < std : : shared_ptr < VRGUILayer > > mSideBySideLayers ;
2020-05-01 19:37:01 +00:00
2020-05-12 20:13:01 +00:00
Pose mHeadPose { } ;
osg : : Vec2i mGuiCursor { } ;
2020-05-01 19:37:01 +00:00
VRGUILayer * mFocusLayer { nullptr } ;
} ;
}
# endif