From e32eb38c3bcdb6629fddb7536b3ca37e2cb6b1cc Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 28 Sep 2015 14:38:03 -0700 Subject: [PATCH 1/2] Fix for Oculus timewarp judder introduced by 20d784ba39db Moved myAvatar->updateFromHMDSensorMatrix from Application::update back into Application::paintGL, so it occurs between displayPlugin->preRender() and displayPlugin->display(). We should render with the most up-to-date camera position as possible, and sample it at the same frequency as the display rate. --- interface/src/Application.cpp | 6 +++--- interface/src/avatar/MyAvatar.cpp | 10 +++++++++- interface/src/avatar/MyAvatar.h | 4 +++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 53e40b5bd3..d33f752cfe 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1055,6 +1055,9 @@ void Application::paintGL() { displayPlugin->preRender(); _offscreenContext->makeCurrent(); + // update the avatar with a fresh HMD pose + _myAvatar->updateFromHMDSensorMatrix(getHMDSensorPose()); + auto lodManager = DependencyManager::get(); @@ -2895,9 +2898,6 @@ void Application::update(float deltaTime) { userInputMapper->getActionState(UserInputMapper::SHIFT), RIGHT_HAND_INDEX); } - // update the avatar with a fresh HMD pose - _myAvatar->updateFromHMDSensorMatrix(getHMDSensorPose(), deltaTime); - updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... updateCamera(deltaTime); // handle various camera tweaks like off axis projection diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4cf1b69ce4..4fe9140b76 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -272,7 +272,15 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { // best called at start of main loop just after we have a fresh hmd pose. // update internal body position from new hmd pose. -void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix, float deltaTime) { +void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { + + auto now = usecTimestampNow(); + auto deltaUsecs = now - _lastUpdateFromHMDTime; + _lastUpdateFromHMDTime = now; + double actualDeltaTime = (double)deltaUsecs / (double)USECS_PER_SECOND; + const float BIGGEST_DELTA_TIME_SECS = 0.25f; + float deltaTime = glm::clamp((float)actualDeltaTime, 0.0f, BIGGEST_DELTA_TIME_SECS); + // update the sensorMatrices based on the new hmd pose _hmdSensorMatrix = hmdSensorMatrix; _hmdSensorPosition = extractTranslation(hmdSensorMatrix); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index c1a6ada751..daa4424928 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -68,7 +68,7 @@ public: // best called at start of main loop just after we have a fresh hmd pose. // update internal body position from new hmd pose. - void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix, float deltaTime); + void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. @@ -361,6 +361,8 @@ private: bool _straightingLean = false; float _straightingLeanAlpha = 0.0f; + + quint64 _lastUpdateFromHMDTime = usecTimestampNow(); }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); From c51ce792052db23bd872f9407d6a52180b27bd97 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 28 Sep 2015 15:30:21 -0700 Subject: [PATCH 2/2] Updated comment on MyAvatar::updateFromHMDSensorMatrix() --- interface/src/avatar/MyAvatar.cpp | 5 +++-- interface/src/avatar/MyAvatar.h | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4fe9140b76..16964735da 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -270,8 +270,9 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { return _sensorToWorldMatrix; } -// best called at start of main loop just after we have a fresh hmd pose. -// update internal body position from new hmd pose. +// Pass a recent sample of the HMD to the avatar. +// This can also update the avatar's position to follow the HMD +// as it moves through the world. void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { auto now = usecTimestampNow(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index daa4424928..bbc0667015 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -66,8 +66,9 @@ public: const glm::quat& getHMDSensorOrientation() const { return _hmdSensorOrientation; } glm::mat4 getSensorToWorldMatrix() const; - // best called at start of main loop just after we have a fresh hmd pose. - // update internal body position from new hmd pose. + // Pass a recent sample of the HMD to the avatar. + // This can also update the avatar's position to follow the HMD + // as it moves through the world. void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); // best called at end of main loop, just before rendering.