mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 03:13:09 +02:00
Merge pull request #7395 from hyperlogic/tony/openvr-crash-on-exit
openvr crash on exit fix
This commit is contained in:
commit
47c4b226ea
13 changed files with 42 additions and 37 deletions
|
@ -1420,6 +1420,8 @@ void Application::paintGL() {
|
||||||
// FIXME not needed anymore?
|
// FIXME not needed anymore?
|
||||||
_offscreenContext->makeCurrent();
|
_offscreenContext->makeCurrent();
|
||||||
|
|
||||||
|
displayPlugin->updateHeadPose(_frameCount);
|
||||||
|
|
||||||
// update the avatar with a fresh HMD pose
|
// update the avatar with a fresh HMD pose
|
||||||
getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
|
getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
|
||||||
|
|
||||||
|
@ -1600,12 +1602,7 @@ void Application::paintGL() {
|
||||||
auto baseProjection = renderArgs._viewFrustum->getProjection();
|
auto baseProjection = renderArgs._viewFrustum->getProjection();
|
||||||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||||
float IPDScale = hmdInterface->getIPDScale();
|
float IPDScale = hmdInterface->getIPDScale();
|
||||||
|
mat4 headPose = displayPlugin->getHeadPose();
|
||||||
// Tell the plugin what pose we're using to render. In this case we're just using the
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// FIXME we probably don't need to set the projection matrix every frame,
|
// 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
|
// only when the display plugin changes (or in non-HMD modes when the user
|
||||||
|
@ -1622,6 +1619,10 @@ void Application::paintGL() {
|
||||||
mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale);
|
mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale);
|
||||||
eyeOffsets[eye] = eyeOffsetTransform;
|
eyeOffsets[eye] = eyeOffsetTransform;
|
||||||
|
|
||||||
|
// Tell the plugin what pose we're using to render. In this case we're just using the
|
||||||
|
// 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.
|
||||||
displayPlugin->setEyeRenderPose(_frameCount, eye, headPose * glm::inverse(eyeOffsetTransform));
|
displayPlugin->setEyeRenderPose(_frameCount, eye, headPose * glm::inverse(eyeOffsetTransform));
|
||||||
|
|
||||||
eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection);
|
eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection);
|
||||||
|
@ -2977,7 +2978,7 @@ void Application::updateMyAvatarLookAtPosition() {
|
||||||
lookAtPosition.x = -lookAtPosition.x;
|
lookAtPosition.x = -lookAtPosition.x;
|
||||||
}
|
}
|
||||||
if (isHMD) {
|
if (isHMD) {
|
||||||
glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(_frameCount);
|
glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose();
|
||||||
glm::quat hmdRotation = glm::quat_cast(headPose);
|
glm::quat hmdRotation = glm::quat_cast(headPose);
|
||||||
lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition);
|
lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition);
|
||||||
} else {
|
} else {
|
||||||
|
@ -4929,7 +4930,7 @@ mat4 Application::getEyeOffset(int eye) const {
|
||||||
|
|
||||||
mat4 Application::getHMDSensorPose() const {
|
mat4 Application::getHMDSensorPose() const {
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
return getActiveDisplayPlugin()->getHeadPose(_frameCount);
|
return getActiveDisplayPlugin()->getHeadPose();
|
||||||
}
|
}
|
||||||
return mat4();
|
return mat4();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ void AvatarUpdate::synchronousProcess() {
|
||||||
|
|
||||||
// Keep our own updated value, so that our asynchronous code can consult it.
|
// Keep our own updated value, so that our asynchronous code can consult it.
|
||||||
_isHMDMode = qApp->isHMDMode();
|
_isHMDMode = qApp->isHMDMode();
|
||||||
auto frameCount = qApp->getFrameCount();
|
|
||||||
|
|
||||||
QSharedPointer<AvatarManager> manager = DependencyManager::get<AvatarManager>();
|
QSharedPointer<AvatarManager> manager = DependencyManager::get<AvatarManager>();
|
||||||
MyAvatar* myAvatar = manager->getMyAvatar();
|
MyAvatar* myAvatar = manager->getMyAvatar();
|
||||||
|
@ -38,7 +37,7 @@ void AvatarUpdate::synchronousProcess() {
|
||||||
|
|
||||||
// transform the head pose from the displayPlugin into avatar coordinates.
|
// transform the head pose from the displayPlugin into avatar coordinates.
|
||||||
glm::mat4 invAvatarMat = glm::inverse(createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()));
|
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()) {
|
if (!isThreaded()) {
|
||||||
process();
|
process();
|
||||||
|
|
|
@ -1258,7 +1258,7 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl
|
||||||
if (qApp->isHMDMode()) {
|
if (qApp->isHMDMode()) {
|
||||||
glm::vec3 cameraPosition = qApp->getCamera()->getPosition();
|
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);
|
glm::mat4 leftEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Left);
|
||||||
leftEyePose = leftEyePose * headPose;
|
leftEyePose = leftEyePose * headPose;
|
||||||
glm::vec3 leftEyePosition = extractTranslation(leftEyePose);
|
glm::vec3 leftEyePosition = extractTranslation(leftEyePose);
|
||||||
|
|
|
@ -342,7 +342,7 @@ void CompositorHelper::computeHmdPickRay(const glm::vec2& cursorPos, glm::vec3&
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 CompositorHelper::getUiTransform() const {
|
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
|
//Finds the collision point of a world space ray
|
||||||
|
|
|
@ -160,4 +160,8 @@ void HmdDisplayPlugin::updateFrameData() {
|
||||||
Parent::updateFrameData();
|
Parent::updateFrameData();
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
_currentRenderEyePoses = _renderEyePoses[_currentRenderFrameIndex];
|
_currentRenderEyePoses = _renderEyePoses[_currentRenderFrameIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 HmdDisplayPlugin::getHeadPose() const {
|
||||||
|
return _headPoseCache.get();
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ThreadSafeValueCache.h>
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
#include "../OpenGLDisplayPlugin.h"
|
#include "../OpenGLDisplayPlugin.h"
|
||||||
|
@ -24,7 +26,7 @@ public:
|
||||||
void setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) override final;
|
void setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) override final;
|
||||||
bool isDisplayVisible() const override { return isHmdMounted(); }
|
bool isDisplayVisible() const override { return isHmdMounted(); }
|
||||||
|
|
||||||
|
virtual glm::mat4 getHeadPose() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void hmdPresent() = 0;
|
virtual void hmdPresent() = 0;
|
||||||
|
@ -46,6 +48,7 @@ protected:
|
||||||
using EyePoses = std::array<glm::mat4, 2>;
|
using EyePoses = std::array<glm::mat4, 2>;
|
||||||
QMap<uint32_t, EyePoses> _renderEyePoses;
|
QMap<uint32_t, EyePoses> _renderEyePoses;
|
||||||
EyePoses _currentRenderEyePoses;
|
EyePoses _currentRenderEyePoses;
|
||||||
|
ThreadSafeValueCache<glm::mat4> _headPoseCache { glm::mat4() };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _enablePreview { false };
|
bool _enablePreview { false };
|
||||||
|
|
|
@ -121,8 +121,12 @@ public:
|
||||||
static const glm::mat4 transform; return transform;
|
static const glm::mat4 transform; return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const {
|
// will query the underlying hmd api to compute the most recent head pose
|
||||||
static const glm::mat4 pose; return pose;
|
virtual void updateHeadPose(uint32_t frameIndex) {}
|
||||||
|
|
||||||
|
// 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
|
// Needed for timewarp style features
|
||||||
|
|
|
@ -15,14 +15,11 @@ void OculusBaseDisplayPlugin::resetSensors() {
|
||||||
ovr_RecenterPose(_session);
|
ovr_RecenterPose(_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
|
void OculusBaseDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
||||||
static uint32_t lastFrameSeen = 0;
|
|
||||||
auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex);
|
auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex);
|
||||||
auto trackingState = ovr_GetTrackingState(_session, displayTime, frameIndex > lastFrameSeen);
|
auto trackingState = ovr_GetTrackingState(_session, displayTime, true);
|
||||||
if (frameIndex > lastFrameSeen) {
|
mat4 headPose = toGlm(trackingState.HeadPose.ThePose);
|
||||||
lastFrameSeen = frameIndex;
|
_headPoseCache.set(headPose);
|
||||||
}
|
|
||||||
return toGlm(trackingState.HeadPose.ThePose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OculusBaseDisplayPlugin::isSupported() const {
|
bool OculusBaseDisplayPlugin::isSupported() const {
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
|
|
||||||
// Stereo specific methods
|
// Stereo specific methods
|
||||||
virtual void resetSensors() override final;
|
virtual void resetSensors() override final;
|
||||||
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
|
virtual void updateHeadPose(uint32_t frameIndex) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void customizeContext() override;
|
void customizeContext() override;
|
||||||
|
|
|
@ -35,14 +35,10 @@ void OculusLegacyDisplayPlugin::resetSensors() {
|
||||||
ovrHmd_RecenterPose(_hmd);
|
ovrHmd_RecenterPose(_hmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 OculusLegacyDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
|
void OculusLegacyDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
||||||
static uint32_t lastFrameSeen = 0;
|
Lock lock(_mutex);
|
||||||
if (frameIndex > lastFrameSeen) {
|
_trackingState = ovrHmd_GetTrackingState(_hmd, ovr_GetTimeInSeconds());
|
||||||
Lock lock(_mutex);
|
_headPoseCache.set(toGlm(_trackingState.HeadPose.ThePose));
|
||||||
_trackingState = ovrHmd_GetTrackingState(_hmd, ovr_GetTimeInSeconds());
|
|
||||||
lastFrameSeen = frameIndex;
|
|
||||||
}
|
|
||||||
return toGlm(_trackingState.HeadPose.ThePose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OculusLegacyDisplayPlugin::isSupported() const {
|
bool OculusLegacyDisplayPlugin::isSupported() const {
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
|
|
||||||
// Stereo specific methods
|
// Stereo specific methods
|
||||||
virtual void resetSensors() override;
|
virtual void resetSensors() override;
|
||||||
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
|
virtual void updateHeadPose(uint32_t frameIndex) override;
|
||||||
|
|
||||||
virtual float getTargetFrameRate() override;
|
virtual float getTargetFrameRate() override;
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ void OpenVrDisplayPlugin::resetSensors() {
|
||||||
_sensorResetMat = glm::inverse(cancelOutRollAndPitch(m));
|
_sensorResetMat = glm::inverse(cancelOutRollAndPitch(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
|
void OpenVrDisplayPlugin::updateHeadPose(uint32_t frameIndex) {
|
||||||
|
|
||||||
float displayFrequency = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float);
|
float displayFrequency = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float);
|
||||||
float frameDuration = 1.f / displayFrequency;
|
float frameDuration = 1.f / displayFrequency;
|
||||||
|
@ -139,14 +139,15 @@ glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
|
||||||
_trackedDeviceLinearVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vVelocity));
|
_trackedDeviceLinearVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vVelocity));
|
||||||
_trackedDeviceAngularVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vAngularVelocity));
|
_trackedDeviceAngularVelocities[i] = transformVectorFast(_sensorResetMat, toGlm(_trackedDevicePose[i].vAngularVelocity));
|
||||||
}
|
}
|
||||||
return _trackedDevicePoseMat4[0];
|
|
||||||
|
_headPoseCache.set(_trackedDevicePoseMat4[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenVrDisplayPlugin::hmdPresent() {
|
void OpenVrDisplayPlugin::hmdPresent() {
|
||||||
// Flip y-axis since GL UV coords are backwards.
|
// Flip y-axis since GL UV coords are backwards.
|
||||||
static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
|
static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
|
||||||
static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 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 };
|
vr::Texture_t texture { (void*)oglplus::GetName(_compositeFramebuffer->color), vr::API_OpenGL, vr::ColorSpace_Auto };
|
||||||
|
|
||||||
_compositor->Submit(vr::Eye_Left, &texture, &leftBounds);
|
_compositor->Submit(vr::Eye_Left, &texture, &leftBounds);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
|
|
||||||
// Stereo specific methods
|
// Stereo specific methods
|
||||||
virtual void resetSensors() override;
|
virtual void resetSensors() override;
|
||||||
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
|
virtual void updateHeadPose(uint32_t frameIndex) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void internalActivate() override;
|
void internalActivate() override;
|
||||||
|
|
Loading…
Reference in a new issue