mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-04 18:45:31 +00:00
Some refactoring
This commit is contained in:
parent
f5e01417ba
commit
da03e8bf41
22 changed files with 362 additions and 188 deletions
|
@ -116,6 +116,8 @@ if(BUILD_VR_OPENXR)
|
|||
engine_vr.cpp
|
||||
mwvr/openxranimation.hpp
|
||||
mwvr/openxranimation.cpp
|
||||
mwvr/openxrenvironment.hpp
|
||||
mwvr/openxrenvironment.cpp
|
||||
mwvr/openxrinputmanager.hpp
|
||||
mwvr/openxrinputmanager.cpp
|
||||
mwvr/openxrlayer.hpp
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
|
||||
#ifdef USE_OPENXR
|
||||
#include "mwvr/openxrinputmanager.hpp"
|
||||
#include "mwvr/openxrviewer.hpp"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
|
@ -548,7 +549,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
gameControllerdb = ""; //if it doesn't exist, pass in an empty string
|
||||
MWInput::InputManager* input =
|
||||
#ifdef USE_OPENXR
|
||||
new MWVR::OpenXRInputManager(mWindow, mXRViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
|
||||
new MWVR::OpenXRInputManager(mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
|
||||
#else
|
||||
new MWInput::InputManager (mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
|
||||
#endif
|
||||
|
@ -736,8 +737,9 @@ void OMW::Engine::go()
|
|||
|
||||
#ifdef USE_OPENXR
|
||||
auto* root = mViewer->getSceneData();
|
||||
mXRViewer->addChild(root);
|
||||
mViewer->setSceneData(mXRViewer);
|
||||
auto* xrViewer = MWVR::OpenXREnvironment::get().getViewer();
|
||||
xrViewer->addChild(root);
|
||||
mViewer->setSceneData(xrViewer);
|
||||
#ifndef _NDEBUG
|
||||
//mXR->addPoseUpdateCallback(new MWVR::PoseLogger(MWVR::TrackedLimb::HEAD, MWVR::TrackedSpace::STAGE));
|
||||
//mXR->addPoseUpdateCallback(new MWVR::PoseLogger(MWVR::TrackedLimb::HEAD, MWVR::TrackedSpace::VIEW));
|
||||
|
@ -798,7 +800,7 @@ void OMW::Engine::go()
|
|||
mEnvironment.getWorld()->updateWindowManager();
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
mXRViewer->traversals();
|
||||
xrViewer->traversals();
|
||||
#else
|
||||
mViewer->updateTraversal();
|
||||
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
#include "mwworld/ptr.hpp"
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
#include "mwvr/openxrmanager.hpp"
|
||||
#include "mwvr/openxrviewer.hpp"
|
||||
#include "mwvr/openxrenvironment.hpp"
|
||||
#endif
|
||||
|
||||
namespace Resource
|
||||
|
@ -213,8 +212,7 @@ namespace OMW
|
|||
Files::ConfigurationManager& mCfgMgr;
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
osg::ref_ptr<MWVR::OpenXRManager> mXR;
|
||||
osg::ref_ptr<MWVR::OpenXRViewer> mXRViewer;
|
||||
MWVR::OpenXREnvironment mXrEnvironment;
|
||||
|
||||
void initVr();
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "engine.hpp"
|
||||
#include "mwbase/environment.hpp"
|
||||
#include "mwvr/openxrmanager.hpp"
|
||||
#include "mwvr/openxrsession.hpp"
|
||||
#include "mwvr/openxrviewer.hpp"
|
||||
|
||||
#ifndef USE_OPENXR
|
||||
#error "USE_OPENXR not defined"
|
||||
|
@ -12,14 +12,14 @@ void OMW::Engine::initVr()
|
|||
if (!mViewer)
|
||||
throw std::logic_error("mViewer must be initialized before calling initVr()");
|
||||
|
||||
mXR = new MWVR::OpenXRManager();
|
||||
mXrEnvironment.setManager(new MWVR::OpenXRManager);
|
||||
|
||||
// Ref: https://wiki.openmw.org/index.php?title=Measurement_Units
|
||||
float unitsPerYard = 64.f;
|
||||
float yardsPerMeter = 0.9144f;
|
||||
float unitsPerMeter = unitsPerYard / yardsPerMeter;
|
||||
mEnvironment.setXRSession(new MWVR::OpenXRSession(mXR, unitsPerMeter));
|
||||
|
||||
mXRViewer = new MWVR::OpenXRViewer(mXR, mViewer);
|
||||
mXrEnvironment.setUnitsPerMeter(unitsPerMeter);
|
||||
mXrEnvironment.setSession(new MWVR::OpenXRSession());
|
||||
mXrEnvironment.setViewer(new MWVR::OpenXRViewer(mViewer));
|
||||
|
||||
}
|
||||
|
|
|
@ -200,26 +200,3 @@ const MWBase::Environment& MWBase::Environment::get()
|
|||
return *sThis;
|
||||
}
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
#include "../mwvr/openxrinputmanager.hpp"
|
||||
#include "../mwvr/openxrsession.hpp"
|
||||
|
||||
MWVR::OpenXRInputManager* MWBase::Environment::getXRInputManager() const
|
||||
{
|
||||
assert(mInputManager);
|
||||
auto xrInputManager = dynamic_cast<MWVR::OpenXRInputManager*>(mInputManager);
|
||||
assert(xrInputManager);
|
||||
return xrInputManager;
|
||||
}
|
||||
|
||||
MWVR::OpenXRSession* MWBase::Environment::getXRSession() const
|
||||
{
|
||||
return mXrSession;
|
||||
}
|
||||
|
||||
void MWBase::Environment::setXRSession(MWVR::OpenXRSession* xrSession)
|
||||
{
|
||||
mXrSession = xrSession;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
#ifndef GAME_BASE_ENVIRONMENT_H
|
||||
#define GAME_BASE_ENVIRONMENT_H
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
namespace MWVR
|
||||
{
|
||||
class OpenXRInputManager;
|
||||
class OpenXRSession;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace MWBase
|
||||
{
|
||||
class World;
|
||||
|
@ -108,15 +100,6 @@ namespace MWBase
|
|||
static const Environment& get();
|
||||
///< Return instance of this class.
|
||||
|
||||
// VR Extensions
|
||||
#ifdef USE_OPENXR
|
||||
MWVR::OpenXRInputManager* getXRInputManager() const;
|
||||
MWVR::OpenXRSession* getXRSession() const;
|
||||
void setXRSession(MWVR::OpenXRSession* xrSession);
|
||||
|
||||
private:
|
||||
MWVR::OpenXRSession* mXrSession;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#ifdef USE_OPENXR
|
||||
#include "../mwvr/openxrsession.hpp"
|
||||
#include "../mwvr/openxrinputmanager.hpp"
|
||||
#include "../mwvr/openxrenvironment.hpp"
|
||||
#endif
|
||||
|
||||
#include "collisiontype.hpp"
|
||||
|
@ -289,7 +290,7 @@ namespace MWPhysics
|
|||
#ifdef USE_OPENXR
|
||||
if (isPlayer)
|
||||
{
|
||||
auto session = MWBase::Environment::get().getXRSession();
|
||||
auto* session = MWVR::OpenXREnvironment::get().getSession();
|
||||
if (session)
|
||||
{
|
||||
float yaw = session->movementYaw();
|
||||
|
@ -388,7 +389,7 @@ namespace MWPhysics
|
|||
#ifdef USE_OPENXR
|
||||
if (isPlayer)
|
||||
{
|
||||
auto inputManager = MWBase::Environment::get().getXRInputManager();
|
||||
auto* inputManager = MWVR::OpenXREnvironment::get().getInputManager();
|
||||
|
||||
osg::Vec3 trackingOffset = inputManager->mHeadOffset;
|
||||
// Player's tracking height should not affect character position
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#ifdef USE_OPENXR
|
||||
#include "../mwvr/openxrinputmanager.hpp"
|
||||
#include "../mwvr/openxrenvironment.hpp"
|
||||
#endif
|
||||
|
||||
#include "npcanimation.hpp"
|
||||
|
@ -126,7 +127,7 @@ namespace MWRender
|
|||
osg::Vec3d position = getFocalPoint();
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
auto inputManager = MWBase::Environment::get().getXRInputManager();
|
||||
auto* inputManager = MWVR::OpenXREnvironment::get().getInputManager();
|
||||
if (inputManager)
|
||||
{
|
||||
position += inputManager->mHeadOffset;
|
||||
|
|
106
apps/openmw/mwvr/openxrenvironment.cpp
Normal file
106
apps/openmw/mwvr/openxrenvironment.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
#include "openxrenvironment.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "openxrinputmanager.hpp"
|
||||
#include "openxrsession.hpp"
|
||||
#include "openxrmenu.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
MWVR::OpenXREnvironment *MWVR::OpenXREnvironment::sThis = 0;
|
||||
|
||||
MWVR::OpenXREnvironment::OpenXREnvironment()
|
||||
: mSession(nullptr)
|
||||
{
|
||||
assert (!sThis);
|
||||
sThis = this;
|
||||
}
|
||||
|
||||
MWVR::OpenXREnvironment::~OpenXREnvironment()
|
||||
{
|
||||
cleanup();
|
||||
sThis = 0;
|
||||
}
|
||||
|
||||
void MWVR::OpenXREnvironment::cleanup()
|
||||
{
|
||||
if (mSession)
|
||||
delete mSession;
|
||||
mSession = nullptr;
|
||||
if (mMenuManager)
|
||||
delete mMenuManager;
|
||||
mMenuManager = nullptr;
|
||||
if (mViewer)
|
||||
delete mViewer;
|
||||
mViewer = nullptr;
|
||||
if (mOpenXRManager)
|
||||
delete mOpenXRManager;
|
||||
mOpenXRManager = nullptr;
|
||||
}
|
||||
|
||||
const MWVR::OpenXREnvironment& MWVR::OpenXREnvironment::get()
|
||||
{
|
||||
assert (sThis);
|
||||
return *sThis;
|
||||
}
|
||||
|
||||
MWVR::OpenXRInputManager* MWVR::OpenXREnvironment::getInputManager() const
|
||||
{
|
||||
auto* inputManager = MWBase::Environment::get().getInputManager();
|
||||
assert(inputManager);
|
||||
auto xrInputManager = dynamic_cast<MWVR::OpenXRInputManager*>(inputManager);
|
||||
assert(xrInputManager);
|
||||
return xrInputManager;
|
||||
}
|
||||
|
||||
MWVR::OpenXRSession* MWVR::OpenXREnvironment::getSession() const
|
||||
{
|
||||
return mSession;
|
||||
}
|
||||
|
||||
void MWVR::OpenXREnvironment::setSession(MWVR::OpenXRSession* xrSession)
|
||||
{
|
||||
mSession = xrSession;
|
||||
}
|
||||
|
||||
MWVR::OpenXRMenuManager* MWVR::OpenXREnvironment::getMenuManager() const
|
||||
{
|
||||
return mMenuManager;
|
||||
}
|
||||
|
||||
void MWVR::OpenXREnvironment::setMenuManager(MWVR::OpenXRMenuManager* menuManager)
|
||||
{
|
||||
mMenuManager = menuManager;
|
||||
}
|
||||
|
||||
|
||||
MWVR::OpenXRViewer* MWVR::OpenXREnvironment::getViewer() const
|
||||
{
|
||||
return mViewer;
|
||||
}
|
||||
|
||||
void MWVR::OpenXREnvironment::setViewer(MWVR::OpenXRViewer* xrViewer)
|
||||
{
|
||||
mViewer = xrViewer;
|
||||
}
|
||||
|
||||
MWVR::OpenXRManager* MWVR::OpenXREnvironment::getManager() const
|
||||
{
|
||||
return mOpenXRManager;
|
||||
}
|
||||
|
||||
void MWVR::OpenXREnvironment::setManager(MWVR::OpenXRManager* xrManager)
|
||||
{
|
||||
mOpenXRManager = xrManager;
|
||||
}
|
||||
|
||||
float MWVR::OpenXREnvironment::unitsPerMeter() const
|
||||
{
|
||||
return mUnitsPerMeter;
|
||||
}
|
||||
|
||||
void MWVR::OpenXREnvironment::setUnitsPerMeter(float unitsPerMeter)
|
||||
{
|
||||
mUnitsPerMeter = unitsPerMeter;
|
||||
}
|
71
apps/openmw/mwvr/openxrenvironment.hpp
Normal file
71
apps/openmw/mwvr/openxrenvironment.hpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
#ifndef OPENXR_ENVIRONMENT_H
|
||||
#define OPENXR_ENVIRONMENT_H
|
||||
|
||||
namespace MWVR
|
||||
{
|
||||
class OpenXRInputManager;
|
||||
class OpenXRSession;
|
||||
class OpenXRMenuManager;
|
||||
class OpenXRViewer;
|
||||
class OpenXRManager;
|
||||
|
||||
/// \brief Central hub for mw openxr subsystems
|
||||
///
|
||||
/// This class allows each mw openxr subsystem to access any others subsystem's top-level manager class.
|
||||
///
|
||||
/// \attention OpenXREnvironment takes ownership of the manager class instances it is handed over in
|
||||
/// the set* functions.
|
||||
class OpenXREnvironment
|
||||
{
|
||||
|
||||
static OpenXREnvironment*sThis;
|
||||
|
||||
OpenXREnvironment(const OpenXREnvironment&) = delete;
|
||||
///< not implemented
|
||||
|
||||
OpenXREnvironment& operator= (const OpenXREnvironment&) = delete;
|
||||
///< not implemented
|
||||
|
||||
public:
|
||||
|
||||
OpenXREnvironment();
|
||||
|
||||
~OpenXREnvironment();
|
||||
|
||||
void cleanup();
|
||||
///< Delete all mwvr-subsystems.
|
||||
|
||||
static const OpenXREnvironment& get();
|
||||
///< Return instance of this class.
|
||||
|
||||
MWVR::OpenXRInputManager* getInputManager() const;
|
||||
|
||||
// The OpenXRInputManager supplants the regular input manager
|
||||
// which is stored in MWBase::Environment
|
||||
// void setInputManager(MWVR::OpenXRInputManager*);
|
||||
|
||||
MWVR::OpenXRMenuManager* getMenuManager() const;
|
||||
void setMenuManager(MWVR::OpenXRMenuManager* xrMenuManager);
|
||||
|
||||
MWVR::OpenXRSession* getSession() const;
|
||||
void setSession(MWVR::OpenXRSession* xrSession);
|
||||
|
||||
MWVR::OpenXRViewer* getViewer() const;
|
||||
void setViewer(MWVR::OpenXRViewer* xrViewer);
|
||||
|
||||
MWVR::OpenXRManager* getManager() const;
|
||||
void setManager(MWVR::OpenXRManager* xrManager);
|
||||
|
||||
float unitsPerMeter() const;
|
||||
void setUnitsPerMeter(float unitsPerMeter);
|
||||
|
||||
private:
|
||||
MWVR::OpenXRSession* mSession;
|
||||
MWVR::OpenXRMenuManager* mMenuManager;
|
||||
MWVR::OpenXRViewer* mViewer;
|
||||
MWVR::OpenXRManager* mOpenXRManager;
|
||||
float mUnitsPerMeter;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,4 +1,5 @@
|
|||
#include "openxrinputmanager.hpp"
|
||||
#include "openxrenvironment.hpp"
|
||||
#include "openxrmanager.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
|
||||
|
@ -63,7 +64,7 @@ namespace MWVR
|
|||
OpenXRAction(const OpenXRAction&) = default;
|
||||
OpenXRAction& operator=(const OpenXRAction&) = default;
|
||||
public:
|
||||
OpenXRAction(osg::ref_ptr<OpenXRManager> XR, XrAction action, XrActionType actionType, const std::string& actionName, const std::string& localName);
|
||||
OpenXRAction(XrAction action, XrActionType actionType, const std::string& actionName, const std::string& localName);
|
||||
~OpenXRAction();
|
||||
|
||||
|
||||
|
@ -74,7 +75,6 @@ namespace MWVR
|
|||
bool getPose(XrPath subactionPath);
|
||||
bool applyHaptics(XrPath subactionPath, float amplitude);
|
||||
|
||||
osg::ref_ptr<OpenXRManager> mXR = nullptr;
|
||||
XrAction mAction = XR_NULL_HANDLE;
|
||||
XrActionType mType;
|
||||
std::string mName;
|
||||
|
@ -182,7 +182,7 @@ namespace MWVR
|
|||
|
||||
ControllerActionPaths generateControllerActionPaths(const std::string& controllerAction);
|
||||
|
||||
OpenXRInput(osg::ref_ptr<OpenXRManager> XR);
|
||||
OpenXRInput();
|
||||
|
||||
OpenXRAction createAction(XrActionType actionType, const std::string& actionName, const std::string& localName, const std::vector<SubAction>& subActions = {});
|
||||
|
||||
|
@ -194,7 +194,6 @@ namespace MWVR
|
|||
bool nextActionEvent(OpenXRActionEvent& action);
|
||||
PoseSet getHandPoses(int64_t time, TrackedSpace space);
|
||||
|
||||
osg::ref_ptr<OpenXRManager> mXR;
|
||||
SubActionPaths mSubactionPath;
|
||||
XrActionSet mActionSet = XR_NULL_HANDLE;
|
||||
|
||||
|
@ -262,12 +261,13 @@ namespace MWVR
|
|||
XrActionSet
|
||||
OpenXRInput::createActionSet()
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
XrActionSet actionSet = XR_NULL_HANDLE;
|
||||
XrActionSetCreateInfo createInfo{ XR_TYPE_ACTION_SET_CREATE_INFO };
|
||||
strcpy_s(createInfo.actionSetName, "gameplay");
|
||||
strcpy_s(createInfo.localizedActionSetName, "Gameplay");
|
||||
createInfo.priority = 0;
|
||||
CHECK_XRCMD(xrCreateActionSet(mXR->impl().mInstance, &createInfo, &actionSet));
|
||||
CHECK_XRCMD(xrCreateActionSet(xr->impl().mInstance, &createInfo, &actionSet));
|
||||
return actionSet;
|
||||
}
|
||||
|
||||
|
@ -283,13 +283,11 @@ namespace MWVR
|
|||
|
||||
|
||||
OpenXRAction::OpenXRAction(
|
||||
osg::ref_ptr<OpenXRManager> XR,
|
||||
XrAction action,
|
||||
XrActionType actionType,
|
||||
const std::string& actionName,
|
||||
const std::string& localName)
|
||||
: mXR(XR)
|
||||
, mAction(action)
|
||||
: mAction(action)
|
||||
, mType(actionType)
|
||||
, mName(actionName)
|
||||
, mLocalName(localName)
|
||||
|
@ -306,12 +304,13 @@ namespace MWVR
|
|||
|
||||
bool OpenXRAction::getFloat(XrPath subactionPath, float& value)
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
XrActionStateGetInfo getInfo{ XR_TYPE_ACTION_STATE_GET_INFO };
|
||||
getInfo.action = mAction;
|
||||
getInfo.subactionPath = subactionPath;
|
||||
|
||||
XrActionStateFloat xrValue{ XR_TYPE_ACTION_STATE_FLOAT };
|
||||
CHECK_XRCMD(xrGetActionStateFloat(mXR->impl().mSession, &getInfo, &xrValue));
|
||||
CHECK_XRCMD(xrGetActionStateFloat(xr->impl().mSession, &getInfo, &xrValue));
|
||||
|
||||
if (xrValue.isActive)
|
||||
value = xrValue.currentState;
|
||||
|
@ -320,12 +319,13 @@ namespace MWVR
|
|||
|
||||
bool OpenXRAction::getBool(XrPath subactionPath, bool& value)
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
XrActionStateGetInfo getInfo{ XR_TYPE_ACTION_STATE_GET_INFO };
|
||||
getInfo.action = mAction;
|
||||
getInfo.subactionPath = subactionPath;
|
||||
|
||||
XrActionStateBoolean xrValue{ XR_TYPE_ACTION_STATE_BOOLEAN };
|
||||
CHECK_XRCMD(xrGetActionStateBoolean(mXR->impl().mSession, &getInfo, &xrValue));
|
||||
CHECK_XRCMD(xrGetActionStateBoolean(xr->impl().mSession, &getInfo, &xrValue));
|
||||
|
||||
if (xrValue.isActive)
|
||||
value = xrValue.currentState;
|
||||
|
@ -335,18 +335,20 @@ namespace MWVR
|
|||
// Pose action only checks if the pose is active or not
|
||||
bool OpenXRAction::getPose(XrPath subactionPath)
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
XrActionStateGetInfo getInfo{ XR_TYPE_ACTION_STATE_GET_INFO };
|
||||
getInfo.action = mAction;
|
||||
getInfo.subactionPath = subactionPath;
|
||||
|
||||
XrActionStatePose xrValue{ XR_TYPE_ACTION_STATE_POSE };
|
||||
CHECK_XRCMD(xrGetActionStatePose(mXR->impl().mSession, &getInfo, &xrValue));
|
||||
CHECK_XRCMD(xrGetActionStatePose(xr->impl().mSession, &getInfo, &xrValue));
|
||||
|
||||
return xrValue.isActive;
|
||||
}
|
||||
|
||||
bool OpenXRAction::applyHaptics(XrPath subactionPath, float amplitude)
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
XrHapticVibration vibration{ XR_TYPE_HAPTIC_VIBRATION };
|
||||
vibration.amplitude = amplitude;
|
||||
vibration.duration = XR_MIN_HAPTIC_DURATION;
|
||||
|
@ -355,7 +357,7 @@ namespace MWVR
|
|||
XrHapticActionInfo hapticActionInfo{ XR_TYPE_HAPTIC_ACTION_INFO };
|
||||
hapticActionInfo.action = mAction;
|
||||
hapticActionInfo.subactionPath = subactionPath;
|
||||
CHECK_XRCMD(xrApplyHapticFeedback(mXR->impl().mSession, &hapticActionInfo, (XrHapticBaseHeader*)&vibration));
|
||||
CHECK_XRCMD(xrApplyHapticFeedback(xr->impl().mSession, &hapticActionInfo, (XrHapticBaseHeader*)&vibration));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -408,23 +410,22 @@ namespace MWVR
|
|||
OpenXRInput::generateControllerActionPaths(
|
||||
const std::string& controllerAction)
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
ControllerActionPaths actionPaths;
|
||||
|
||||
std::string left = std::string("/user/hand/left") + controllerAction;
|
||||
std::string right = std::string("/user/hand/right") + controllerAction;
|
||||
std::string pad = std::string("/user/gamepad") + controllerAction;
|
||||
|
||||
CHECK_XRCMD(xrStringToPath(mXR->impl().mInstance, left.c_str(), &actionPaths[LEFT_HAND]));
|
||||
CHECK_XRCMD(xrStringToPath(mXR->impl().mInstance, right.c_str(), &actionPaths[RIGHT_HAND]));
|
||||
CHECK_XRCMD(xrStringToPath(mXR->impl().mInstance, pad.c_str(), &actionPaths[GAMEPAD]));
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().mInstance, left.c_str(), &actionPaths[LEFT_HAND]));
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().mInstance, right.c_str(), &actionPaths[RIGHT_HAND]));
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().mInstance, pad.c_str(), &actionPaths[GAMEPAD]));
|
||||
|
||||
return actionPaths;
|
||||
}
|
||||
|
||||
OpenXRInput::OpenXRInput(
|
||||
osg::ref_ptr<OpenXRManager> XR)
|
||||
: mXR(XR)
|
||||
, mSubactionPath{ {
|
||||
OpenXRInput::OpenXRInput()
|
||||
: mSubactionPath{ {
|
||||
generateXrPath("/user/hand/left"),
|
||||
generateXrPath("/user/hand/right"),
|
||||
generateXrPath("/user/gamepad"),
|
||||
|
@ -468,10 +469,11 @@ namespace MWVR
|
|||
, mHandPoseAction(std::move(createAction(XR_ACTION_TYPE_POSE_INPUT, "hand_pose", "Hand Pose", { LEFT_HAND, RIGHT_HAND })))
|
||||
, mHapticsAction(std::move(createAction(XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_hand", "Vibrate Hand", { LEFT_HAND, RIGHT_HAND })))
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
{ // Set up default bindings for the oculus
|
||||
XrPath oculusTouchInteractionProfilePath;
|
||||
CHECK_XRCMD(
|
||||
xrStringToPath(XR->impl().mInstance, "/interaction_profiles/oculus/touch_controller", &oculusTouchInteractionProfilePath));
|
||||
xrStringToPath(xr->impl().mInstance, "/interaction_profiles/oculus/touch_controller", &oculusTouchInteractionProfilePath));
|
||||
std::vector<XrActionSuggestedBinding> bindings{ {
|
||||
{mHandPoseAction, mPosePath[LEFT_HAND]},
|
||||
{mHandPoseAction, mPosePath[RIGHT_HAND]},
|
||||
|
@ -500,7 +502,7 @@ namespace MWVR
|
|||
suggestedBindings.interactionProfile = oculusTouchInteractionProfilePath;
|
||||
suggestedBindings.suggestedBindings = bindings.data();
|
||||
suggestedBindings.countSuggestedBindings = (uint32_t)bindings.size();
|
||||
CHECK_XRCMD(xrSuggestInteractionProfileBindings(XR->impl().mInstance, &suggestedBindings));
|
||||
CHECK_XRCMD(xrSuggestInteractionProfileBindings(xr->impl().mInstance, &suggestedBindings));
|
||||
|
||||
/*
|
||||
mSpellModifier; // L-Squeeze
|
||||
|
@ -527,16 +529,16 @@ namespace MWVR
|
|||
createInfo.action = mHandPoseAction;
|
||||
createInfo.poseInActionSpace.orientation.w = 1.f;
|
||||
createInfo.subactionPath = mSubactionPath[LEFT_HAND];
|
||||
CHECK_XRCMD(xrCreateActionSpace(XR->impl().mSession, &createInfo, &mHandSpace[LEFT_HAND]));
|
||||
CHECK_XRCMD(xrCreateActionSpace(xr->impl().mSession, &createInfo, &mHandSpace[LEFT_HAND]));
|
||||
createInfo.subactionPath = mSubactionPath[RIGHT_HAND];
|
||||
CHECK_XRCMD(xrCreateActionSpace(XR->impl().mSession, &createInfo, &mHandSpace[RIGHT_HAND]));
|
||||
CHECK_XRCMD(xrCreateActionSpace(xr->impl().mSession, &createInfo, &mHandSpace[RIGHT_HAND]));
|
||||
}
|
||||
|
||||
{ // Set up the action set
|
||||
XrSessionActionSetsAttachInfo attachInfo{ XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO };
|
||||
attachInfo.countActionSets = 1;
|
||||
attachInfo.actionSets = &mActionSet;
|
||||
CHECK_XRCMD(xrAttachSessionActionSets(XR->impl().mSession, &attachInfo));
|
||||
CHECK_XRCMD(xrAttachSessionActionSets(xr->impl().mSession, &attachInfo));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -563,7 +565,8 @@ namespace MWVR
|
|||
|
||||
XrAction action = XR_NULL_HANDLE;
|
||||
CHECK_XRCMD(xrCreateAction(mActionSet, &createInfo, &action));
|
||||
return OpenXRAction(mXR, action, actionType, actionName, localName);
|
||||
|
||||
return OpenXRAction(action, actionType, actionName, localName);
|
||||
}
|
||||
|
||||
XrPath
|
||||
|
@ -578,7 +581,8 @@ namespace MWVR
|
|||
void
|
||||
OpenXRInput::updateControls()
|
||||
{
|
||||
if (!mXR->impl().mSessionRunning)
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
if (!xr->impl().mSessionRunning)
|
||||
return;
|
||||
|
||||
|
||||
|
@ -586,7 +590,7 @@ namespace MWVR
|
|||
XrActionsSyncInfo syncInfo{ XR_TYPE_ACTIONS_SYNC_INFO };
|
||||
syncInfo.countActiveActionSets = 1;
|
||||
syncInfo.activeActionSets = &activeActionSet;
|
||||
CHECK_XRCMD(xrSyncActions(mXR->impl().mSession, &syncInfo));
|
||||
CHECK_XRCMD(xrSyncActions(xr->impl().mSession, &syncInfo));
|
||||
|
||||
mGameMenu.update();
|
||||
mInventory.update();
|
||||
|
@ -686,8 +690,9 @@ namespace MWVR
|
|||
|
||||
XrPath OpenXRInput::generateXrPath(const std::string& path)
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
XrPath xrpath = 0;
|
||||
CHECK_XRCMD(xrStringToPath(mXR->impl().mInstance, path.c_str(), &xrpath));
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().mInstance, path.c_str(), &xrpath));
|
||||
return xrpath;
|
||||
}
|
||||
|
||||
|
@ -709,12 +714,13 @@ namespace MWVR
|
|||
int64_t time,
|
||||
TrackedSpace space)
|
||||
{
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
PoseSet handPoses{};
|
||||
XrSpace referenceSpace = XR_NULL_HANDLE;
|
||||
if(space == TrackedSpace::STAGE)
|
||||
referenceSpace = mXR->impl().mReferenceSpaceStage;
|
||||
referenceSpace = xr->impl().mReferenceSpaceStage;
|
||||
if(space == TrackedSpace::VIEW)
|
||||
referenceSpace = mXR->impl().mReferenceSpaceView;
|
||||
referenceSpace = xr->impl().mReferenceSpaceView;
|
||||
|
||||
XrSpaceLocation location{ XR_TYPE_SPACE_LOCATION };
|
||||
XrSpaceVelocity velocity{ XR_TYPE_SPACE_VELOCITY };
|
||||
|
@ -750,7 +756,7 @@ namespace MWVR
|
|||
|
||||
OpenXRInputManager::OpenXRInputManager(
|
||||
SDL_Window* window,
|
||||
osg::ref_ptr<OpenXRViewer> viewer,
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer,
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
||||
osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation,
|
||||
const std::string& userFile,
|
||||
|
@ -760,7 +766,7 @@ namespace MWVR
|
|||
bool grab)
|
||||
: MWInput::InputManager(
|
||||
window,
|
||||
viewer->mViewer,
|
||||
viewer,
|
||||
screenCaptureHandler,
|
||||
screenCaptureOperation,
|
||||
userFile,
|
||||
|
@ -768,7 +774,7 @@ namespace MWVR
|
|||
userControllerBindingsFile,
|
||||
controllerBindingsFile,
|
||||
grab)
|
||||
, mXRInput(new OpenXRInput(viewer->mXR))
|
||||
, mXRInput(new OpenXRInput())
|
||||
{
|
||||
// VR mode has no concept of these
|
||||
mControlSwitch["vanitymode"] = false;
|
||||
|
@ -793,11 +799,10 @@ namespace MWVR
|
|||
bool disableControls,
|
||||
bool disableEvents)
|
||||
{
|
||||
auto* session = OpenXREnvironment::get().getSession();
|
||||
|
||||
mXRInput->updateControls();
|
||||
|
||||
auto* session = MWBase::Environment::get().getXRSession();
|
||||
|
||||
OpenXRActionEvent event{};
|
||||
while (mXRInput->nextActionEvent(event))
|
||||
{
|
||||
|
@ -814,6 +819,7 @@ namespace MWVR
|
|||
|
||||
void OpenXRInputManager::processEvent(const OpenXRActionEvent& event)
|
||||
{
|
||||
auto* session = OpenXREnvironment::get().getSession();
|
||||
switch (event.action)
|
||||
{
|
||||
case A_GameMenu:
|
||||
|
@ -821,7 +827,7 @@ namespace MWVR
|
|||
toggleMainMenu();
|
||||
// Explicitly request position update here so that the player can move the menu
|
||||
// using the menu key when the menu can't be toggled.
|
||||
MWBase::Environment::get().getXRSession()->updateMenuPosition();
|
||||
session->updateMenuPosition();
|
||||
break;
|
||||
case A_Screenshot:
|
||||
screenshot();
|
||||
|
@ -968,10 +974,11 @@ namespace MWVR
|
|||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
auto player = mPlayer->getPlayer();
|
||||
|
||||
auto* session = MWBase::Environment::get().getXRSession();
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
auto* session = OpenXREnvironment::get().getSession();
|
||||
auto currentHeadPose = session->predictedPoses().head[(int)TrackedSpace::STAGE];
|
||||
session->mXR->playerScale(currentHeadPose);
|
||||
currentHeadPose.position *= session->unitsPerMeter();
|
||||
xr->playerScale(currentHeadPose);
|
||||
currentHeadPose.position *= OpenXREnvironment::get().unitsPerMeter();
|
||||
osg::Vec3 vrMovement = currentHeadPose.position - mPreviousHeadPose.position;
|
||||
mPreviousHeadPose = currentHeadPose;
|
||||
|
||||
|
@ -994,13 +1001,10 @@ namespace MWVR
|
|||
osg::Quat gameworldYaw = osg::Quat(mYaw, osg::Vec3(0, 0, -1));
|
||||
mHeadOffset += vrMovement;
|
||||
|
||||
Log(Debug::Verbose) << "Set head offset";
|
||||
|
||||
mVrAngles[0] = pitch;
|
||||
mVrAngles[1] = roll;
|
||||
mVrAngles[2] = yaw;
|
||||
world->rotateObject(player, mVrAngles[0], mVrAngles[1], mVrAngles[2], MWBase::RotationFlag_none);
|
||||
Log(Debug::Verbose) << "yaw=" << yaw << ", pitch=" << pitch << ", roll=" << roll;
|
||||
|
||||
MWBase::Environment::get().getWorld()->getRenderingManager().getCamera()->updateCamera();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace MWVR
|
|||
public:
|
||||
OpenXRInputManager(
|
||||
SDL_Window* window,
|
||||
osg::ref_ptr<OpenXRViewer> viewer,
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer,
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
||||
osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation,
|
||||
const std::string& userFile, bool userFileExists,
|
||||
|
@ -43,7 +43,6 @@ namespace MWVR
|
|||
|
||||
void showActivationIndication(bool show);
|
||||
|
||||
osg::ref_ptr<OpenXRViewer> mXRViewer;
|
||||
std::unique_ptr<OpenXRInput> mXRInput;
|
||||
Pose mPreviousHeadPose{};
|
||||
osg::Vec3 mHeadOffset{ 0,0,0 };
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "openxrenvironment.hpp"
|
||||
#include "openxrmanager.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
#include "../mwinput/inputmanagerimp.hpp"
|
||||
|
@ -198,13 +199,15 @@ namespace MWVR
|
|||
OpenXRManager::RealizeOperation::operator()(
|
||||
osg::GraphicsContext* gc)
|
||||
{
|
||||
mXR->realize(gc);
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
xr->realize(gc);
|
||||
}
|
||||
|
||||
bool
|
||||
OpenXRManager::RealizeOperation::realized()
|
||||
{
|
||||
return mXR->realized();
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
return xr->realized();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -85,22 +85,20 @@ namespace MWVR
|
|||
class RealizeOperation : public osg::GraphicsOperation
|
||||
{
|
||||
public:
|
||||
RealizeOperation(osg::ref_ptr<OpenXRManager> XR) : osg::GraphicsOperation("OpenXRRealizeOperation", false), mXR(XR) {};
|
||||
RealizeOperation() : osg::GraphicsOperation("OpenXRRealizeOperation", false){};
|
||||
void operator()(osg::GraphicsContext* gc) override;
|
||||
virtual bool realized();
|
||||
|
||||
private:
|
||||
osg::ref_ptr<OpenXRManager> mXR;
|
||||
};
|
||||
|
||||
class CleanupOperation : public osg::GraphicsOperation
|
||||
{
|
||||
public:
|
||||
CleanupOperation(osg::ref_ptr<OpenXRManager> XR) : osg::GraphicsOperation("OpenXRCleanupOperation", false), mXR(XR) {};
|
||||
CleanupOperation() : osg::GraphicsOperation("OpenXRCleanupOperation", false) {};
|
||||
void operator()(osg::GraphicsContext* gc) override;
|
||||
|
||||
private:
|
||||
osg::ref_ptr<OpenXRManager> mXR;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -97,4 +97,23 @@ namespace MWVR
|
|||
{
|
||||
// Doesn't need to do anything
|
||||
}
|
||||
|
||||
OpenXRMenuManager::OpenXRMenuManager(
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer)
|
||||
: mOsgViewer(viewer)
|
||||
{
|
||||
mMenusRoot->setName("XR Menus Root");
|
||||
}
|
||||
|
||||
OpenXRMenuManager::~OpenXRMenuManager(void)
|
||||
{
|
||||
}
|
||||
|
||||
void OpenXRMenuManager::showMenus(bool show)
|
||||
{
|
||||
}
|
||||
|
||||
void OpenXRMenuManager::updatePose(Pose pose)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,25 @@ namespace MWVR
|
|||
osg::ref_ptr<osg::Geode> mGeode{ new osg::Geode };
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> mTransform{ new osg::PositionAttitudeTransform() };
|
||||
};
|
||||
|
||||
class OpenXRMenuManager
|
||||
{
|
||||
public:
|
||||
OpenXRMenuManager(
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer);
|
||||
|
||||
~OpenXRMenuManager(void);
|
||||
|
||||
void showMenus(bool show);
|
||||
|
||||
void updatePose(Pose pose);
|
||||
|
||||
private:
|
||||
Pose pose{};
|
||||
osg::ref_ptr<osgViewer::Viewer> mOsgViewer{ nullptr };
|
||||
osg::ref_ptr<osg::Group> mMenusRoot{ new osg::Group };
|
||||
std::unique_ptr<OpenXRMenu> mMenu{ nullptr };
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "openxrenvironment.hpp"
|
||||
#include "openxrmanager.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
#include "openxrinputmanager.hpp"
|
||||
|
@ -26,11 +27,7 @@
|
|||
|
||||
namespace MWVR
|
||||
{
|
||||
OpenXRSession::OpenXRSession(
|
||||
osg::ref_ptr<OpenXRManager> XR,
|
||||
float unitsPerMeter)
|
||||
: mXR(XR)
|
||||
, mUnitsPerMeter(unitsPerMeter)
|
||||
OpenXRSession::OpenXRSession()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -48,8 +45,10 @@ namespace MWVR
|
|||
void OpenXRSession::swapBuffers(osg::GraphicsContext* gc)
|
||||
{
|
||||
Timer timer("OpenXRSession::SwapBuffers");
|
||||
static int wat = 0;
|
||||
if (!mXR->sessionRunning())
|
||||
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
|
||||
if (!xr->sessionRunning())
|
||||
return;
|
||||
if (!mPredictionsReady)
|
||||
return;
|
||||
|
@ -60,17 +59,18 @@ namespace MWVR
|
|||
|
||||
timer.checkpoint("Rendered");
|
||||
|
||||
mXR->endFrame(mXR->impl().frameState().predictedDisplayTime, &mLayerStack);
|
||||
xr->endFrame(xr->impl().frameState().predictedDisplayTime, &mLayerStack);
|
||||
}
|
||||
|
||||
void OpenXRSession::waitFrame()
|
||||
{
|
||||
mXR->handleEvents();
|
||||
if (!mXR->sessionRunning())
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
xr->handleEvents();
|
||||
if (!xr->sessionRunning())
|
||||
return;
|
||||
|
||||
Timer timer("OpenXRSession::waitFrame");
|
||||
mXR->waitFrame();
|
||||
xr->waitFrame();
|
||||
timer.checkpoint("waitFrame");
|
||||
predictNext(0);
|
||||
|
||||
|
@ -152,26 +152,26 @@ namespace MWVR
|
|||
|
||||
void OpenXRSession::predictNext(int extraPeriods)
|
||||
{
|
||||
auto mPredictedDisplayTime = mXR->impl().frameState().predictedDisplayTime;
|
||||
|
||||
auto input = MWBase::Environment::get().getXRInputManager();
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
auto* input = OpenXREnvironment::get().getInputManager();
|
||||
auto mPredictedDisplayTime = xr->impl().frameState().predictedDisplayTime;
|
||||
|
||||
auto previousHeadPose = mPredictedPoses.head[(int)TrackedSpace::STAGE];
|
||||
|
||||
// Update pose predictions
|
||||
mPredictedPoses.head[(int)TrackedSpace::STAGE] = mXR->impl().getPredictedLimbPose(mPredictedDisplayTime, TrackedLimb::HEAD, TrackedSpace::STAGE);
|
||||
mPredictedPoses.head[(int)TrackedSpace::VIEW] = mXR->impl().getPredictedLimbPose(mPredictedDisplayTime, TrackedLimb::HEAD, TrackedSpace::VIEW);
|
||||
mPredictedPoses.head[(int)TrackedSpace::STAGE] = xr->impl().getPredictedLimbPose(mPredictedDisplayTime, TrackedLimb::HEAD, TrackedSpace::STAGE);
|
||||
mPredictedPoses.head[(int)TrackedSpace::VIEW] = xr->impl().getPredictedLimbPose(mPredictedDisplayTime, TrackedLimb::HEAD, TrackedSpace::VIEW);
|
||||
mPredictedPoses.hands[(int)TrackedSpace::STAGE] = input->getHandPoses(mPredictedDisplayTime, TrackedSpace::STAGE);
|
||||
mPredictedPoses.hands[(int)TrackedSpace::VIEW] = input->getHandPoses(mPredictedDisplayTime, TrackedSpace::VIEW);
|
||||
auto stageViews = mXR->impl().getPredictedViews(mPredictedDisplayTime, TrackedSpace::STAGE);
|
||||
auto hmdViews = mXR->impl().getPredictedViews(mPredictedDisplayTime, TrackedSpace::VIEW);
|
||||
auto stageViews = xr->impl().getPredictedViews(mPredictedDisplayTime, TrackedSpace::STAGE);
|
||||
auto hmdViews = xr->impl().getPredictedViews(mPredictedDisplayTime, TrackedSpace::VIEW);
|
||||
mPredictedPoses.eye[(int)TrackedSpace::STAGE][(int)Side::LEFT_HAND] = fromXR(stageViews[(int)Side::LEFT_HAND].pose);
|
||||
mPredictedPoses.eye[(int)TrackedSpace::VIEW][(int)Side::LEFT_HAND] = fromXR(hmdViews[(int)Side::LEFT_HAND].pose);
|
||||
mPredictedPoses.eye[(int)TrackedSpace::STAGE][(int)Side::RIGHT_HAND] = fromXR(stageViews[(int)Side::RIGHT_HAND].pose);
|
||||
mPredictedPoses.eye[(int)TrackedSpace::VIEW][(int)Side::RIGHT_HAND] = fromXR(hmdViews[(int)Side::RIGHT_HAND].pose);
|
||||
|
||||
auto newpos = mPredictedPoses.head[(int)TrackedSpace::STAGE].position * mUnitsPerMeter;
|
||||
auto oldpos = previousHeadPose.position * mUnitsPerMeter;
|
||||
auto newpos = mPredictedPoses.head[(int)TrackedSpace::STAGE].position * OpenXREnvironment::get().unitsPerMeter();
|
||||
auto oldpos = previousHeadPose.position * OpenXREnvironment::get().unitsPerMeter();
|
||||
|
||||
Log(Debug::Verbose) << "Head stage: " << newpos << ", diff=" << (newpos - oldpos);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class OpenXRSession
|
|||
using time_point = clock::time_point;
|
||||
|
||||
public:
|
||||
OpenXRSession(osg::ref_ptr<OpenXRManager> XR, float unitsPerMeter);
|
||||
OpenXRSession();
|
||||
~OpenXRSession();
|
||||
|
||||
void setLayer(OpenXRLayerStack::Layer layerType, OpenXRLayer* layer);
|
||||
|
@ -46,11 +46,7 @@ public:
|
|||
//! Yaw angle to be used for offsetting movement direction
|
||||
float movementYaw(void);
|
||||
|
||||
float unitsPerMeter() const { return mUnitsPerMeter; };
|
||||
|
||||
osg::ref_ptr<OpenXRManager> mXR;
|
||||
OpenXRLayerStack mLayerStack{};
|
||||
float mUnitsPerMeter = 1.f;
|
||||
|
||||
PoseSets mPredictedPoses{};
|
||||
bool mPredictionsReady{ false };
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "openxrsession.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
#include "openxrinputmanager.hpp"
|
||||
#include "openxrenvironment.hpp"
|
||||
#include "Windows.h"
|
||||
#include "../mwrender/vismask.hpp"
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
@ -17,12 +18,10 @@ namespace MWVR
|
|||
{
|
||||
|
||||
OpenXRViewer::OpenXRViewer(
|
||||
osg::ref_ptr<OpenXRManager> XR,
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer)
|
||||
: osg::Group()
|
||||
, mXR(XR)
|
||||
, mCompositionLayerProjectionViews(2, {XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW})
|
||||
, mRealizeOperation(new RealizeOperation(XR, this))
|
||||
, mRealizeOperation(new RealizeOperation())
|
||||
, mViewer(viewer)
|
||||
, mPreDraw(new PredrawCallback(this))
|
||||
, mPostDraw(new PostdrawCallback(this))
|
||||
|
@ -42,10 +41,6 @@ namespace MWVR
|
|||
mRightHandTransform->setName("tracker r hand");
|
||||
mRightHandTransform->setUpdateCallback(new TrackedNodeUpdateCallback(this));
|
||||
this->addChild(mRightHandTransform);
|
||||
|
||||
// TODO: Left off here
|
||||
mMenusRoot = new osg::Group();
|
||||
mMenusRoot->setName("XR Menus Root");
|
||||
}
|
||||
|
||||
OpenXRViewer::~OpenXRViewer(void)
|
||||
|
@ -69,7 +64,8 @@ namespace MWVR
|
|||
|
||||
void OpenXRViewer::traversals()
|
||||
{
|
||||
mXR->handleEvents();
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
xr->handleEvents();
|
||||
mViewer->updateTraversal();
|
||||
mViewer->renderingTraversals();
|
||||
}
|
||||
|
@ -100,21 +96,23 @@ namespace MWVR
|
|||
|
||||
osg::Vec4 clearColor = mainCamera->getClearColor();
|
||||
|
||||
if (!mXR->realized())
|
||||
mXR->realize(context);
|
||||
auto* session = MWBase::Environment::get().getXRSession();
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
if (!xr->realized())
|
||||
xr->realize(context);
|
||||
|
||||
auto* session = OpenXREnvironment::get().getSession();
|
||||
|
||||
OpenXRSwapchain::Config leftConfig;
|
||||
leftConfig.width = mXR->impl().mConfigViews[(int)Side::LEFT_HAND].recommendedImageRectWidth;
|
||||
leftConfig.height = mXR->impl().mConfigViews[(int)Side::LEFT_HAND].recommendedImageRectHeight;
|
||||
leftConfig.samples = mXR->impl().mConfigViews[(int)Side::LEFT_HAND].recommendedSwapchainSampleCount;
|
||||
leftConfig.width = xr->impl().mConfigViews[(int)Side::LEFT_HAND].recommendedImageRectWidth;
|
||||
leftConfig.height = xr->impl().mConfigViews[(int)Side::LEFT_HAND].recommendedImageRectHeight;
|
||||
leftConfig.samples = xr->impl().mConfigViews[(int)Side::LEFT_HAND].recommendedSwapchainSampleCount;
|
||||
OpenXRSwapchain::Config rightConfig;
|
||||
rightConfig.width = mXR->impl().mConfigViews[(int)Side::RIGHT_HAND].recommendedImageRectWidth;
|
||||
rightConfig.height = mXR->impl().mConfigViews[(int)Side::RIGHT_HAND].recommendedImageRectHeight;
|
||||
rightConfig.samples = mXR->impl().mConfigViews[(int)Side::RIGHT_HAND].recommendedSwapchainSampleCount;
|
||||
rightConfig.width = xr->impl().mConfigViews[(int)Side::RIGHT_HAND].recommendedImageRectWidth;
|
||||
rightConfig.height = xr->impl().mConfigViews[(int)Side::RIGHT_HAND].recommendedImageRectHeight;
|
||||
rightConfig.samples = xr->impl().mConfigViews[(int)Side::RIGHT_HAND].recommendedSwapchainSampleCount;
|
||||
|
||||
auto leftView = new OpenXRWorldView(mXR, "LeftEye", context->getState(), leftConfig, session->unitsPerMeter());
|
||||
auto rightView = new OpenXRWorldView(mXR, "RightEye", context->getState(), rightConfig, session->unitsPerMeter());
|
||||
auto leftView = new OpenXRWorldView(xr, "LeftEye", context->getState(), leftConfig);
|
||||
auto rightView = new OpenXRWorldView(xr, "RightEye", context->getState(), rightConfig);
|
||||
|
||||
mViews["LeftEye"] = leftView;
|
||||
mViews["RightEye"] = rightView;
|
||||
|
@ -153,9 +151,9 @@ namespace MWVR
|
|||
|
||||
// Mirror texture doesn't have to be an OpenXR swapchain.
|
||||
// It's just convenient.
|
||||
mMirrorTextureSwapchain.reset(new OpenXRSwapchain(mXR, context->getState(), config));
|
||||
mMirrorTextureSwapchain.reset(new OpenXRSwapchain(xr, context->getState(), config));
|
||||
|
||||
//auto menuView = new OpenXRMenu(mXR, config, context->getState(), "MainMenu", osg::Vec2(1.f, 1.f));
|
||||
//auto menuView = new OpenXRMenu(xr, config, context->getState(), "MainMenu", osg::Vec2(1.f, 1.f));
|
||||
//mViews["MenuView"] = menuView;
|
||||
//auto menuCamera = mCameras["MenuView"] = menuView->createCamera(2, clearColor, context);
|
||||
|
||||
|
@ -167,9 +165,10 @@ namespace MWVR
|
|||
//menuCamera->setPostDrawCallback(mPostDraw);
|
||||
|
||||
|
||||
|
||||
//mViewer->addSlave(menuCamera, true);
|
||||
mViewer->getSlave(0)._updateSlaveCallback = new OpenXRWorldView::UpdateSlaveCallback(mXR, session, leftView, context);
|
||||
mViewer->getSlave(1)._updateSlaveCallback = new OpenXRWorldView::UpdateSlaveCallback(mXR, session, rightView, context);
|
||||
mViewer->getSlave(0)._updateSlaveCallback = new OpenXRWorldView::UpdateSlaveCallback(xr, session, leftView, context);
|
||||
mViewer->getSlave(1)._updateSlaveCallback = new OpenXRWorldView::UpdateSlaveCallback(xr, session, rightView, context);
|
||||
|
||||
mainCamera->getGraphicsContext()->setSwapCallback(new OpenXRViewer::SwapBuffersCallback(this));
|
||||
mainCamera->setGraphicsContext(nullptr);
|
||||
|
@ -211,7 +210,8 @@ namespace MWVR
|
|||
OpenXRViewer::SwapBuffersCallback::swapBuffersImplementation(
|
||||
osg::GraphicsContext* gc)
|
||||
{
|
||||
MWBase::Environment::get().getXRSession()->swapBuffers(gc);
|
||||
auto* session = OpenXREnvironment::get().getSession();
|
||||
session->swapBuffers(gc);
|
||||
}
|
||||
|
||||
void OpenXRViewer::swapBuffers(osg::GraphicsContext* gc)
|
||||
|
@ -220,6 +220,9 @@ namespace MWVR
|
|||
if (!mConfigured)
|
||||
return;
|
||||
|
||||
auto* session = OpenXREnvironment::get().getSession();
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
|
||||
Timer timer("OpenXRViewer::SwapBuffers");
|
||||
|
||||
auto leftView = mViews["LeftEye"];
|
||||
|
@ -229,13 +232,13 @@ namespace MWVR
|
|||
rightView->swapBuffers(gc);
|
||||
timer.checkpoint("Views");
|
||||
|
||||
mCompositionLayerProjectionViews[0].pose = toXR(MWBase::Environment::get().getXRSession()->predictedPoses().eye[(int)TrackedSpace::STAGE][(int)Side::LEFT_HAND]);
|
||||
mCompositionLayerProjectionViews[1].pose = toXR(MWBase::Environment::get().getXRSession()->predictedPoses().eye[(int)TrackedSpace::STAGE][(int)Side::RIGHT_HAND]);
|
||||
mCompositionLayerProjectionViews[0].pose = toXR(session->predictedPoses().eye[(int)TrackedSpace::STAGE][(int)Side::LEFT_HAND]);
|
||||
mCompositionLayerProjectionViews[1].pose = toXR(session->predictedPoses().eye[(int)TrackedSpace::STAGE][(int)Side::RIGHT_HAND]);
|
||||
|
||||
timer.checkpoint("Poses");
|
||||
|
||||
// TODO: Keep track of these in the session too.
|
||||
auto stageViews = mXR->impl().getPredictedViews(mXR->impl().frameState().predictedDisplayTime, TrackedSpace::STAGE);
|
||||
auto stageViews = xr->impl().getPredictedViews(xr->impl().frameState().predictedDisplayTime, TrackedSpace::STAGE);
|
||||
mCompositionLayerProjectionViews[0].fov = stageViews[0].fov;
|
||||
mCompositionLayerProjectionViews[1].fov = stageViews[1].fov;
|
||||
timer.checkpoint("Fovs");
|
||||
|
@ -245,7 +248,7 @@ namespace MWVR
|
|||
{
|
||||
mLayer.reset(new XrCompositionLayerProjection);
|
||||
mLayer->type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
|
||||
mLayer->space = mXR->impl().mReferenceSpaceStage;
|
||||
mLayer->space = xr->impl().mReferenceSpaceStage;
|
||||
mLayer->viewCount = 2;
|
||||
mLayer->views = mCompositionLayerProjectionViews.data();
|
||||
}
|
||||
|
@ -260,13 +263,14 @@ namespace MWVR
|
|||
osg::GraphicsContext* gc)
|
||||
{
|
||||
OpenXRManager::RealizeOperation::operator()(gc);
|
||||
mViewer->realize(gc);
|
||||
|
||||
OpenXREnvironment::get().getViewer()->realize(gc);
|
||||
}
|
||||
|
||||
bool
|
||||
OpenXRViewer::RealizeOperation::realized()
|
||||
{
|
||||
return mViewer->realized();
|
||||
return OpenXREnvironment::get().getViewer()->realized();
|
||||
}
|
||||
|
||||
void OpenXRViewer::preDrawCallback(osg::RenderInfo& info)
|
||||
|
@ -277,10 +281,12 @@ namespace MWVR
|
|||
|
||||
if (name == "LeftEye")
|
||||
{
|
||||
if (mXR->sessionRunning())
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
auto* session = OpenXREnvironment::get().getSession();
|
||||
if (xr->sessionRunning())
|
||||
{
|
||||
mXR->beginFrame();
|
||||
auto& poses = MWBase::Environment::get().getXRSession()->predictedPoses();
|
||||
xr->beginFrame();
|
||||
auto& poses = session->predictedPoses();
|
||||
//auto menuPose = poses.head[(int)TrackedSpace::STAGE];
|
||||
//mViews["MenuView"]->setPredictedPose(menuPose);
|
||||
}
|
||||
|
@ -314,7 +320,8 @@ namespace MWVR
|
|||
return;
|
||||
}
|
||||
|
||||
auto session = MWBase::Environment::get().getXRSession();
|
||||
auto* xr = OpenXREnvironment::get().getManager();
|
||||
auto* session = OpenXREnvironment::get().getSession();
|
||||
auto& poses = session->predictedPoses();
|
||||
auto handPosesStage = poses.hands[(int)TrackedSpace::STAGE];
|
||||
int side = (int)Side::LEFT_HAND;
|
||||
|
@ -325,18 +332,18 @@ namespace MWVR
|
|||
|
||||
MWVR::Pose handStage = handPosesStage[side];
|
||||
MWVR::Pose headStage = poses.head[(int)TrackedSpace::STAGE];
|
||||
mXR->playerScale(handStage);
|
||||
mXR->playerScale(headStage);
|
||||
xr->playerScale(handStage);
|
||||
xr->playerScale(headStage);
|
||||
auto orientation = handStage.orientation;
|
||||
auto position = handStage.position - headStage.position;
|
||||
position = position * session->unitsPerMeter();
|
||||
position = position * OpenXREnvironment::get().unitsPerMeter();
|
||||
|
||||
auto camera = mViewer->getCamera();
|
||||
auto viewMatrix = camera->getViewMatrix();
|
||||
|
||||
|
||||
// Align orientation with the game world
|
||||
auto inputManager = MWBase::Environment::get().getXRInputManager();
|
||||
auto* inputManager = OpenXREnvironment::get().getInputManager();
|
||||
if (inputManager)
|
||||
{
|
||||
auto playerYaw = osg::Quat(-inputManager->mYaw, osg::Vec3d(0, 0, 1));
|
||||
|
@ -371,7 +378,7 @@ namespace MWVR
|
|||
if (hand_transform->getName() == "tracker r hand")
|
||||
offcenter.z() *= -1.;
|
||||
osg::Vec3 recenter = orientation * offcenter;
|
||||
position = position + recenter * session->unitsPerMeter();
|
||||
position = position + recenter * OpenXREnvironment::get().unitsPerMeter();
|
||||
|
||||
hand_transform->setAttitude(orientation);
|
||||
hand_transform->setPosition(position);
|
||||
|
|
|
@ -25,12 +25,11 @@ namespace MWVR
|
|||
class RealizeOperation : public OpenXRManager::RealizeOperation
|
||||
{
|
||||
public:
|
||||
RealizeOperation(osg::ref_ptr<OpenXRManager> XR, osg::ref_ptr<OpenXRViewer> viewer) : OpenXRManager::RealizeOperation(XR), mViewer(viewer) {};
|
||||
RealizeOperation() {};
|
||||
void operator()(osg::GraphicsContext* gc) override;
|
||||
bool realized() override;
|
||||
|
||||
private:
|
||||
osg::ref_ptr<OpenXRViewer> mViewer;
|
||||
};
|
||||
|
||||
class SwapBuffersCallback : public osg::GraphicsContext::SwapCallback
|
||||
|
@ -84,7 +83,6 @@ namespace MWVR
|
|||
|
||||
public:
|
||||
OpenXRViewer(
|
||||
osg::ref_ptr<OpenXRManager> XR,
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer);
|
||||
|
||||
~OpenXRViewer(void);
|
||||
|
@ -107,7 +105,6 @@ namespace MWVR
|
|||
|
||||
public:
|
||||
|
||||
osg::observer_ptr<OpenXRManager> mXR = nullptr;
|
||||
std::unique_ptr<XrCompositionLayerProjection> mLayer = nullptr;
|
||||
std::vector<XrCompositionLayerProjectionView> mCompositionLayerProjectionViews;
|
||||
osg::ref_ptr<OpenXRManager::RealizeOperation> mRealizeOperation = nullptr;
|
||||
|
@ -126,9 +123,6 @@ namespace MWVR
|
|||
std::mutex mMutex;
|
||||
|
||||
bool mConfigured{ false };
|
||||
|
||||
osg::ref_ptr<osg::Group> mMenusRoot{ new osg::Group };
|
||||
std::unique_ptr<OpenXRMenu> mMenus{ nullptr };
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "openxrworldview.hpp"
|
||||
#include "openxrenvironment.hpp"
|
||||
#include "openxrmanager.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
#include "../mwinput/inputmanagerimp.hpp"
|
||||
|
@ -99,7 +100,7 @@ namespace MWVR
|
|||
{
|
||||
MWVR::Pose pose = predictedPose();
|
||||
mXR->playerScale(pose);
|
||||
osg::Vec3 position = pose.position * mUnitsPerMeter;
|
||||
osg::Vec3 position = pose.position * OpenXREnvironment::get().unitsPerMeter();
|
||||
osg::Quat orientation = pose.orientation;
|
||||
|
||||
float y = position.y();
|
||||
|
@ -123,10 +124,8 @@ namespace MWVR
|
|||
osg::ref_ptr<OpenXRManager> XR,
|
||||
std::string name,
|
||||
osg::ref_ptr<osg::State> state,
|
||||
OpenXRSwapchain::Config config,
|
||||
float unitsPerMeter)
|
||||
OpenXRSwapchain::Config config)
|
||||
: OpenXRView(XR, name, config, state)
|
||||
, mUnitsPerMeter(unitsPerMeter)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -167,7 +166,7 @@ namespace MWVR
|
|||
// Updating the head pose needs to happen after waitFrame(),
|
||||
// But i can't call waitFrame from the input manager since it might
|
||||
// not always be active.
|
||||
auto inputManager = MWBase::Environment::get().getXRInputManager();
|
||||
auto* inputManager = OpenXREnvironment::get().getInputManager();
|
||||
if (inputManager)
|
||||
inputManager->updateHead();
|
||||
|
||||
|
@ -191,8 +190,5 @@ namespace MWVR
|
|||
camera->setViewMatrix(modifiedViewMatrix);
|
||||
camera->setProjectionMatrix(projectionMatrix);
|
||||
slave.updateSlaveImplementation(view);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,15 +26,13 @@ namespace MWVR
|
|||
};
|
||||
|
||||
public:
|
||||
OpenXRWorldView(osg::ref_ptr<OpenXRManager> XR, std::string name, osg::ref_ptr<osg::State> state, OpenXRSwapchain::Config config, float unitsPerMeter);
|
||||
OpenXRWorldView(osg::ref_ptr<OpenXRManager> XR, std::string name, osg::ref_ptr<osg::State> state, OpenXRSwapchain::Config config);
|
||||
~OpenXRWorldView();
|
||||
|
||||
//! Projection offset for this view
|
||||
osg::Matrix projectionMatrix();
|
||||
//! View offset for this view
|
||||
osg::Matrix viewMatrix();
|
||||
|
||||
float mUnitsPerMeter = 1.f;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue