diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a971051311..786f29fc90 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1603,7 +1603,7 @@ void Application::paintGL() { // unmodified head pose because the only plugin that cares (the Oculus plugin) uses it // for rotational timewarp. If we move to support positonal timewarp, we need to // ensure this contains the full pose composed with the eye offsets. - mat4 headPose = displayPlugin->getHeadPose(_frameCount); + mat4 headPose = displayPlugin->updateHeadPose(_frameCount); // FIXME we probably don't need to set the projection matrix every frame, // only when the display plugin changes (or in non-HMD modes when the user @@ -2975,7 +2975,7 @@ void Application::updateMyAvatarLookAtPosition() { lookAtPosition.x = -lookAtPosition.x; } if (isHMD) { - glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(_frameCount); + glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); glm::quat hmdRotation = glm::quat_cast(headPose); lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); } else { @@ -4927,7 +4927,7 @@ mat4 Application::getEyeOffset(int eye) const { mat4 Application::getHMDSensorPose() const { if (isHMDMode()) { - return getActiveDisplayPlugin()->getHeadPose(_frameCount); + return getActiveDisplayPlugin()->getHeadPose(); } return mat4(); } diff --git a/interface/src/avatar/AvatarUpdate.cpp b/interface/src/avatar/AvatarUpdate.cpp index a52b584527..3e0d23cc1c 100644 --- a/interface/src/avatar/AvatarUpdate.cpp +++ b/interface/src/avatar/AvatarUpdate.cpp @@ -38,7 +38,7 @@ void AvatarUpdate::synchronousProcess() { // transform the head pose from the displayPlugin into avatar coordinates. glm::mat4 invAvatarMat = glm::inverse(createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition())); - _headPose = invAvatarMat * (myAvatar->getSensorToWorldMatrix() * qApp->getActiveDisplayPlugin()->getHeadPose(frameCount)); + _headPose = invAvatarMat * (myAvatar->getSensorToWorldMatrix() * qApp->getActiveDisplayPlugin()->getHeadPose()); if (!isThreaded()) { process(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7198f32422..550c11df4d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1258,7 +1258,7 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl if (qApp->isHMDMode()) { glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); - glm::mat4 headPose = qApp->getActiveDisplayPlugin()->getHeadPose(qApp->getFrameCount()); + glm::mat4 headPose = qApp->getActiveDisplayPlugin()->getHeadPose(); glm::mat4 leftEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Left); leftEyePose = leftEyePose * headPose; glm::vec3 leftEyePosition = extractTranslation(leftEyePose); diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index f2040eaa43..3e09e96704 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -342,7 +342,7 @@ void CompositorHelper::computeHmdPickRay(const glm::vec2& cursorPos, glm::vec3& } glm::mat4 CompositorHelper::getUiTransform() const { - return _currentCamera * glm::inverse(_currentDisplayPlugin->getHeadPose(_currentFrame)); + return _currentCamera * glm::inverse(_currentDisplayPlugin->getHeadPose()); } //Finds the collision point of a world space ray diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 76db1ecbe2..376cec7b70 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -121,8 +121,14 @@ public: static const glm::mat4 transform; return transform; } - virtual glm::mat4 getHeadPose(uint32_t frameIndex) const { - static const glm::mat4 pose; return pose; + // will query the underlying hmd api to compute the most recent head pose + virtual glm::mat4 updateHeadPose(uint32_t frameIndex) { + return glm::mat4(); + } + + // returns a copy of the most recent head pose, computed via updateHeadPose + virtual glm::mat4 getHeadPose() const { + return glm::mat4(); } // Needed for timewarp style features diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index f1613176df..0f87d526d7 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -15,14 +15,20 @@ void OculusBaseDisplayPlugin::resetSensors() { ovr_RecenterPose(_session); } -glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const { +glm::mat4 OculusBaseDisplayPlugin::updateHeadPose(uint32_t frameIndex) { static uint32_t lastFrameSeen = 0; auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex); auto trackingState = ovr_GetTrackingState(_session, displayTime, frameIndex > lastFrameSeen); if (frameIndex > lastFrameSeen) { lastFrameSeen = frameIndex; } - return toGlm(trackingState.HeadPose.ThePose); + mat4 headPose = toGlm(trackingState.HeadPose.ThePose); + _headPoseCache.set(headPose); + return headPose; +} + +glm::mat4 OculusBaseDisplayPlugin::getHeadPose() const { + return _headPoseCache.get(); } bool OculusBaseDisplayPlugin::isSupported() const { diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index e6f0b265a2..cf8f38fe3a 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include @@ -20,7 +21,8 @@ public: // Stereo specific methods virtual void resetSensors() override final; - virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override; + virtual glm::mat4 updateHeadPose(uint32_t frameIndex) override; + virtual glm::mat4 getHeadPose() const override; protected: void customizeContext() override; @@ -36,4 +38,5 @@ protected: ovrHmdDesc _hmdDesc; ovrLayerEyeFov _sceneLayer; ovrViewScaleDesc _viewScaleDesc; + ThreadSafeValueCache _headPoseCache { glm::mat4() }; }; diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index d0363d4dcc..f559e902d9 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -38,7 +38,7 @@ static mat4 _sensorResetMat; static std::array VR_EYES { { vr::Eye_Left, vr::Eye_Right } }; bool OpenVrDisplayPlugin::isSupported() const { - return !isOculusPresent() && vr::VR_IsHmdPresent(); + return /*!isOculusPresent() &&*/ vr::VR_IsHmdPresent(); } void OpenVrDisplayPlugin::internalActivate() { @@ -112,7 +112,7 @@ void OpenVrDisplayPlugin::resetSensors() { _sensorResetMat = glm::inverse(cancelOutRollAndPitch(m)); } -glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const { +glm::mat4 OpenVrDisplayPlugin::updateHeadPose(uint32_t frameIndex) { float displayFrequency = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float); float frameDuration = 1.f / displayFrequency; @@ -139,14 +139,21 @@ glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const { _trackedDeviceLinearVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vVelocity)); _trackedDeviceAngularVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vAngularVelocity)); } + + _headPoseCache.set(_trackedDevicePoseMat4[0]); + return _trackedDevicePoseMat4[0]; } +glm::mat4 OpenVrDisplayPlugin::getHeadPose() const { + return _headPoseCache.get(); +} + void OpenVrDisplayPlugin::hmdPresent() { // Flip y-axis since GL UV coords are backwards. static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 }; static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 }; - + vr::Texture_t texture { (void*)oglplus::GetName(_compositeFramebuffer->color), vr::API_OpenGL, vr::ColorSpace_Auto }; _compositor->Submit(vr::Eye_Left, &texture, &leftBounds); diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index c7577fd53f..7405aab82e 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -12,6 +12,7 @@ #include #include +#include const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only. @@ -27,7 +28,8 @@ public: // Stereo specific methods virtual void resetSensors() override; - virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override; + virtual glm::mat4 updateHeadPose(uint32_t frameIndex) override; + virtual glm::mat4 getHeadPose() const override; protected: void internalActivate() override; @@ -41,4 +43,5 @@ private: std::atomic _hmdActivityLevel { vr::k_EDeviceActivityLevel_Unknown }; static const QString NAME; mutable Mutex _poseMutex; + ThreadSafeValueCache _headPoseCache { glm::mat4() }; };