1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-20 00:23:51 +00:00

More accurate interpretation of openxr session states

This commit is contained in:
Mads Buvik Sandvei 2020-10-18 14:22:03 +02:00
parent cf20faff21
commit 6425749b7e
8 changed files with 187 additions and 151 deletions

View file

@ -179,7 +179,7 @@ namespace MWVR
OpenXRActionSet::updateControls() OpenXRActionSet::updateControls()
{ {
auto* xr = Environment::get().getManager(); auto* xr = Environment::get().getManager();
if (!xr->impl().xrSessionRunning()) if (!xr->impl().appShouldReadInput())
return; return;
const XrActiveActionSet activeActionSet{ mActionSet, XR_NULL_PATH }; const XrActiveActionSet activeActionSet{ mActionSet, XR_NULL_PATH };

View file

@ -21,25 +21,11 @@ namespace MWVR
} }
bool bool
OpenXRManager::realized() OpenXRManager::realized() const
{ {
return !!mPrivate; return !!mPrivate;
} }
bool OpenXRManager::xrSessionRunning()
{
if (realized())
return impl().xrSessionRunning();
return false;
}
bool OpenXRManager::xrSessionCanRender()
{
if (realized())
return impl().xrSessionCanRender();
return false;
}
void OpenXRManager::handleEvents() void OpenXRManager::handleEvents()
{ {
if (realized()) if (realized())
@ -56,9 +42,30 @@ namespace MWVR
return impl().beginFrame(); return impl().beginFrame();
} }
void OpenXRManager::endFrame(FrameInfo frameInfo, int layerCount, const std::array<CompositionLayerProjectionView, 2>& layerStack) void OpenXRManager::endFrame(FrameInfo frameInfo, const std::array<CompositionLayerProjectionView, 2>* layerStack)
{ {
return impl().endFrame(frameInfo, layerCount, layerStack); return impl().endFrame(frameInfo, layerStack);
}
bool OpenXRManager::appShouldSyncFrameLoop() const
{
if (realized())
return impl().appShouldSyncFrameLoop();
return false;
}
bool OpenXRManager::appShouldRender() const
{
if (realized())
return impl().appShouldRender();
return false;
}
bool OpenXRManager::appShouldReadInput() const
{
if (realized())
return impl().appShouldReadInput();
return false;
} }
void void

View file

@ -42,7 +42,7 @@ namespace MWVR
~OpenXRManager(); ~OpenXRManager();
/// Manager has been initialized. /// Manager has been initialized.
bool realized(); bool realized() const;
//! Forward call to xrWaitFrame() //! Forward call to xrWaitFrame()
FrameInfo waitFrame(); FrameInfo waitFrame();
@ -51,13 +51,16 @@ namespace MWVR
void beginFrame(); void beginFrame();
//! Forward call to xrEndFrame() //! Forward call to xrEndFrame()
void endFrame(FrameInfo frameInfo, int layerCount, const std::array<CompositionLayerProjectionView, 2>& layerStack); void endFrame(FrameInfo frameInfo, const std::array<CompositionLayerProjectionView, 2>* layerStack);
//! Whether the openxr session is currently in a running state //! Whether the app should call the openxr frame sync functions ( xr*Frame() )
bool xrSessionRunning(); bool appShouldSyncFrameLoop() const;
//! Whether frames can be rendered in the current state //! Whether the app should render anything.
bool xrSessionCanRender(); bool appShouldRender() const;
//! Whether the session is focused and can read input
bool appShouldReadInput() const;
//! Process all openxr events //! Process all openxr events
void handleEvents(); void handleEvents();

View file

