From b710fa5a75f65f839fecf449915d6326b15f0aec Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Tue, 1 Dec 2020 21:36:46 +0100 Subject: [PATCH] Another attempt at fixing the pipelines via mygui3.2 compatibility. This time by injecting inheritance of layers to inject the setPick function. --- apps/openmw/mwgui/layout.cpp | 19 ------ apps/openmw/mwgui/layout.hpp | 3 - apps/openmw/mwgui/windowmanagerimp.cpp | 7 +++ apps/openmw/mwvr/vrgui.cpp | 72 ++++++++++++++++++++-- apps/openmw/mwvr/vrgui.hpp | 4 ++ components/myguiplatform/additivelayer.hpp | 2 +- components/myguiplatform/scalinglayer.hpp | 2 +- 7 files changed, 81 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwgui/layout.cpp b/apps/openmw/mwgui/layout.cpp index ab201ae64..49030817b 100644 --- a/apps/openmw/mwgui/layout.cpp +++ b/apps/openmw/mwgui/layout.cpp @@ -83,25 +83,6 @@ namespace MWGui window->setCaptionWithReplacing(title); } - void Layout::setLayerPick(bool pick) - { -#if MYGUI_VERSION >= MYGUI_DEFINE_VERSION(3,4,0) - MyGUI::ILayer* layer = mMainWidget->getLayer(); - // MyGUI exposes pick on the implementations of ILayer only, but not ILayer itself. - auto* oLayer = layer->castType(false); - auto* sLayer = layer->castType(false); - if (oLayer) - oLayer->setPick(pick); - if (sLayer) - sLayer->setPick(pick); -#else -#ifdef USE_OPENXR -#error "MyGUI version 3.4.0 or greater required to build for VR" -#endif - throw std::logic_error("Not implemented"); -#endif - } - MyGUI::Widget* Layout::getWidget(const std::string &_name) { for (MyGUI::Widget* widget : mListWindowRoot) diff --git a/apps/openmw/mwgui/layout.hpp b/apps/openmw/mwgui/layout.hpp index d10aadc55..910015c1e 100644 --- a/apps/openmw/mwgui/layout.hpp +++ b/apps/openmw/mwgui/layout.hpp @@ -64,9 +64,6 @@ namespace MWGui // NOTE: this assume that mMainWidget is of type Window. void setTitle(const std::string& title); - /// \note Affects the layer, not just the widget. - void setLayerPick(bool pick); - MyGUI::Widget* mMainWidget; protected: diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 7a75b092e..58bf17fdf 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -200,6 +200,7 @@ namespace MWGui mGuiPlatform = new osgMyGUI::Platform(viewer, guiRoot, resourceSystem->getImageManager(), uiScale); mGuiPlatform->initialise(resourcePath, logpath); + #ifdef USE_OPENXR mGuiPlatform->getRenderManagerPtr()->setViewSize(1024, 1024); #endif @@ -238,6 +239,12 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); MyGUI::FactoryManager::getInstance().registerFactory("Resource", "AutoSizedResourceSkin"); + +#ifdef USE_OPENXR + if (MWBase::Environment::get().getVrMode()) + MWVR::VRGUIManager::registerMyGUIFactories(); +#endif + #ifdef USE_OPENXR MyGUI::ResourceManager::getInstance().load("core_vr.xml"); #else diff --git a/apps/openmw/mwvr/vrgui.cpp b/apps/openmw/mwvr/vrgui.cpp index 978e888ff..c649f2574 100644 --- a/apps/openmw/mwvr/vrgui.cpp +++ b/apps/openmw/mwvr/vrgui.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +43,9 @@ #include #include #include +#include +#include +#include namespace osg { @@ -660,7 +665,7 @@ namespace MWVR it->second->insertWidget(widget); if (it->second.get() != mFocusLayer) - widget->setLayerPick(false); + setPick(widget, false); } void VRGUIManager::removeLayer(const std::string& name) @@ -715,7 +720,8 @@ namespace MWVR { Log(Debug::Verbose) << "Blacklisted"; // Never pick an invisible layer - widget->setLayerPick(false); + auto* layer = widget->mMainWidget->getLayer(); + setPick(mFocusLayer->mWidgets.front(), false); return; } @@ -814,13 +820,13 @@ namespace MWVR if (mFocusLayer) { - mFocusLayer->mWidgets.front()->setLayerPick(false); + setPick(mFocusLayer->mWidgets.front(), false); } mFocusLayer = layer; if (mFocusLayer) { Log(Debug::Verbose) << "Set focus layer to " << mFocusLayer->mWidgets.front()->mMainWidget->getLayer()->getName(); - mFocusLayer->mWidgets.front()->setLayerPick(true); + setPick(mFocusLayer->mWidgets.front(), true); } else { @@ -886,6 +892,64 @@ namespace MWVR } } + class Pickable + { + public: + virtual void setPick(bool pick) = 0; + }; + + template + class PickLayer : public L, public Pickable + { + public: + using L::L; + + void setPick(bool pick) override + { + mIsPick = pick; + } + }; + + template + class MyFactory + { + public: + using LayerType = L; + using PickLayerType = PickLayer; + using Delegate = MyGUI::delegates::CDelegate1; + static typename Delegate::IDelegate* getFactory() + { + return MyGUI::newDelegate(createFromFactory); + } + + static void registerFactory() + { + MyGUI::FactoryManager::getInstance().registerFactory("Layer", LayerType::getClassTypeName(), getFactory()); + } + + private: + static void createFromFactory(MyGUI::IObject*& _instance) + { + _instance = new PickLayerType(); + } + }; + + void VRGUIManager::registerMyGUIFactories() + { + MyFactory< MyGUI::OverlappedLayer >::registerFactory(); + MyFactory< MyGUI::SharedLayer >::registerFactory(); + MyFactory< osgMyGUI::AdditiveLayer >::registerFactory(); + MyFactory< osgMyGUI::AdditiveLayer >::registerFactory(); + } + + void VRGUIManager::setPick(MWGui::Layout* widget, bool pick) + { + auto* layer = widget->mMainWidget->getLayer(); + auto* pickable = dynamic_cast(layer); + if (pickable) + pickable->setPick(pick); + } + void VRGUIManager::computeGuiCursor(osg::Vec3 hitPoint) { float x = 0; diff --git a/apps/openmw/mwvr/vrgui.hpp b/apps/openmw/mwvr/vrgui.hpp index 3497e8d1e..6d46b95b8 100644 --- a/apps/openmw/mwvr/vrgui.hpp +++ b/apps/openmw/mwvr/vrgui.hpp @@ -168,6 +168,10 @@ namespace MWVR /// Update settings where applicable void processChangedSettings(const std::set< std::pair >& changed); + static void registerMyGUIFactories(); + + static void setPick(MWGui::Layout* widget, bool pick); + private: void computeGuiCursor(osg::Vec3 hitPoint); void updateSideBySideLayers(); diff --git a/components/myguiplatform/additivelayer.hpp b/components/myguiplatform/additivelayer.hpp index f89e1d007..eb8a2a719 100644 --- a/components/myguiplatform/additivelayer.hpp +++ b/components/myguiplatform/additivelayer.hpp @@ -14,7 +14,7 @@ namespace osgMyGUI { /// @brief A Layer rendering with additive blend mode. - class AdditiveLayer final : public MyGUI::OverlappedLayer + class AdditiveLayer : public MyGUI::OverlappedLayer { public: MYGUI_RTTI_DERIVED( AdditiveLayer ) diff --git a/components/myguiplatform/scalinglayer.hpp b/components/myguiplatform/scalinglayer.hpp index f9fd92a78..70f476638 100644 --- a/components/myguiplatform/scalinglayer.hpp +++ b/components/myguiplatform/scalinglayer.hpp @@ -8,7 +8,7 @@ namespace osgMyGUI ///@brief A Layer that lays out and renders widgets in screen-relative coordinates. The "Size" property determines the size of the virtual screen, /// which is then upscaled to the real screen size during rendering. The aspect ratio is kept intact, adding blanks to the sides when necessary. - class ScalingLayer final : public MyGUI::OverlappedLayer + class ScalingLayer : public MyGUI::OverlappedLayer { public: MYGUI_RTTI_DERIVED(ScalingLayer)