diff --git a/apps/openmw/engine_vr.cpp b/apps/openmw/engine_vr.cpp index d77c6c7cf..c224d6ae4 100644 --- a/apps/openmw/engine_vr.cpp +++ b/apps/openmw/engine_vr.cpp @@ -11,6 +11,6 @@ void OMW::Engine::initVr() throw std::logic_error("mViewer must be initialized before calling initVr()"); mXR = new MWVR::OpenXRManager(); - mXRViewer = new MWVR::OpenXRViewer(mXR, mViewer, 1.f); + mXRViewer = new MWVR::OpenXRViewer(mXR, mViewer, 64.f * 0.9144); } diff --git a/apps/openmw/mwvr/openxrinputmanager.cpp b/apps/openmw/mwvr/openxrinputmanager.cpp index 75ebae9e9..49bbfbcc7 100644 --- a/apps/openmw/mwvr/openxrinputmanager.cpp +++ b/apps/openmw/mwvr/openxrinputmanager.cpp @@ -414,68 +414,6 @@ 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 }))) { - - - - //{ mHandPoseAction, mPosePath[LEFT_HAND]}, - //{ mHandPoseAction, mPosePath[RIGHT_HAND] }, - //{ mHapticsAction, mHapticPath[LEFT_HAND] }, - //{ mHapticsAction, mHapticPath[RIGHT_HAND] }, - - //{ mLookLeftRight, mThumbstickXPath[RIGHT_HAND] }, - //{ mMoveLeftRight, mThumbstickXPath[LEFT_HAND] }, - //{ mMoveForwardBackward, mThumbstickYPath[LEFT_HAND] }, - //{ mActivate, mSqueezeClickPath[RIGHT_HAND] }, - //{ mUse, mTriggerClickPath[RIGHT_HAND] }, - //{ mJump, mTriggerValuePath[LEFT_HAND] }, - //{ mWeapon, mAPath[RIGHT_HAND] }, - //{ mSpell, mAPath[RIGHT_HAND] }, - //{ mCycleSpellLeft, mThumbstickClickPath[LEFT_HAND] }, - //{ mCycleSpellRight, mThumbstickClickPath[RIGHT_HAND] }, - //{ mCycleWeaponLeft, mThumbstickClickPath[LEFT_HAND] }, - //{ mCycleWeaponRight, mThumbstickClickPath[RIGHT_HAND] }, - //{ mSneak, mXPath[LEFT_HAND] }, - //{ mInventory, mBPath[RIGHT_HAND] }, - //{ mQuickMenu, mYPath[LEFT_HAND] }, - //{ mSpellModifier, mSqueezeClickPath[LEFT_HAND] }, - //{ mGameMenu, mMenuClickPath[LEFT_HAND] }, - - // There are not enough actions on controllers to assign everything. - //mUnused = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "Unused", "Unused", { })); - //mScreenshot = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "Screenshot", "Screenshot", { })); - //mConsole = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "Console", "Console", { })); - //mMoveLeft = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "MoveLeft", "MoveLeft", { })); - //mMoveRight = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "MoveRight", "MoveRight", { })); - //mMoveForward = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "MoveForward", "MoveForward", { })); - //mMoveBackward = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "MoveBackward", "MoveBackward", { })); - //mAutoMove = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "AutoMove", "AutoMove", { })); - //mRest = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "Rest", "Rest", { })); - //mJournal = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "Journal", "Journal", { })); - //mRun = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "Run", "Run", { })); - //mAlwaysRun = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "AlwaysRun", "AlwaysRun", { })); - //mQuickSave = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickSave", "QuickSave", { })); - //mQuickLoad = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickLoad", "QuickLoad", { })); - //mToggleWeapon = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "ToggleWeapon", "ToggleWeapon", { })); - //mToggleSpell = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "ToggleSpell", "ToggleSpell", { })); - //mTogglePOV = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "TogglePOV", "TogglePOV", { })); - //mQuickKey1 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey1", "QuickKey1", { })); - //mQuickKey2 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey2", "QuickKey2", { })); - //mQuickKey3 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey3", "QuickKey3", { })); - //mQuickKey4 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey4", "QuickKey4", { })); - //mQuickKey5 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey5", "QuickKey5", { })); - //mQuickKey6 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey6", "QuickKey6", { })); - //mQuickKey7 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey7", "QuickKey7", { })); - //mQuickKey8 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey8", "QuickKey8", { })); - //mQuickKey9 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey9", "QuickKey9", { })); - //mQuickKey10 = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKey10", "QuickKey10", { })); - //mQuickKeysMenu = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "QuickKeysMenu", "QuickKeysMenu", { })); - //mToggleHUD = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "ToggleHUD", "ToggleHUD", { })); - //mToggleDebug = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "ToggleDebug", "ToggleDebug", { })); - //mToggleSneak = std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "ToggleSneak", "ToggleSneak", { })); - //mLookUpDown = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "LookUpDown", "LookUpDown", { })); - //mZoomIn = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "ZoomIn", "ZoomIn", { })); - //mZoomOut = std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "ZoomOut", "ZoomOut", { })); - { // Set up default bindings for the oculus XrPath oculusTouchInteractionProfilePath; CHECK_XRCMD( diff --git a/apps/openmw/mwvr/openxrlayer.cpp b/apps/openmw/mwvr/openxrlayer.cpp index 797e5ab08..2c0023467 100644 --- a/apps/openmw/mwvr/openxrlayer.cpp +++ b/apps/openmw/mwvr/openxrlayer.cpp @@ -39,6 +39,6 @@ namespace MWVR { if (!mLayers[1]) return nullptr; - + return nullptr; } } diff --git a/apps/openmw/mwvr/openxrmanager.cpp b/apps/openmw/mwvr/openxrmanager.cpp index 16562c9cf..efa3bf45d 100644 --- a/apps/openmw/mwvr/openxrmanager.cpp +++ b/apps/openmw/mwvr/openxrmanager.cpp @@ -44,7 +44,7 @@ namespace MWVR OpenXRManager::frameIndex() { if (realized()) - return impl().frameIndex; + return impl().mFrameIndex; return -1; } @@ -67,10 +67,10 @@ namespace MWVR return impl().waitFrame(); } - void OpenXRManager::beginFrame() + void OpenXRManager::beginFrame(long long frameIndex) { if (realized()) - return impl().beginFrame(); + return impl().beginFrame(frameIndex); } void OpenXRManager::endFrame() diff --git a/apps/openmw/mwvr/openxrmanager.hpp b/apps/openmw/mwvr/openxrmanager.hpp index 824c17358..1ae2ba7ef 100644 --- a/apps/openmw/mwvr/openxrmanager.hpp +++ b/apps/openmw/mwvr/openxrmanager.hpp @@ -96,7 +96,7 @@ namespace MWVR void handleEvents(); void waitFrame(); - void beginFrame(); + void beginFrame(long long frameIndex); void endFrame(); void updateControls(); void updatePoses(); diff --git a/apps/openmw/mwvr/openxrmanagerimpl.cpp b/apps/openmw/mwvr/openxrmanagerimpl.cpp index 9513f0ebf..d2bcf1aa2 100644 --- a/apps/openmw/mwvr/openxrmanagerimpl.cpp +++ b/apps/openmw/mwvr/openxrmanagerimpl.cpp @@ -275,8 +275,9 @@ namespace MWVR } void - OpenXRManagerImpl::beginFrame() + OpenXRManagerImpl::beginFrame(long long frameIndex) { + Log(Debug::Verbose) << "frameIndex = " << frameIndex; if (!mSessionRunning) return; @@ -284,11 +285,12 @@ namespace MWVR // We need to wait for the frame to become idle or ready // (There is no guarantee osg won't get us here before endFrame() returns) - while (mFrameStatus == OPENXR_FRAME_STATUS_ENDING) + while (mFrameStatus == OPENXR_FRAME_STATUS_ENDING || mFrameIndex < frameIndex) mFrameStatusSignal.wait(lock); if (mFrameStatus == OPENXR_FRAME_STATUS_IDLE) { + Log(Debug::Verbose) << "beginFrame()"; handleEvents(); waitFrame(); @@ -356,6 +358,7 @@ namespace MWVR frameEndInfo.layers = mLayerStack.layerHeaders(); CHECK_XRCMD(xrEndFrame(mSession, &frameEndInfo)); mFrameStatus = OPENXR_FRAME_STATUS_IDLE; + mFrameIndex++; mFrameStatusSignal.notify_all(); } diff --git a/apps/openmw/mwvr/openxrmanagerimpl.hpp b/apps/openmw/mwvr/openxrmanagerimpl.hpp index 8570d8da3..c794edacb 100644 --- a/apps/openmw/mwvr/openxrmanagerimpl.hpp +++ b/apps/openmw/mwvr/openxrmanagerimpl.hpp @@ -56,7 +56,7 @@ namespace MWVR const XrEventDataBaseHeader* nextEvent(); void waitFrame(); - void beginFrame(); + void beginFrame(long long frameIndex); void endFrame(); std::array getStageViews(); std::array getHmdViews(); @@ -69,7 +69,7 @@ namespace MWVR void HandleSessionStateChanged(const XrEventDataSessionStateChanged& stateChangedEvent); bool initialized = false; - long long frameIndex = 0; + long long mFrameIndex = 0; XrInstance mInstance = XR_NULL_HANDLE; XrSession mSession = XR_NULL_HANDLE; XrSpace mSpace = XR_NULL_HANDLE; diff --git a/apps/openmw/mwvr/openxrmenu.cpp b/apps/openmw/mwvr/openxrmenu.cpp index 7a52d9cbc..2c6297024 100644 --- a/apps/openmw/mwvr/openxrmenu.cpp +++ b/apps/openmw/mwvr/openxrmenu.cpp @@ -55,6 +55,8 @@ namespace MWVR mLayer->pose.position = osg::toXR(pose.position); mLayer->pose.orientation = osg::toXR(-pose.orientation); mPositionNeedsUpdate = false; + + Log(Debug::Verbose) << "Menu pose updated to: " << pose; } void OpenXRMenu::postrenderCallback(osg::RenderInfo& info) diff --git a/apps/openmw/mwvr/openxrview.cpp b/apps/openmw/mwvr/openxrview.cpp index 4ee1a94f7..c6785cbde 100644 --- a/apps/openmw/mwvr/openxrview.cpp +++ b/apps/openmw/mwvr/openxrview.cpp @@ -71,7 +71,8 @@ namespace MWVR { void OpenXRView::prerenderCallback(osg::RenderInfo& renderInfo) { - mXR->beginFrame(); + Log(Debug::Verbose) << "prerenderCallback"; + mXR->beginFrame(mFrameIndex); if(mSwapchain) mSwapchain->beginFrame(renderInfo.getState()->getGraphicsContext()); } @@ -81,6 +82,7 @@ namespace MWVR { if (mSwapchain) mSwapchain->endFrame(renderInfo.getState()->getGraphicsContext()); mXR->viewerBarrier(); + mFrameIndex++; } bool OpenXRView::realize(osg::ref_ptr state) diff --git a/apps/openmw/mwvr/openxrview.hpp b/apps/openmw/mwvr/openxrview.hpp index ca0e9b92a..53a7b40d3 100644 --- a/apps/openmw/mwvr/openxrview.hpp +++ b/apps/openmw/mwvr/openxrview.hpp @@ -66,11 +66,14 @@ namespace MWVR OpenXRSwapchain& swapchain(void) { return *mSwapchain; } //! Create the view surface bool realize(osg::ref_ptr state); + //! Current frame being rendered + long long frameIndex() { return mFrameIndex; }; protected: osg::ref_ptr mXR; std::unique_ptr mSwapchain; OpenXRSwapchain::Config mSwapchainConfig; + long long mFrameIndex{ 0 }; }; } diff --git a/apps/openmw/mwvr/openxrviewer.cpp b/apps/openmw/mwvr/openxrviewer.cpp index 1786cac87..f999d7c49 100644 --- a/apps/openmw/mwvr/openxrviewer.cpp +++ b/apps/openmw/mwvr/openxrviewer.cpp @@ -79,6 +79,7 @@ namespace MWVR if (!context->makeCurrent()) { throw std::logic_error("OpenXRViewer::configure() failed to make graphics context current."); + return; } mMainCamera = mViewer->getCamera(); @@ -183,8 +184,8 @@ namespace MWVR mMirrorTextureSwapchain->current()->blit(gc, 0, 0, mMirrorTextureSwapchain->width(), mMirrorTextureSwapchain->height()); - gc->swapBuffersImplementation(); mMirrorTextureSwapchain->releaseSwapchainImage(); + gc->swapBuffersImplementation(); } @@ -202,8 +203,8 @@ namespace MWVR auto* camera = slave._camera.get(); auto name = camera->getName(); - Log(Debug::Debug) << "Updating camera " << name; - + Log(Debug::Verbose) << "Updating camera " << name; + mXR->beginFrame(mView->frameIndex()); auto viewMatrix = view.getCamera()->getViewMatrix() * mView->viewMatrix(); auto projMatrix = mView->projectionMatrix(); diff --git a/apps/openmw/mwvr/openxrworldview.cpp b/apps/openmw/mwvr/openxrworldview.cpp index cfb774204..130fe097e 100644 --- a/apps/openmw/mwvr/openxrworldview.cpp +++ b/apps/openmw/mwvr/openxrworldview.cpp @@ -80,7 +80,7 @@ namespace MWVR auto hmdViews = mXR->impl().getHmdViews(); float near = Settings::Manager::getFloat("near clip", "Camera"); - float far = Settings::Manager::getFloat("viewing distance", "Camera"); + float far = Settings::Manager::getFloat("viewing distance", "Camera") * mMetersPerUnit; //return perspectiveFovMatrix() return perspectiveFovMatrix(near, far, hmdViews[mView].fov); } @@ -90,17 +90,26 @@ namespace MWVR osg::Matrix viewMatrix; auto hmdViews = mXR->impl().getHmdViews(); auto pose = hmdViews[mView].pose; - osg::Vec3 position = osg::Vec3(pose.position.x, pose.position.y, pose.position.z); + osg::Vec3 position = osg::fromXR(pose.position); auto stageViews = mXR->impl().getStageViews(); auto stagePose = stageViews[mView].pose; + // Comfort shortcut. + // TODO: STAGE movement should affect in-game movement but not like this. + // This method should only be using HEAD view. + // But for comfort i'm keeping this until such movement has been implemented. +#if 1 + position = -osg::fromXR(stagePose.position); + position.y() += 0.9144 * 2.; +#endif + // invert orientation (conjugate of Quaternion) and position to apply to the view matrix as offset - viewMatrix.setTrans(position); + viewMatrix.setTrans(position * mMetersPerUnit); viewMatrix.postMultRotate(osg::fromXR(stagePose.orientation).conj()); // Scale to world units - viewMatrix.postMultScale(osg::Vec3d(mMetersPerUnit, mMetersPerUnit, mMetersPerUnit)); + //viewMatrix.postMultScale(osg::Vec3d(1.f / mMetersPerUnit, 1.f / mMetersPerUnit, 1.f / mMetersPerUnit)); return viewMatrix; } @@ -116,6 +125,7 @@ namespace MWVR setWidth(config.recommendedImageRectWidth); setHeight(config.recommendedImageRectHeight); setSamples(config.recommendedSwapchainSampleCount); + realize(state); // XR->setViewSubImage(view, mSwapchain->subImage()); }