mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-15 20:49:56 +00:00
More refactoring/cleanup
This commit is contained in:
parent
1cf97fd7ad
commit
df45ee1690
19 changed files with 253 additions and 230 deletions
|
@ -32,7 +32,7 @@ bool OpenXRAction::getFloat(XrPath subactionPath, float& value)
|
|||
getInfo.subactionPath = subactionPath;
|
||||
|
||||
XrActionStateFloat xrValue{ XR_TYPE_ACTION_STATE_FLOAT };
|
||||
CHECK_XRCMD(xrGetActionStateFloat(xr->impl().mSession, &getInfo, &xrValue));
|
||||
CHECK_XRCMD(xrGetActionStateFloat(xr->impl().xrSession(), &getInfo, &xrValue));
|
||||
|
||||
if (xrValue.isActive)
|
||||
value = xrValue.currentState;
|
||||
|
@ -47,7 +47,7 @@ bool OpenXRAction::getBool(XrPath subactionPath, bool& value)
|
|||
getInfo.subactionPath = subactionPath;
|
||||
|
||||
XrActionStateBoolean xrValue{ XR_TYPE_ACTION_STATE_BOOLEAN };
|
||||
CHECK_XRCMD(xrGetActionStateBoolean(xr->impl().mSession, &getInfo, &xrValue));
|
||||
CHECK_XRCMD(xrGetActionStateBoolean(xr->impl().xrSession(), &getInfo, &xrValue));
|
||||
|
||||
if (xrValue.isActive)
|
||||
value = xrValue.currentState;
|
||||
|
@ -63,7 +63,7 @@ bool OpenXRAction::getPoseIsActive(XrPath subactionPath)
|
|||
getInfo.subactionPath = subactionPath;
|
||||
|
||||
XrActionStatePose xrValue{ XR_TYPE_ACTION_STATE_POSE };
|
||||
CHECK_XRCMD(xrGetActionStatePose(xr->impl().mSession, &getInfo, &xrValue));
|
||||
CHECK_XRCMD(xrGetActionStatePose(xr->impl().xrSession(), &getInfo, &xrValue));
|
||||
|
||||
return xrValue.isActive;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ bool OpenXRAction::applyHaptics(XrPath subactionPath, float amplitude)
|
|||
XrHapticActionInfo hapticActionInfo{ XR_TYPE_HAPTIC_ACTION_INFO };
|
||||
hapticActionInfo.action = mAction;
|
||||
hapticActionInfo.subactionPath = subactionPath;
|
||||
CHECK_XRCMD(xrApplyHapticFeedback(xr->impl().mSession, &hapticActionInfo, (XrHapticBaseHeader*)&vibration));
|
||||
CHECK_XRCMD(xrApplyHapticFeedback(xr->impl().xrSession(), &hapticActionInfo, (XrHapticBaseHeader*)&vibration));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ OpenXRInput::OpenXRInput(const std::vector<SuggestedBindings>& suggestedBindings
|
|||
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().xrSession(), &attachInfo));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -144,7 +144,7 @@ OpenXRInput::createActionSet()
|
|||
strcpy_s(createInfo.actionSetName, "gameplay");
|
||||
strcpy_s(createInfo.localizedActionSetName, "Gameplay");
|
||||
createInfo.priority = 0;
|
||||
CHECK_XRCMD(xrCreateActionSet(xr->impl().mInstance, &createInfo, &actionSet));
|
||||
CHECK_XRCMD(xrCreateActionSet(xr->impl().xrInstance(), &createInfo, &actionSet));
|
||||
return actionSet;
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ void OpenXRInput::suggestBindings(const SuggestedBindings& mwSuggestedBindings)
|
|||
auto* xr = Environment::get().getManager();
|
||||
XrPath oculusTouchInteractionProfilePath;
|
||||
CHECK_XRCMD(
|
||||
xrStringToPath(xr->impl().mInstance, mwSuggestedBindings.controllerPath.c_str(), &oculusTouchInteractionProfilePath));
|
||||
xrStringToPath(xr->impl().xrInstance(), mwSuggestedBindings.controllerPath.c_str(), &oculusTouchInteractionProfilePath));
|
||||
|
||||
std::vector<XrActionSuggestedBinding> suggestedBindings =
|
||||
{
|
||||
|
@ -178,7 +178,7 @@ void OpenXRInput::suggestBindings(const SuggestedBindings& mwSuggestedBindings)
|
|||
xrSuggestedBindings.interactionProfile = oculusTouchInteractionProfilePath;
|
||||
xrSuggestedBindings.suggestedBindings = suggestedBindings.data();
|
||||
xrSuggestedBindings.countSuggestedBindings = (uint32_t)suggestedBindings.size();
|
||||
CHECK_XRCMD(xrSuggestInteractionProfileBindings(xr->impl().mInstance, &xrSuggestedBindings));
|
||||
CHECK_XRCMD(xrSuggestInteractionProfileBindings(xr->impl().xrInstance(), &xrSuggestedBindings));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -192,8 +192,8 @@ OpenXRInput::generateControllerActionPaths(
|
|||
std::string left = std::string("/user/hand/left") + controllerAction;
|
||||
std::string right = std::string("/user/hand/right") + controllerAction;
|
||||
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().mInstance, left.c_str(), &actionPaths[(int)Side::LEFT_SIDE]));
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().mInstance, right.c_str(), &actionPaths[(int)Side::RIGHT_SIDE]));
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().xrInstance(), left.c_str(), &actionPaths[(int)Side::LEFT_SIDE]));
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().xrInstance(), right.c_str(), &actionPaths[(int)Side::RIGHT_SIDE]));
|
||||
|
||||
mPathMap[actionPath] = actionPaths;
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ void
|
|||
OpenXRInput::updateControls()
|
||||
{
|
||||
auto* xr = Environment::get().getManager();
|
||||
if (!xr->impl().mSessionRunning)
|
||||
if (!xr->impl().xrSessionRunning())
|
||||
return;
|
||||
|
||||
|
||||
|
@ -229,7 +229,7 @@ OpenXRInput::updateControls()
|
|||
XrActionsSyncInfo syncInfo{ XR_TYPE_ACTIONS_SYNC_INFO };
|
||||
syncInfo.countActiveActionSets = 1;
|
||||
syncInfo.activeActionSets = &activeActionSet;
|
||||
CHECK_XRCMD(xrSyncActions(xr->impl().mSession, &syncInfo));
|
||||
CHECK_XRCMD(xrSyncActions(xr->impl().xrSession(), &syncInfo));
|
||||
|
||||
|
||||
// Note on update order:
|
||||
|
@ -246,7 +246,7 @@ XrPath OpenXRInput::generateXrPath(const std::string& path)
|
|||
{
|
||||
auto* xr = Environment::get().getManager();
|
||||
XrPath xrpath = 0;
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().mInstance, path.c_str(), &xrpath));
|
||||
CHECK_XRCMD(xrStringToPath(xr->impl().xrInstance(), path.c_str(), &xrpath));
|
||||
return xrpath;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,10 @@ namespace MWVR
|
|||
return !!mPrivate;
|
||||
}
|
||||
|
||||
bool OpenXRManager::sessionRunning()
|
||||
bool OpenXRManager::xrSessionRunning()
|
||||
{
|
||||
if (realized())
|
||||
return impl().mSessionRunning;
|
||||
return impl().xrSessionRunning();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -71,12 +71,6 @@ namespace MWVR
|
|||
return impl().endFrame(displayTime, layerCount, layerStack);
|
||||
}
|
||||
|
||||
void OpenXRManager::updateControls()
|
||||
{
|
||||
if (realized())
|
||||
return impl().updateControls();
|
||||
}
|
||||
|
||||
void
|
||||
OpenXRManager::realize(
|
||||
osg::GraphicsContext* gc)
|
||||
|
@ -97,13 +91,6 @@ namespace MWVR
|
|||
}
|
||||
}
|
||||
|
||||
int OpenXRManager::eyes()
|
||||
{
|
||||
if (realized())
|
||||
return impl().eyes();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OpenXRManager::enablePredictions()
|
||||
{
|
||||
return impl().enablePredictions();
|
||||
|
@ -114,21 +101,31 @@ namespace MWVR
|
|||
return impl().disablePredictions();
|
||||
}
|
||||
|
||||
std::array<View, 2> OpenXRManager::getPredictedViews(int64_t predictedDisplayTime, TrackedSpace space)
|
||||
std::array<View, 2> OpenXRManager::getPredictedViews(int64_t predictedDisplayTime, ReferenceSpace space)
|
||||
{
|
||||
return impl().getPredictedViews(predictedDisplayTime, space);
|
||||
}
|
||||
|
||||
MWVR::Pose OpenXRManager::getPredictedHeadPose(int64_t predictedDisplayTime, TrackedSpace space)
|
||||
MWVR::Pose OpenXRManager::getPredictedHeadPose(int64_t predictedDisplayTime, ReferenceSpace space)
|
||||
{
|
||||
return impl().getPredictedHeadPose(predictedDisplayTime, space);
|
||||
}
|
||||
|
||||
long long OpenXRManager::getLastPredictedDisplayTime()
|
||||
{
|
||||
return impl().getLastPredictedDisplayTime();
|
||||
}
|
||||
|
||||
long long OpenXRManager::getLastPredictedDisplayPeriod()
|
||||
{
|
||||
return impl().getLastPredictedDisplayPeriod();
|
||||
}
|
||||
|
||||
std::array<SwapchainConfig, 2> OpenXRManager::getRecommendedSwapchainConfig() const
|
||||
{
|
||||
return impl().getRecommendedSwapchainConfig();
|
||||
}
|
||||
|
||||
void
|
||||
OpenXRManager::RealizeOperation::operator()(
|
||||
osg::GraphicsContext* gc)
|
||||
|
|
|
@ -53,26 +53,47 @@ namespace MWVR
|
|||
|
||||
bool realized();
|
||||
|
||||
long long frameIndex();
|
||||
bool sessionRunning();
|
||||
|
||||
void handleEvents();
|
||||
//! Forward call to xrWaitFrame()
|
||||
void waitFrame();
|
||||
void beginFrame();
|
||||
void endFrame(int64_t displayTime, int layerCount, const std::array<CompositionLayerProjectionView, 2>& layerStack);
|
||||
void updateControls();
|
||||
|
||||
//! Forward call to xrBeginFrame()
|
||||
void beginFrame();
|
||||
|
||||
//! Forward call to xrEndFrame()
|
||||
void endFrame(int64_t displayTime, int layerCount, const std::array<CompositionLayerProjectionView, 2>& layerStack);
|
||||
|
||||
//! Whether the openxr session is currently in a running state
|
||||
bool xrSessionRunning();
|
||||
|
||||
//! Process all openxr events
|
||||
void handleEvents();
|
||||
|
||||
//! Instantiate implementation
|
||||
void realize(osg::GraphicsContext* gc);
|
||||
|
||||
int eyes();
|
||||
|
||||
//! Enable pose predictions. Exist to police that predictions are never made out of turn.
|
||||
void enablePredictions();
|
||||
|
||||
//! Disable pose predictions.
|
||||
void disablePredictions();
|
||||
std::array<View, 2> getPredictedViews(int64_t predictedDisplayTime, TrackedSpace space);
|
||||
MWVR::Pose getPredictedHeadPose(int64_t predictedDisplayTime, TrackedSpace space);
|
||||
|
||||
//! Get poses and fov of both eyes at the predicted time, relative to the given reference space. \note Will throw if predictions are disabled.
|
||||
std::array<View, 2> getPredictedViews(int64_t predictedDisplayTime, ReferenceSpace space);
|
||||
|
||||
//! Get the pose of the player's head at the predicted time, relative to the given reference space. \note Will throw if predictions are disabled.
|
||||
MWVR::Pose getPredictedHeadPose(int64_t predictedDisplayTime, ReferenceSpace space);
|
||||
|
||||
//! Last predicted display time returned from xrWaitFrame();
|
||||
long long getLastPredictedDisplayTime();
|
||||
|
||||
//! Last predicted display period returned from xrWaitFrame();
|
||||
long long getLastPredictedDisplayPeriod();
|
||||
|
||||
//! Configuration hints for instantiating swapchains, queried from openxr.
|
||||
std::array<SwapchainConfig, 2> getRecommendedSwapchainConfig() const;
|
||||
|
||||
OpenXRManagerImpl& impl() { return *mPrivate; }
|
||||
const OpenXRManagerImpl& impl() const { return *mPrivate; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<OpenXRManagerImpl> mPrivate;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "openxrmanagerimpl.hpp"
|
||||
#include "openxrswapchain.hpp"
|
||||
#include "openxrswapchainimpl.hpp"
|
||||
#include "vrtexture.hpp"
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
@ -173,6 +173,11 @@ namespace MWVR
|
|||
return res;
|
||||
}
|
||||
|
||||
std::string XrResultString(XrResult res)
|
||||
{
|
||||
return to_string(res);
|
||||
}
|
||||
|
||||
OpenXRManagerImpl::~OpenXRManagerImpl()
|
||||
{
|
||||
|
||||
|
@ -259,12 +264,6 @@ namespace MWVR
|
|||
Log(Debug::Verbose) << ss.str();
|
||||
}
|
||||
|
||||
XrFrameState OpenXRManagerImpl::frameState()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mFrameStateMutex);
|
||||
return mFrameState;
|
||||
}
|
||||
|
||||
void
|
||||
OpenXRManagerImpl::waitFrame()
|
||||
{
|
||||
|
@ -294,7 +293,7 @@ namespace MWVR
|
|||
{
|
||||
XrCompositionLayerProjectionView xrLayer;
|
||||
xrLayer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
||||
xrLayer.subImage = layer.swapchain->subImage();
|
||||
xrLayer.subImage = layer.swapchain->impl().xrSubImage();
|
||||
xrLayer.pose = toXR(layer.pose);
|
||||
xrLayer.fov = toXR(layer.fov);
|
||||
xrLayer.next = nullptr;
|
||||
|
@ -316,7 +315,7 @@ namespace MWVR
|
|||
compositionLayerProjectionViews[(int)Side::RIGHT_SIDE] = toXR(layerStack[(int)Side::RIGHT_SIDE]);
|
||||
XrCompositionLayerProjection layer{};
|
||||
layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
|
||||
layer.space = getReferenceSpace(TrackedSpace::STAGE);
|
||||
layer.space = getReferenceSpace(ReferenceSpace::STAGE);
|
||||
layer.viewCount = 2;
|
||||
layer.views = compositionLayerProjectionViews.data();
|
||||
auto* xrLayerStack = reinterpret_cast<XrCompositionLayerBaseHeader*>(&layer);
|
||||
|
@ -334,7 +333,7 @@ namespace MWVR
|
|||
std::array<View, 2>
|
||||
OpenXRManagerImpl::getPredictedViews(
|
||||
int64_t predictedDisplayTime,
|
||||
TrackedSpace space)
|
||||
ReferenceSpace space)
|
||||
{
|
||||
if (!mPredictionsEnabled)
|
||||
{
|
||||
|
@ -350,10 +349,10 @@ namespace MWVR
|
|||
viewLocateInfo.displayTime = predictedDisplayTime;
|
||||
switch (space)
|
||||
{
|
||||
case TrackedSpace::STAGE:
|
||||
case ReferenceSpace::STAGE:
|
||||
viewLocateInfo.space = mReferenceSpaceStage;
|
||||
break;
|
||||
case TrackedSpace::VIEW:
|
||||
case ReferenceSpace::VIEW:
|
||||
viewLocateInfo.space = mReferenceSpaceView;
|
||||
break;
|
||||
}
|
||||
|
@ -369,7 +368,7 @@ namespace MWVR
|
|||
|
||||
MWVR::Pose OpenXRManagerImpl::getPredictedHeadPose(
|
||||
int64_t predictedDisplayTime,
|
||||
TrackedSpace space)
|
||||
ReferenceSpace space)
|
||||
{
|
||||
if (!mPredictionsEnabled)
|
||||
{
|
||||
|
@ -382,10 +381,10 @@ namespace MWVR
|
|||
|
||||
switch (space)
|
||||
{
|
||||
case TrackedSpace::STAGE:
|
||||
case ReferenceSpace::STAGE:
|
||||
referenceSpace = mReferenceSpaceStage;
|
||||
break;
|
||||
case TrackedSpace::VIEW:
|
||||
case ReferenceSpace::VIEW:
|
||||
referenceSpace = mReferenceSpaceView;
|
||||
break;
|
||||
}
|
||||
|
@ -398,16 +397,11 @@ namespace MWVR
|
|||
location.pose.orientation.w = 1;
|
||||
}
|
||||
return MWVR::Pose{
|
||||
osg::fromXR(location.pose.position),
|
||||
osg::fromXR(location.pose.orientation)
|
||||
fromXR(location.pose.position),
|
||||
fromXR(location.pose.orientation)
|
||||
};
|
||||
}
|
||||
|
||||
int OpenXRManagerImpl::eyes()
|
||||
{
|
||||
return mConfigViews.size();
|
||||
}
|
||||
|
||||
void OpenXRManagerImpl::handleEvents()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mEventMutex);
|
||||
|
@ -435,9 +429,6 @@ namespace MWVR
|
|||
}
|
||||
}
|
||||
|
||||
void OpenXRManagerImpl::updateControls()
|
||||
{
|
||||
}
|
||||
void
|
||||
OpenXRManagerImpl::HandleSessionStateChanged(
|
||||
const XrEventDataSessionStateChanged& stateChangedEvent)
|
||||
|
@ -495,12 +486,12 @@ namespace MWVR
|
|||
|
||||
MWVR::Pose fromXR(XrPosef pose)
|
||||
{
|
||||
return MWVR::Pose{ osg::fromXR(pose.position), osg::fromXR(pose.orientation) };
|
||||
return MWVR::Pose{ fromXR(pose.position), fromXR(pose.orientation) };
|
||||
}
|
||||
|
||||
XrPosef toXR(MWVR::Pose pose)
|
||||
{
|
||||
return XrPosef{ osg::toXR(pose.orientation), osg::toXR(pose.position) };
|
||||
return XrPosef{ toXR(pose.orientation), toXR(pose.position) };
|
||||
}
|
||||
|
||||
MWVR::FieldOfView fromXR(XrFovf fov)
|
||||
|
@ -513,12 +504,12 @@ namespace MWVR
|
|||
return XrFovf{ fov.angleLeft, fov.angleRight, fov.angleUp, fov.angleDown };
|
||||
}
|
||||
|
||||
XrSpace OpenXRManagerImpl::getReferenceSpace(TrackedSpace space)
|
||||
XrSpace OpenXRManagerImpl::getReferenceSpace(ReferenceSpace space)
|
||||
{
|
||||
XrSpace referenceSpace = XR_NULL_HANDLE;
|
||||
if (space == TrackedSpace::STAGE)
|
||||
if (space == ReferenceSpace::STAGE)
|
||||
referenceSpace = mReferenceSpaceStage;
|
||||
if (space == TrackedSpace::VIEW)
|
||||
if (space == ReferenceSpace::VIEW)
|
||||
referenceSpace = mReferenceSpaceView;
|
||||
return referenceSpace;
|
||||
}
|
||||
|
@ -533,32 +524,48 @@ namespace MWVR
|
|||
mPredictionsEnabled = false;
|
||||
}
|
||||
|
||||
long long OpenXRManagerImpl::getLastPredictedDisplayTime()
|
||||
{
|
||||
return mFrameState.predictedDisplayTime;
|
||||
}
|
||||
|
||||
long long OpenXRManagerImpl::getLastPredictedDisplayPeriod()
|
||||
{
|
||||
return mFrameState.predictedDisplayPeriod;
|
||||
}
|
||||
}
|
||||
|
||||
namespace osg
|
||||
{
|
||||
|
||||
Vec3 fromXR(XrVector3f v)
|
||||
std::array<SwapchainConfig, 2> OpenXRManagerImpl::getRecommendedSwapchainConfig() const
|
||||
{
|
||||
return Vec3{ v.x, -v.z, v.y };
|
||||
std::array<SwapchainConfig, 2> config{};
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
config[i] = SwapchainConfig{
|
||||
mConfigViews[i].recommendedImageRectWidth,
|
||||
mConfigViews[i].maxImageRectWidth,
|
||||
mConfigViews[i].recommendedImageRectHeight,
|
||||
mConfigViews[i].maxImageRectHeight,
|
||||
mConfigViews[i].recommendedSwapchainSampleCount,
|
||||
mConfigViews[i].recommendedSwapchainSampleCount,
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
Quat fromXR(XrQuaternionf quat)
|
||||
osg::Vec3 fromXR(XrVector3f v)
|
||||
{
|
||||
return Quat{ quat.x, -quat.z, quat.y, quat.w };
|
||||
return osg::Vec3{ v.x, -v.z, v.y };
|
||||
}
|
||||
|
||||
XrVector3f toXR(Vec3 v)
|
||||
osg::Quat fromXR(XrQuaternionf quat)
|
||||
{
|
||||
return osg::Quat{ quat.x, -quat.z, quat.y, quat.w };
|
||||
}
|
||||
|
||||
XrVector3f toXR(osg::Vec3 v)
|
||||
{
|
||||
return XrVector3f{ v.x(), v.z(), -v.y() };
|
||||
}
|
||||
|
||||
XrQuaternionf toXR(Quat quat)
|
||||
XrQuaternionf toXR(osg::Quat quat)
|
||||
{
|
||||
return XrQuaternionf{ quat.x(), quat.z(), -quat.y(), quat.w() };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,82 +22,82 @@
|
|||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
namespace osg {
|
||||
Vec3 fromXR(XrVector3f);
|
||||
Quat fromXR(XrQuaternionf quat);
|
||||
XrVector3f toXR(Vec3 v);
|
||||
XrQuaternionf toXR(Quat quat);
|
||||
}
|
||||
|
||||
namespace MWVR
|
||||
{
|
||||
|
||||
// Error management macros and functions. Should be used on every openxr call.
|
||||
#define CHK_STRINGIFY(x) #x
|
||||
#define TOSTRING(x) CHK_STRINGIFY(x)
|
||||
#define FILE_AND_LINE __FILE__ ":" TOSTRING(__LINE__)
|
||||
#define CHECK_XRCMD(cmd) CheckXrResult(cmd, #cmd, FILE_AND_LINE);
|
||||
#define CHECK_XRRESULT(res, cmdStr) CheckXrResult(res, cmdStr, FILE_AND_LINE);
|
||||
XrResult CheckXrResult(XrResult res, const char* originator = nullptr, const char* sourceLocation = nullptr);
|
||||
std::string XrResultString(XrResult res);
|
||||
|
||||
XrResult CheckXrResult(XrResult res, const char* originator = nullptr, const char* sourceLocation = nullptr);
|
||||
MWVR::Pose fromXR(XrPosef pose);
|
||||
XrPosef toXR(MWVR::Pose pose);
|
||||
MWVR::FieldOfView fromXR(XrFovf fov);
|
||||
XrFovf toXR(MWVR::FieldOfView fov);
|
||||
/// Conversion methods from openxr types to osg/mwvr types. Includes managing the differing conventions.
|
||||
MWVR::Pose fromXR(XrPosef pose);
|
||||
MWVR::FieldOfView fromXR(XrFovf fov);
|
||||
osg::Vec3 fromXR(XrVector3f);
|
||||
osg::Quat fromXR(XrQuaternionf quat);
|
||||
|
||||
XrCompositionLayerProjectionView toXR(MWVR::CompositionLayerProjectionView layer);
|
||||
/// Conversion methods from osg/mwvr types to openxr types. Includes managing the differing conventions.
|
||||
XrPosef toXR(MWVR::Pose pose);
|
||||
XrFovf toXR(MWVR::FieldOfView fov);
|
||||
XrVector3f toXR(osg::Vec3 v);
|
||||
XrQuaternionf toXR(osg::Quat quat);
|
||||
|
||||
struct OpenXRManagerImpl
|
||||
{
|
||||
OpenXRManagerImpl(void);
|
||||
~OpenXRManagerImpl(void);
|
||||
XrCompositionLayerProjectionView toXR(MWVR::CompositionLayerProjectionView layer);
|
||||
|
||||
void LogLayersAndExtensions();
|
||||
void LogInstanceInfo();
|
||||
void LogReferenceSpaces();
|
||||
struct OpenXRManagerImpl
|
||||
{
|
||||
OpenXRManagerImpl(void);
|
||||
~OpenXRManagerImpl(void);
|
||||
|
||||
const XrEventDataBaseHeader* nextEvent();
|
||||
void waitFrame();
|
||||
void beginFrame();
|
||||
void endFrame(int64_t displayTime, int layerCount, const std::array<CompositionLayerProjectionView, 2>& layerStack);
|
||||
std::array<View, 2> getPredictedViews(int64_t predictedDisplayTime, TrackedSpace space);
|
||||
MWVR::Pose getPredictedHeadPose(int64_t predictedDisplayTime, TrackedSpace space);
|
||||
int eyes();
|
||||
void handleEvents();
|
||||
void updateControls();
|
||||
void HandleSessionStateChanged(const XrEventDataSessionStateChanged& stateChangedEvent);
|
||||
XrFrameState frameState();
|
||||
XrSpace getReferenceSpace(TrackedSpace space);
|
||||
void enablePredictions();
|
||||
void disablePredictions();
|
||||
long long getLastPredictedDisplayPeriod();
|
||||
void waitFrame();
|
||||
void beginFrame();
|
||||
void endFrame(int64_t displayTime, int layerCount, const std::array<CompositionLayerProjectionView, 2>& layerStack);
|
||||
bool xrSessionRunning() const { return mSessionRunning; }
|
||||
std::array<View, 2> getPredictedViews(int64_t predictedDisplayTime, ReferenceSpace space);
|
||||
MWVR::Pose getPredictedHeadPose(int64_t predictedDisplayTime, ReferenceSpace space);
|
||||
void handleEvents();
|
||||
void enablePredictions();
|
||||
void disablePredictions();
|
||||
long long getLastPredictedDisplayTime();
|
||||
long long getLastPredictedDisplayPeriod();
|
||||
std::array<SwapchainConfig, 2> getRecommendedSwapchainConfig() const;
|
||||
XrSpace getReferenceSpace(ReferenceSpace space);
|
||||
XrSession xrSession() const { return mSession; };
|
||||
XrInstance xrInstance() const { return mInstance; };
|
||||
|
||||
bool initialized = false;
|
||||
bool mPredictionsEnabled = false;
|
||||
XrInstance mInstance = XR_NULL_HANDLE;
|
||||
XrSession mSession = XR_NULL_HANDLE;
|
||||
XrSpace mSpace = XR_NULL_HANDLE;
|
||||
XrFormFactor mFormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
|
||||
XrViewConfigurationType mViewConfigType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
|
||||
XrEnvironmentBlendMode mEnvironmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
|
||||
XrSystemId mSystemId = XR_NULL_SYSTEM_ID;
|
||||
XrGraphicsBindingOpenGLWin32KHR mGraphicsBinding{ XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR };
|
||||
XrSystemProperties mSystemProperties{ XR_TYPE_SYSTEM_PROPERTIES };
|
||||
std::array<XrViewConfigurationView, 2> mConfigViews{ { {XR_TYPE_VIEW_CONFIGURATION_VIEW}, {XR_TYPE_VIEW_CONFIGURATION_VIEW} } };
|
||||
XrSpace mReferenceSpaceView = XR_NULL_HANDLE;
|
||||
XrSpace mReferenceSpaceStage = XR_NULL_HANDLE;
|
||||
XrEventDataBuffer mEventDataBuffer{ XR_TYPE_EVENT_DATA_BUFFER };
|
||||
XrFrameState mFrameState{};
|
||||
XrSessionState mSessionState = XR_SESSION_STATE_UNKNOWN;
|
||||
bool mSessionRunning = false;
|
||||
std::mutex mFrameStateMutex{};
|
||||
std::mutex mEventMutex{};
|
||||
protected:
|
||||
void LogLayersAndExtensions();
|
||||
void LogInstanceInfo();
|
||||
void LogReferenceSpaces();
|
||||
const XrEventDataBaseHeader* nextEvent();
|
||||
void HandleSessionStateChanged(const XrEventDataSessionStateChanged& stateChangedEvent);
|
||||
|
||||
XrActionSet mActionSet = nullptr;
|
||||
XrAction mHandPoseAction = nullptr;
|
||||
XrSpace mHandSpaces[2]{ nullptr, nullptr };
|
||||
XrPath mSubactionPaths[2]{ 0, 0 };
|
||||
XrPath mPosePath[2]{ 0, 0 };
|
||||
};
|
||||
private:
|
||||
bool initialized = false;
|
||||
bool mPredictionsEnabled = false;
|
||||
XrInstance mInstance = XR_NULL_HANDLE;
|
||||
XrSession mSession = XR_NULL_HANDLE;
|
||||
XrSpace mSpace = XR_NULL_HANDLE;
|
||||
XrFormFactor mFormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
|
||||
XrViewConfigurationType mViewConfigType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
|
||||
XrEnvironmentBlendMode mEnvironmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
|
||||
XrSystemId mSystemId = XR_NULL_SYSTEM_ID;
|
||||
XrGraphicsBindingOpenGLWin32KHR mGraphicsBinding{ XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR };
|
||||
XrSystemProperties mSystemProperties{ XR_TYPE_SYSTEM_PROPERTIES };
|
||||
std::array<XrViewConfigurationView, 2> mConfigViews{ { {XR_TYPE_VIEW_CONFIGURATION_VIEW}, {XR_TYPE_VIEW_CONFIGURATION_VIEW} } };
|
||||
XrSpace mReferenceSpaceView = XR_NULL_HANDLE;
|
||||
XrSpace mReferenceSpaceStage = XR_NULL_HANDLE;
|
||||
XrEventDataBuffer mEventDataBuffer{ XR_TYPE_EVENT_DATA_BUFFER };
|
||||
XrFrameState mFrameState{};
|
||||
XrSessionState mSessionState = XR_SESSION_STATE_UNKNOWN;
|
||||
bool mSessionRunning = false;
|
||||
std::mutex mFrameStateMutex{};
|
||||
std::mutex mEventMutex{};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace MWVR {
|
|||
SUBVIEW_MAX = RIGHT_VIEW, //!< Used to size subview arrays. Not a valid input.
|
||||
};
|
||||
|
||||
OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, OpenXRSwapchain::Config config);
|
||||
OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, SwapchainConfig config);
|
||||
~OpenXRSwapchainImpl();
|
||||
|
||||
void beginFrame(osg::GraphicsContext* gc);
|
||||
|
@ -53,10 +53,10 @@ namespace MWVR {
|
|||
bool mIsAcquired{ false };
|
||||
};
|
||||
|
||||
OpenXRSwapchainImpl::OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, OpenXRSwapchain::Config config)
|
||||
: mWidth(config.width)
|
||||
, mHeight(config.height)
|
||||
, mSamples(config.samples)
|
||||
OpenXRSwapchainImpl::OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, SwapchainConfig config)
|
||||
: mWidth(config.recommendedWidth)
|
||||
, mHeight(config.recommendedHeight)
|
||||
, mSamples(config.recommendedSamples)
|
||||
{
|
||||
if (mWidth <= 0)
|
||||
throw std::invalid_argument("Width must be a positive integer");
|
||||
|
@ -69,9 +69,9 @@ namespace MWVR {
|
|||
|
||||
// Select a swapchain format.
|
||||
uint32_t swapchainFormatCount;
|
||||
CHECK_XRCMD(xrEnumerateSwapchainFormats(xr->impl().mSession, 0, &swapchainFormatCount, nullptr));
|
||||
CHECK_XRCMD(xrEnumerateSwapchainFormats(xr->impl().xrSession(), 0, &swapchainFormatCount, nullptr));
|
||||
std::vector<int64_t> swapchainFormats(swapchainFormatCount);
|
||||
CHECK_XRCMD(xrEnumerateSwapchainFormats(xr->impl().mSession, (uint32_t)swapchainFormats.size(), &swapchainFormatCount, swapchainFormats.data()));
|
||||
CHECK_XRCMD(xrEnumerateSwapchainFormats(xr->impl().xrSession(), (uint32_t)swapchainFormats.size(), &swapchainFormatCount, swapchainFormats.data()));
|
||||
|
||||
// List of supported color swapchain formats.
|
||||
constexpr int64_t SupportedColorSwapchainFormats[] = {
|
||||
|
@ -100,7 +100,7 @@ namespace MWVR {
|
|||
swapchainCreateInfo.faceCount = 1;
|
||||
swapchainCreateInfo.sampleCount = mSamples;
|
||||
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
CHECK_XRCMD(xrCreateSwapchain(xr->impl().mSession, &swapchainCreateInfo, &mSwapchain));
|
||||
CHECK_XRCMD(xrCreateSwapchain(xr->impl().xrSession(), &swapchainCreateInfo, &mSwapchain));
|
||||
|
||||
uint32_t imageCount = 0;
|
||||
CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, 0, &imageCount, nullptr));
|
||||
|
@ -176,7 +176,7 @@ namespace MWVR {
|
|||
CHECK_XRCMD(xrReleaseSwapchainImage(mSwapchain, &releaseInfo));
|
||||
}
|
||||
|
||||
OpenXRSwapchain::OpenXRSwapchain(osg::ref_ptr<osg::State> state, OpenXRSwapchain::Config config)
|
||||
OpenXRSwapchain::OpenXRSwapchain(osg::ref_ptr<osg::State> state, SwapchainConfig config)
|
||||
: mPrivate(new OpenXRSwapchainImpl(state, config))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace MWVR
|
|||
};
|
||||
|
||||
public:
|
||||
OpenXRSwapchain(osg::ref_ptr<osg::State> state, Config config);
|
||||
OpenXRSwapchain(osg::ref_ptr<osg::State> state, SwapchainConfig config);
|
||||
~OpenXRSwapchain();
|
||||
|
||||
public:
|
||||
|
|
|
@ -31,7 +31,7 @@ PoseAction::PoseAction(std::unique_ptr<OpenXRAction> xrAction)
|
|||
createInfo.action = *mXRAction;
|
||||
createInfo.poseInActionSpace.orientation.w = 1.f;
|
||||
createInfo.subactionPath = XR_NULL_PATH;
|
||||
CHECK_XRCMD(xrCreateActionSpace(xr->impl().mSession, &createInfo, &mXRSpace));
|
||||
CHECK_XRCMD(xrCreateActionSpace(xr->impl().xrSession(), &createInfo, &mXRSpace));
|
||||
}
|
||||
|
||||
void PoseAction::update(long long time)
|
||||
|
@ -39,7 +39,7 @@ void PoseAction::update(long long time)
|
|||
mPrevious = mValue;
|
||||
|
||||
auto* xr = Environment::get().getManager();
|
||||
XrSpace referenceSpace = xr->impl().getReferenceSpace(TrackedSpace::STAGE);
|
||||
XrSpace referenceSpace = xr->impl().getReferenceSpace(ReferenceSpace::STAGE);
|
||||
|
||||
XrSpaceLocation location{ XR_TYPE_SPACE_LOCATION };
|
||||
XrSpaceVelocity velocity{ XR_TYPE_SPACE_VELOCITY };
|
||||
|
@ -51,8 +51,8 @@ void PoseAction::update(long long time)
|
|||
location.pose.orientation.w = 1;
|
||||
|
||||
mValue = Pose{
|
||||
osg::fromXR(location.pose.position),
|
||||
osg::fromXR(location.pose.orientation)
|
||||
fromXR(location.pose.position),
|
||||
fromXR(location.pose.orientation)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ osg::Matrix VRSession::viewMatrix(FramePhase phase, Side side)
|
|||
|
||||
bool VRSession::isRunning() const {
|
||||
auto* xr = Environment::get().getManager();
|
||||
return xr->sessionRunning();
|
||||
return xr->xrSessionRunning();
|
||||
}
|
||||
|
||||
void VRSession::swapBuffers(osg::GraphicsContext* gc, VRViewer& viewer)
|
||||
|
@ -254,13 +254,13 @@ void VRSession::prepareFrame()
|
|||
PoseSet predictedPoses{};
|
||||
|
||||
xr->enablePredictions();
|
||||
predictedPoses.head = xr->getPredictedHeadPose(predictedDisplayTime, TrackedSpace::STAGE) * mPlayerScale;
|
||||
auto hmdViews = xr->getPredictedViews(predictedDisplayTime, TrackedSpace::VIEW);
|
||||
predictedPoses.head = xr->getPredictedHeadPose(predictedDisplayTime, ReferenceSpace::STAGE) * mPlayerScale;
|
||||
auto hmdViews = xr->getPredictedViews(predictedDisplayTime, ReferenceSpace::VIEW);
|
||||
predictedPoses.view[(int)Side::LEFT_SIDE].pose = hmdViews[(int)Side::LEFT_SIDE].pose * mPlayerScale;
|
||||
predictedPoses.view[(int)Side::RIGHT_SIDE].pose = hmdViews[(int)Side::RIGHT_SIDE].pose * mPlayerScale;
|
||||
predictedPoses.view[(int)Side::LEFT_SIDE].fov = hmdViews[(int)Side::LEFT_SIDE].fov;
|
||||
predictedPoses.view[(int)Side::RIGHT_SIDE].fov = hmdViews[(int)Side::RIGHT_SIDE].fov;
|
||||
auto stageViews = xr->getPredictedViews(predictedDisplayTime, TrackedSpace::STAGE);
|
||||
auto stageViews = xr->getPredictedViews(predictedDisplayTime, ReferenceSpace::STAGE);
|
||||
predictedPoses.eye[(int)Side::LEFT_SIDE] = stageViews[(int)Side::LEFT_SIDE].pose * mPlayerScale;
|
||||
predictedPoses.eye[(int)Side::RIGHT_SIDE] = stageViews[(int)Side::RIGHT_SIDE].pose * mPlayerScale;
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace MWVR
|
|||
|
||||
extern void getEulerAngles(const osg::Quat& quat, float& yaw, float& pitch, float& roll);
|
||||
|
||||
//! Manages VR logic, such as managing frames, predicting their poses, and handling frame synchronization.
|
||||
//! Should not be confused with the openxr session object.
|
||||
class VRSession
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -13,52 +13,56 @@
|
|||
|
||||
namespace MWVR
|
||||
{
|
||||
VRTexture::VRTexture(
|
||||
osg::ref_ptr<osg::State> state,
|
||||
std::size_t width,
|
||||
std::size_t height,
|
||||
uint32_t msaaSamples)
|
||||
|
||||
VRTexture::VRTexture(osg::ref_ptr<osg::State> state, std::size_t width, std::size_t height, uint32_t msaaSamples, uint32_t colorBuffer, uint32_t depthBuffer)
|
||||
: mState(state)
|
||||
, mWidth(width)
|
||||
, mHeight(height)
|
||||
, mSamples(msaaSamples)
|
||||
, mColorBuffer(colorBuffer)
|
||||
, mDepthBuffer(depthBuffer)
|
||||
{
|
||||
|
||||
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
||||
|
||||
gl->glGenFramebuffers(1, &mBlitFBO);
|
||||
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, mBlitFBO);
|
||||
|
||||
gl->glGenFramebuffers(1, &mFBO);
|
||||
glGenTextures(1, &mDepthBuffer);
|
||||
glGenTextures(1, &mColorBuffer);
|
||||
|
||||
if (mSamples == 0)
|
||||
if (mSamples <= 1)
|
||||
mTextureTarget = GL_TEXTURE_2D;
|
||||
else
|
||||
mTextureTarget = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
|
||||
glBindTexture(mTextureTarget, mColorBuffer);
|
||||
if (mSamples == 0)
|
||||
glTexImage2D(mTextureTarget, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_INT, nullptr);
|
||||
else
|
||||
gl->glTexImage2DMultisample(mTextureTarget, mSamples, GL_RGBA, mWidth, mHeight, false);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_ARB);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_ARB);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
if (mColorBuffer == 0)
|
||||
{
|
||||
glGenTextures(1, &mColorBuffer);
|
||||
glBindTexture(mTextureTarget, mColorBuffer);
|
||||
if (mSamples <= 1)
|
||||
glTexImage2D(mTextureTarget, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_INT, nullptr);
|
||||
else
|
||||
gl->glTexImage2DMultisample(mTextureTarget, mSamples, GL_RGBA, mWidth, mHeight, false);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_ARB);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_ARB);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
}
|
||||
|
||||
glBindTexture(mTextureTarget, mDepthBuffer);
|
||||
if (mSamples == 0)
|
||||
glTexImage2D(mTextureTarget, 0, GL_DEPTH_COMPONENT24, mWidth, mHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||
else
|
||||
gl->glTexImage2DMultisample(mTextureTarget, mSamples, GL_DEPTH_COMPONENT, mWidth, mHeight, false);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
if (mDepthBuffer == 0)
|
||||
{
|
||||
glGenTextures(1, &mDepthBuffer);
|
||||
glBindTexture(mTextureTarget, mDepthBuffer);
|
||||
if (mSamples <= 1)
|
||||
glTexImage2D(mTextureTarget, 0, GL_DEPTH_COMPONENT24, mWidth, mHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||
else
|
||||
gl->glTexImage2DMultisample(mTextureTarget, mSamples, GL_DEPTH_COMPONENT, mWidth, mHeight, false);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(mTextureTarget, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
}
|
||||
|
||||
|
||||
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace MWVR
|
|||
class VRTexture : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
VRTexture(osg::ref_ptr<osg::State> state, std::size_t width, std::size_t height, uint32_t msaaSamples);
|
||||
VRTexture(osg::ref_ptr<osg::State> state, std::size_t width, std::size_t height, uint32_t msaaSamples, uint32_t colorBuffer = 0, uint32_t depthBuffer = 0);
|
||||
~VRTexture();
|
||||
|
||||
void destroy(osg::State* state);
|
||||
|
|
|
@ -172,13 +172,13 @@ std::ostream& operator <<(
|
|||
|
||||
std::ostream& operator <<(
|
||||
std::ostream& os,
|
||||
TrackedSpace limb)
|
||||
ReferenceSpace limb)
|
||||
{
|
||||
switch (limb)
|
||||
{
|
||||
case TrackedSpace::STAGE:
|
||||
case ReferenceSpace::STAGE:
|
||||
os << "STAGE"; break;
|
||||
case TrackedSpace::VIEW:
|
||||
case ReferenceSpace::VIEW:
|
||||
os << "VIEW"; break;
|
||||
}
|
||||
return os;
|
||||
|
|
|
@ -24,7 +24,7 @@ enum class TrackedLimb
|
|||
};
|
||||
|
||||
//! Describes what space to track the limb in
|
||||
enum class TrackedSpace
|
||||
enum class ReferenceSpace
|
||||
{
|
||||
STAGE = 0, //!< Track limb in the VR stage space. Meaning a space with a floor level origin and fixed horizontal orientation.
|
||||
VIEW = 1 //!< Track limb in the VR view space. Meaning a space with the head as origin and orientation.
|
||||
|
@ -58,7 +58,7 @@ struct Pose
|
|||
bool operator==(const Pose& rhs) const;
|
||||
};
|
||||
|
||||
//! Represents the field of view of an eye
|
||||
//! Fov of a single eye
|
||||
struct FieldOfView {
|
||||
float angleLeft;
|
||||
float angleRight;
|
||||
|
@ -97,13 +97,23 @@ struct CompositionLayerProjectionView
|
|||
FieldOfView fov;
|
||||
};
|
||||
|
||||
struct SwapchainConfig
|
||||
{
|
||||
uint32_t recommendedWidth = -1;
|
||||
uint32_t maxWidth = -1;
|
||||
uint32_t recommendedHeight = -1;
|
||||
uint32_t maxHeight = -1;
|
||||
uint32_t recommendedSamples = -1;
|
||||
uint32_t maxSamples = -1;
|
||||
};
|
||||
|
||||
// Serialization methods for VR types.
|
||||
std::ostream& operator <<(std::ostream& os, const Pose& pose);
|
||||
std::ostream& operator <<(std::ostream& os, const FieldOfView& fov);
|
||||
std::ostream& operator <<(std::ostream& os, const View& view);
|
||||
std::ostream& operator <<(std::ostream& os, const PoseSet& poseSet);
|
||||
std::ostream& operator <<(std::ostream& os, TrackedLimb limb);
|
||||
std::ostream& operator <<(std::ostream& os, TrackedSpace space);
|
||||
std::ostream& operator <<(std::ostream& os, ReferenceSpace space);
|
||||
std::ostream& operator <<(std::ostream& os, Side side);
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace MWVR {
|
|||
|
||||
VRView::VRView(
|
||||
std::string name,
|
||||
OpenXRSwapchain::Config config,
|
||||
SwapchainConfig config,
|
||||
osg::ref_ptr<osg::State> state)
|
||||
: mSwapchainConfig{ config }
|
||||
, mSwapchain(new OpenXRSwapchain(state, mSwapchainConfig))
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace MWVR
|
|||
};
|
||||
|
||||
public:
|
||||
VRView(std::string name, OpenXRSwapchain::Config config, osg::ref_ptr<osg::State> state);
|
||||
VRView(std::string name, SwapchainConfig config, osg::ref_ptr<osg::State> state);
|
||||
virtual ~VRView();
|
||||
|
||||
public:
|
||||
|
@ -52,7 +52,7 @@ namespace MWVR
|
|||
void swapBuffers(osg::GraphicsContext* gc);
|
||||
|
||||
public:
|
||||
OpenXRSwapchain::Config mSwapchainConfig;
|
||||
SwapchainConfig mSwapchainConfig;
|
||||
std::unique_ptr<OpenXRSwapchain> mSwapchain;
|
||||
std::string mName{};
|
||||
bool mRendering{ false };
|
||||
|
|
|
@ -67,17 +67,10 @@ namespace MWVR
|
|||
|
||||
xr->handleEvents();
|
||||
|
||||
OpenXRSwapchain::Config leftConfig;
|
||||
leftConfig.width = xr->impl().mConfigViews[(int)Side::LEFT_SIDE].recommendedImageRectWidth;
|
||||
leftConfig.height = xr->impl().mConfigViews[(int)Side::LEFT_SIDE].recommendedImageRectHeight;
|
||||
leftConfig.samples = xr->impl().mConfigViews[(int)Side::LEFT_SIDE].recommendedSwapchainSampleCount;
|
||||
OpenXRSwapchain::Config rightConfig;
|
||||
rightConfig.width = xr->impl().mConfigViews[(int)Side::RIGHT_SIDE].recommendedImageRectWidth;
|
||||
rightConfig.height = xr->impl().mConfigViews[(int)Side::RIGHT_SIDE].recommendedImageRectHeight;
|
||||
rightConfig.samples = xr->impl().mConfigViews[(int)Side::RIGHT_SIDE].recommendedSwapchainSampleCount;
|
||||
auto config = xr->getRecommendedSwapchainConfig();
|
||||
|
||||
auto leftView = new VRView("LeftEye", leftConfig, context->getState());
|
||||
auto rightView = new VRView("RightEye", rightConfig, context->getState());
|
||||
auto leftView = new VRView("LeftEye", config[(int)Side::LEFT_SIDE], context->getState());
|
||||
auto rightView = new VRView("RightEye", config[(int)Side::RIGHT_SIDE], context->getState());
|
||||
|
||||
mViews["LeftEye"] = leftView;
|
||||
mViews["RightEye"] = rightView;
|
||||
|
@ -118,15 +111,7 @@ namespace MWVR
|
|||
|
||||
mViewer->setReleaseContextAtEndOfFrameHint(false);
|
||||
|
||||
|
||||
OpenXRSwapchain::Config config;
|
||||
config.width = mainCamera->getViewport()->width();
|
||||
config.height = mainCamera->getViewport()->height();
|
||||
config.samples = 1;
|
||||
|
||||
// Mirror texture doesn't have to be an OpenXR swapchain.
|
||||
// It was just convenient at the time.
|
||||
mMirrorTextureSwapchain.reset(new OpenXRSwapchain(context->getState(), config));
|
||||
mMirrorTexture.reset(new VRTexture(context->getState(), mainCamera->getViewport()->width(), mainCamera->getViewport()->height(), 0));
|
||||
|
||||
mViewer->getSlave(0)._updateSlaveCallback = new VRView::UpdateSlaveCallback(leftView, context);
|
||||
mViewer->getSlave(1)._updateSlaveCallback = new VRView::UpdateSlaveCallback(rightView, context);
|
||||
|
@ -151,18 +136,16 @@ namespace MWVR
|
|||
|
||||
void VRViewer::blitEyesToMirrorTexture(osg::GraphicsContext* gc)
|
||||
{
|
||||
int mirror_width = mMirrorTextureSwapchain->width() / 2;
|
||||
mMirrorTextureSwapchain->beginFrame(gc);
|
||||
|
||||
mViews["RightEye"]->swapchain().renderBuffer()->blit(gc, 0, 0, mirror_width, mMirrorTextureSwapchain->height());
|
||||
mViews["LeftEye"]->swapchain().renderBuffer()->blit(gc, mirror_width, 0, 2 * mirror_width, mMirrorTextureSwapchain->height());
|
||||
|
||||
mMirrorTextureSwapchain->endFrame(gc);
|
||||
|
||||
auto* state = gc->getState();
|
||||
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
||||
int mirror_width = mMirrorTexture->width() / 2;
|
||||
mMirrorTexture->beginFrame(gc);
|
||||
|
||||
mViews["RightEye"]->swapchain().renderBuffer()->blit(gc, 0, 0, mirror_width, mMirrorTexture->height());
|
||||
mViews["LeftEye"]->swapchain().renderBuffer()->blit(gc, mirror_width, 0, 2 * mirror_width, mMirrorTexture->height());
|
||||
|
||||
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||
mMirrorTextureSwapchain->renderBuffer()->blit(gc, 0, 0, mMirrorTextureSwapchain->width(), mMirrorTextureSwapchain->height());
|
||||
mMirrorTexture->blit(gc, 0, 0, mMirrorTexture->width(), mMirrorTexture->height());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -91,8 +91,7 @@ namespace MWVR
|
|||
osg::ref_ptr<PredrawCallback> mPreDraw{ nullptr };
|
||||
osg::ref_ptr<PostdrawCallback> mPostDraw{ nullptr };
|
||||
osg::GraphicsContext* mMainCameraGC{ nullptr };
|
||||
|
||||
std::unique_ptr<OpenXRSwapchain> mMirrorTextureSwapchain{ nullptr };
|
||||
std::unique_ptr<VRTexture> mMirrorTexture{ nullptr };
|
||||
|
||||
std::mutex mMutex;
|
||||
|
||||
|
|
Loading…
Reference in a new issue