@ -474,41 +474,41 @@ namespace MWVR
} }
void void
OpenXRManagerImpl::endFrame(FrameInfo frameInfo, int layerCount, const std::array<CompositionLayerProjectionView, 2>& layerStack) OpenXRManagerImpl::endFrame(FrameInfo frameInfo, const std::array<CompositionLayerProjectionView, 2>* layerStack)
{ {
std::array<XrCompositionLayerProjectionView, 2> compositionLayerProjectionViews{};
compositionLayerProjectionViews[(int)Side::LEFT_SIDE] = toXR(layerStack[(int)Side::LEFT_SIDE]);
compositionLayerProjectionViews[(int)Side::RIGHT_SIDE] = toXR(layerStack[(int)Side::RIGHT_SIDE]);
XrCompositionLayerProjection layer{};
layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
layer.space = getReferenceSpace(ReferenceSpace::STAGE);
layer.viewCount = 2;
layer.views = compositionLayerProjectionViews.data();
auto* xrLayerStack = reinterpret_cast<XrCompositionLayerBaseHeader*>(&layer);
std::array<XrCompositionLayerDepthInfoKHR, 2> compositionLayerDepth = mLayerDepth;
if (xrExtensionIsEnabled(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME))
{
auto farClip = Settings::Manager::getFloat("viewing distance", "Camera");
// All values not set here are set previously as they are constant
compositionLayerDepth[(int)Side::LEFT_SIDE].farZ = farClip;
compositionLayerDepth[(int)Side::RIGHT_SIDE].farZ = farClip;
compositionLayerDepth[(int)Side::LEFT_SIDE].subImage = layerStack[(int)Side::LEFT_SIDE].swapchain->impl().xrSubImageDepth();
compositionLayerDepth[(int)Side::RIGHT_SIDE].subImage = layerStack[(int)Side::RIGHT_SIDE].swapchain->impl().xrSubImageDepth();
if (compositionLayerDepth[(int)Side::LEFT_SIDE].subImage.swapchain != XR_NULL_HANDLE
&& compositionLayerDepth[(int)Side::RIGHT_SIDE].subImage.swapchain != XR_NULL_HANDLE)
{
compositionLayerProjectionViews[(int)Side::LEFT_SIDE].next = &compositionLayerDepth[(int)Side::LEFT_SIDE];
compositionLayerProjectionViews[(int)Side::RIGHT_SIDE].next = &compositionLayerDepth[(int)Side::RIGHT_SIDE];
}
}
XrFrameEndInfo frameEndInfo{ XR_TYPE_FRAME_END_INFO }; XrFrameEndInfo frameEndInfo{ XR_TYPE_FRAME_END_INFO };
frameEndInfo.displayTime = frameInfo.runtimePredictedDisplayTime; frameEndInfo.displayTime = frameInfo.runtimePredictedDisplayTime;
frameEndInfo.environmentBlendMode = mEnvironmentBlendMode; frameEndInfo.environmentBlendMode = mEnvironmentBlendMode;
//if (frameInfo.runtimeRequestsRender) if (layerStack)
{ {
frameEndInfo.layerCount = layerCount; std::array<XrCompositionLayerProjectionView, 2> compositionLayerProjectionViews{};
compositionLayerProjectionViews[(int)Side::LEFT_SIDE] = toXR((*layerStack)[(int)Side::LEFT_SIDE]);
compositionLayerProjectionViews[(int)Side::RIGHT_SIDE] = toXR((*layerStack)[(int)Side::RIGHT_SIDE]);
XrCompositionLayerProjection layer{};
layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
layer.space = getReferenceSpace(ReferenceSpace::STAGE);
layer.viewCount = 2;
layer.views = compositionLayerProjectionViews.data();
auto* xrLayerStack = reinterpret_cast<XrCompositionLayerBaseHeader*>(&layer);
std::array<XrCompositionLayerDepthInfoKHR, 2> compositionLayerDepth = mLayerDepth;
if (xrExtensionIsEnabled(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME))
{
auto farClip = Settings::Manager::getFloat("viewing distance", "Camera");
// All values not set here are set previously as they are constant
compositionLayerDepth[(int)Side::LEFT_SIDE].farZ = farClip;
compositionLayerDepth[(int)Side::RIGHT_SIDE].farZ = farClip;
compositionLayerDepth[(int)Side::LEFT_SIDE].subImage = (*layerStack)[(int)Side::LEFT_SIDE].swapchain->impl().xrSubImageDepth();
compositionLayerDepth[(int)Side::RIGHT_SIDE].subImage = (*layerStack)[(int)Side::RIGHT_SIDE].swapchain->impl().xrSubImageDepth();
if (compositionLayerDepth[(int)Side::LEFT_SIDE].subImage.swapchain != XR_NULL_HANDLE
&& compositionLayerDepth[(int)Side::RIGHT_SIDE].subImage.swapchain != XR_NULL_HANDLE)
{
compositionLayerProjectionViews[(int)Side::LEFT_SIDE].next = &compositionLayerDepth[(int)Side::LEFT_SIDE];
compositionLayerProjectionViews[(int)Side::RIGHT_SIDE].next = &compositionLayerDepth[(int)Side::RIGHT_SIDE];
}
}
frameEndInfo.layerCount = 1;
frameEndInfo.layers = &xrLayerStack; frameEndInfo.layers = &xrLayerStack;
} }
CHECK_XRCMD(xrEndFrame(mSession, &frameEndInfo)); CHECK_XRCMD(xrEndFrame(mSession, &frameEndInfo));
@ -602,6 +602,15 @@ namespace MWVR
} }
popEvent(); popEvent();
} }
if (mXrSessionShouldStop)
{
if (checkStopCondition())
{
CHECK_XRCMD(xrEndSession(mSession));
mXrSessionShouldStop = false;
}
}
} }
const XrEventDataBaseHeader* OpenXRManagerImpl::nextEvent() const XrEventDataBaseHeader* OpenXRManagerImpl::nextEvent()
@ -638,50 +647,70 @@ namespace MWVR
OpenXRManagerImpl::handleSessionStateChanged( OpenXRManagerImpl::handleSessionStateChanged(
const XrEventDataSessionStateChanged& stateChangedEvent) const XrEventDataSessionStateChanged& stateChangedEvent)
{ {
auto oldState = mSessionState; Log(Debug::Verbose) << "XrEventDataSessionStateChanged: state " << to_string(mSessionState) << "->" << to_string(stateChangedEvent.state);
auto newState = stateChangedEvent.state; mSessionState = stateChangedEvent.state;
Log(Debug::Verbose) << "XrEventDataSessionStateChanged: state " << to_string(oldState) << "->" << to_string(newState);
bool success = true;
switch (newState) // Ref: https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#session-states
switch (mSessionState)
{ {
case XR_SESSION_STATE_IDLE:
{
mAppShouldSyncFrameLoop = false;
mAppShouldRender = false;
mAppShouldReadInput = false;
mXrSessionShouldStop = false;
break;
}
case XR_SESSION_STATE_READY: case XR_SESSION_STATE_READY:
{ {
mAppShouldSyncFrameLoop = true;
mAppShouldRender = false;
mAppShouldReadInput = false;
mXrSessionShouldStop = false;
XrSessionBeginInfo beginInfo{ XR_TYPE_SESSION_BEGIN_INFO }; XrSessionBeginInfo beginInfo{ XR_TYPE_SESSION_BEGIN_INFO };
beginInfo.primaryViewConfigurationType = mViewConfigType; beginInfo.primaryViewConfigurationType = mViewConfigType;
CHECK_XRCMD(xrBeginSession(mSession, &beginInfo)); CHECK_XRCMD(xrBeginSession(mSession, &beginInfo));
mSessionRunning = true;
break; break;
} }
case XR_SESSION_STATE_STOPPING: case XR_SESSION_STATE_STOPPING:
{ {
if (checkStopCondition()) mAppShouldSyncFrameLoop = false;
{ mAppShouldRender = false;
CHECK_XRCMD(xrEndSession(mSession)); mAppShouldReadInput = false;
mSessionStopRequested = false; mXrSessionShouldStop = true;
mSessionRunning = false; break;
} }
else case XR_SESSION_STATE_SYNCHRONIZED:
{ {
mSessionStopRequested = true; mAppShouldSyncFrameLoop = true;
success = false; mAppShouldRender = false;
} mAppShouldReadInput = false;
mXrSessionShouldStop = false;
break;
}
case XR_SESSION_STATE_VISIBLE:
{
mAppShouldSyncFrameLoop = true;
mAppShouldRender = true;
mAppShouldReadInput = false;
mXrSessionShouldStop = false;
break;
}
case XR_SESSION_STATE_FOCUSED:
{
mAppShouldSyncFrameLoop = true;
mAppShouldRender = true;
mAppShouldReadInput = true;
mXrSessionShouldStop = false;
break; break;
} }
default: default:
Log(Debug::Verbose) << "XrEventDataSessionStateChanged: Ignoring new state " << to_string(newState); Log(Debug::Warning) << "XrEventDataSessionStateChanged: Ignoring new state " << to_string(mSessionState);
} }
if (success) return true;
{
mSessionState = newState;
}
else
{
Log(Debug::Verbose) << "XrEventDataSessionStateChanged: Conditions for state " << to_string(newState) << " not met, retrying next frame";
}
return success;
} }
bool OpenXRManagerImpl::checkStopCondition() bool OpenXRManagerImpl::checkStopCondition()
@ -760,11 +789,6 @@ namespace MWVR
return mEnabledExtensions.count(extensionName) != 0; return mEnabledExtensions.count(extensionName) != 0;
} }
bool OpenXRManagerImpl::xrSessionCanRender()
{
return xrSessionRunning() && !xrSessionStopRequested();
}
void OpenXRManagerImpl::xrResourceAcquired() void OpenXRManagerImpl::xrResourceAcquired()
{ {
mAcquiredResources++; mAcquiredResources++;
@ -792,11 +816,6 @@ namespace MWVR
return function; return function;
} }
bool OpenXRManagerImpl::xrSessionStopRequested()
{
return mSessionStopRequested;
}
void OpenXRManagerImpl::enablePredictions() void OpenXRManagerImpl::enablePredictions()
{ {
mPredictionsEnabled = true; mPredictionsEnabled = true;

View file

@ -51,8 +51,10 @@ namespace MWVR
FrameInfo waitFrame(); FrameInfo waitFrame();
void beginFrame(); void beginFrame();
void endFrame(FrameInfo frameInfo, int layerCount, const std::array<CompositionLayerProjectionView, 2>& layerStack); void endFrame(FrameInfo frameInfo, const std::array<CompositionLayerProjectionView, 2>* layerStack);
bool xrSessionRunning() const { return mSessionRunning; } bool appShouldSyncFrameLoop() const { return mAppShouldSyncFrameLoop; }
bool appShouldRender() const { return mAppShouldRender; }
bool appShouldReadInput() const { return mAppShouldReadInput; }
std::array<View, 2> getPredictedViews(int64_t predictedDisplayTime, ReferenceSpace space); std::array<View, 2> getPredictedViews(int64_t predictedDisplayTime, ReferenceSpace space);
MWVR::Pose getPredictedHeadPose(int64_t predictedDisplayTime, ReferenceSpace space); MWVR::Pose getPredictedHeadPose(int64_t predictedDisplayTime, ReferenceSpace space);
void handleEvents(); void handleEvents();
@ -65,8 +67,6 @@ namespace MWVR
XrSession xrSession() const { return mSession; }; XrSession xrSession() const { return mSession; };
XrInstance xrInstance() const { return mInstance; }; XrInstance xrInstance() const { return mInstance; };
bool xrExtensionIsEnabled(const char* extensionName) const; bool xrExtensionIsEnabled(const char* extensionName) const;
bool xrSessionStopRequested();
bool xrSessionCanRender();
void xrResourceAcquired(); void xrResourceAcquired();
void xrResourceReleased(); void xrResourceReleased();
void xrUpdateNames(); void xrUpdateNames();
@ -106,8 +106,12 @@ namespace MWVR
XrFrameState mFrameState{}; XrFrameState mFrameState{};
XrSessionState mSessionState = XR_SESSION_STATE_UNKNOWN; XrSessionState mSessionState = XR_SESSION_STATE_UNKNOWN;
XrDebugUtilsMessengerEXT mDebugMessenger{ nullptr }; XrDebugUtilsMessengerEXT mDebugMessenger{ nullptr };
bool mSessionStopRequested = false;
bool mSessionRunning = false; bool mXrSessionShouldStop = false;
bool mAppShouldSyncFrameLoop = false;
bool mAppShouldRender = false;
bool mAppShouldReadInput = false;
uint32_t mAcquiredResources = 0; uint32_t mAcquiredResources = 0;
std::mutex mFrameStateMutex{}; std::mutex mFrameStateMutex{};
std::mutex mEventMutex{}; std::mutex mEventMutex{};

View file

@ -111,12 +111,6 @@ namespace MWVR
} }
} }
bool VRSession::isRunning() const {
return true;
auto* xr = Environment::get().getManager();
return xr->xrSessionRunning();
}
void VRSession::swapBuffers(osg::GraphicsContext* gc, VRViewer& viewer) void VRSession::swapBuffers(osg::GraphicsContext* gc, VRViewer& viewer)
{ {
auto* xr = Environment::get().getManager(); auto* xr = Environment::get().getManager();
@ -127,22 +121,29 @@ namespace MWVR
auto leftView = viewer.getView("LeftEye"); auto leftView = viewer.getView("LeftEye");
auto rightView = viewer.getView("RightEye"); auto rightView = viewer.getView("RightEye");
if (frameMeta->mShouldRender) if (frameMeta->mShouldSyncFrameLoop)
{ {
viewer.blitEyesToMirrorTexture(gc); if (frameMeta->mShouldRender)
gc->swapBuffersImplementation(); {
leftView->swapBuffers(gc); viewer.blitEyesToMirrorTexture(gc);
rightView->swapBuffers(gc); gc->swapBuffersImplementation();
leftView->swapBuffers(gc);
rightView->swapBuffers(gc);
std::array<CompositionLayerProjectionView, 2> layerStack{};
layerStack[(int)Side::LEFT_SIDE].swapchain = &leftView->swapchain();
layerStack[(int)Side::RIGHT_SIDE].swapchain = &rightView->swapchain();
layerStack[(int)Side::LEFT_SIDE].pose = frameMeta->mPredictedPoses.eye[(int)Side::LEFT_SIDE] / mPlayerScale;
layerStack[(int)Side::RIGHT_SIDE].pose = frameMeta->mPredictedPoses.eye[(int)Side::RIGHT_SIDE] / mPlayerScale;
layerStack[(int)Side::LEFT_SIDE].fov = frameMeta->mPredictedPoses.view[(int)Side::LEFT_SIDE].fov;
layerStack[(int)Side::RIGHT_SIDE].fov = frameMeta->mPredictedPoses.view[(int)Side::RIGHT_SIDE].fov;
xr->endFrame(frameMeta->mFrameInfo, &layerStack);
}
else
{
gc->swapBuffersImplementation();
xr->endFrame(frameMeta->mFrameInfo, nullptr);
}
std::array<CompositionLayerProjectionView, 2> layerStack{};
layerStack[(int)Side::LEFT_SIDE].swapchain = &leftView->swapchain();
layerStack[(int)Side::RIGHT_SIDE].swapchain = &rightView->swapchain();
layerStack[(int)Side::LEFT_SIDE].pose = frameMeta->mPredictedPoses.eye[(int)Side::LEFT_SIDE] / mPlayerScale;
layerStack[(int)Side::RIGHT_SIDE].pose = frameMeta->mPredictedPoses.eye[(int)Side::RIGHT_SIDE] / mPlayerScale;
layerStack[(int)Side::LEFT_SIDE].fov = frameMeta->mPredictedPoses.view[(int)Side::LEFT_SIDE].fov;
layerStack[(int)Side::RIGHT_SIDE].fov = frameMeta->mPredictedPoses.view[(int)Side::RIGHT_SIDE].fov;
xr->endFrame(frameMeta->mFrameInfo, 1, layerStack);
xr->xrResourceReleased(); xr->xrResourceReleased();
} }
@ -181,7 +182,7 @@ namespace MWVR
frame = std::move(getFrame(previousPhase)); frame = std::move(getFrame(previousPhase));
} }
if (phase == mXrSyncPhase && frame->mShouldRender) if (phase == mXrSyncPhase && frame->mShouldSyncFrameLoop)
{ {
// We may reach this point before xrEndFrame of the previous frame // We may reach this point before xrEndFrame of the previous frame
// Must wait or openxr will interpret another call to xrBeginFrame() as skipping a frame // Must wait or openxr will interpret another call to xrBeginFrame() as skipping a frame
@ -191,10 +192,7 @@ namespace MWVR
mCondition.wait(lock); mCondition.wait(lock);
} }
if (frame->mShouldRender) Environment::get().getManager()->beginFrame();
{
Environment::get().getManager()->beginFrame();
}
} }
} }
@ -215,42 +213,48 @@ namespace MWVR
frame.reset(new VRFrameMeta); frame.reset(new VRFrameMeta);
frame->mFrameNo = mFrames; frame->mFrameNo = mFrames;
frame->mShouldRender = xr->xrSessionCanRender(); frame->mShouldSyncFrameLoop = xr->appShouldSyncFrameLoop();
if (frame->mShouldRender) frame->mShouldRender = xr->appShouldRender();
if (frame->mShouldSyncFrameLoop)
{ {
frame->mFrameInfo = xr->waitFrame(); frame->mFrameInfo = xr->waitFrame();
xr->xrResourceAcquired(); xr->xrResourceAcquired();
if (frame->mShouldRender)
{
frame->mPredictedDisplayTime = frame->mFrameInfo.runtimePredictedDisplayTime;
PoseSet predictedPoses{};
xr->enablePredictions();
predictedPoses.head = xr->getPredictedHeadPose(frame->mPredictedDisplayTime, ReferenceSpace::STAGE) * mPlayerScale;
auto hmdViews = xr->getPredictedViews(frame->mPredictedDisplayTime, 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(frame->mPredictedDisplayTime, 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;
auto* input = Environment::get().getInputManager();
if (input)
{
predictedPoses.hands[(int)Side::LEFT_SIDE] = input->getLimbPose(frame->mPredictedDisplayTime, TrackedLimb::LEFT_HAND) * mPlayerScale;
predictedPoses.hands[(int)Side::RIGHT_SIDE] = input->getLimbPose(frame->mPredictedDisplayTime, TrackedLimb::RIGHT_HAND) * mPlayerScale;
}
xr->disablePredictions();
frame->mPredictedPoses = predictedPoses;
}
} }
frame->mPredictedDisplayTime = frame->mFrameInfo.runtimePredictedDisplayTime;
PoseSet predictedPoses{};
xr->enablePredictions();
predictedPoses.head = xr->getPredictedHeadPose(frame->mPredictedDisplayTime, ReferenceSpace::STAGE) * mPlayerScale;
auto hmdViews = xr->getPredictedViews(frame->mPredictedDisplayTime, 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(frame->mPredictedDisplayTime, 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;
auto* input = Environment::get().getInputManager();
if (input)
{
predictedPoses.hands[(int)Side::LEFT_SIDE] = input->getLimbPose(frame->mPredictedDisplayTime, TrackedLimb::LEFT_HAND) * mPlayerScale;
predictedPoses.hands[(int)Side::RIGHT_SIDE] = input->getLimbPose(frame->mPredictedDisplayTime, TrackedLimb::RIGHT_HAND) * mPlayerScale;
}
xr->disablePredictions();
frame->mPredictedPoses = predictedPoses;
} }
const PoseSet& VRSession::predictedPoses(FramePhase phase) const PoseSet& VRSession::predictedPoses(FramePhase phase)
{ {
auto& frame = getFrame(phase); auto& frame = getFrame(phase);
// TODO: Manage execution order properly instead of this hack
if (phase == FramePhase::Update && !frame) if (phase == FramePhase::Update && !frame)
beginPhase(FramePhase::Update); beginPhase(FramePhase::Update);

View file

@ -47,6 +47,7 @@ namespace MWVR
long long mPredictedDisplayTime{ 0 }; long long mPredictedDisplayTime{ 0 };
PoseSet mPredictedPoses{}; PoseSet mPredictedPoses{};
bool mShouldRender{ false }; bool mShouldRender{ false };
bool mShouldSyncFrameLoop{ false };
FrameInfo mFrameInfo{}; FrameInfo mFrameInfo{};
}; };
@ -67,8 +68,6 @@ namespace MWVR
void beginPhase(FramePhase phase); void beginPhase(FramePhase phase);
std::unique_ptr<VRFrameMeta>& getFrame(FramePhase phase); std::unique_ptr<VRFrameMeta>& getFrame(FramePhase phase);
bool isRunning() const;
float playerScale() const { return mPlayerScale; } float playerScale() const { return mPlayerScale; }
float setPlayerScale(float scale) { return mPlayerScale = scale; } float setPlayerScale(float scale) { return mPlayerScale = scale; }

View file

@ -955,7 +955,7 @@ XR_EXT_debug_utils message level info = true
XR_EXT_debug_utils message level warning = true XR_EXT_debug_utils message level warning = true
XR_EXT_debug_utils message level error = true XR_EXT_debug_utils message level error = true
# Enable/disable openxr debug message types # Enable/disable openxr debug message types
XR_EXT_debug_utils message type general = false XR_EXT_debug_utils message type general = true
XR_EXT_debug_utils message type validation = true XR_EXT_debug_utils message type validation = true
XR_EXT_debug_utils message type performance = true XR_EXT_debug_utils message type performance = true
XR_EXT_debug_utils message type conformance = true XR_EXT_debug_utils message type conformance = true