diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5036eefbd6..6fdcd8f797 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -234,7 +234,7 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { return AvatarData::toByteArray(cullSmallChanges, sendAll); } -void MyAvatar::reset(bool andRecenter) { +void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "reset", Q_ARG(bool, andRecenter)); @@ -244,8 +244,12 @@ void MyAvatar::reset(bool andRecenter) { // Reset dynamic state. _wasPushing = _isPushing = _isBraking = false; _follow.deactivate(); - _skeletonModel->reset(); - getHead()->reset(); + if (andReload) { + _skeletonModel->reset(); + } + if (andHead) { // which drives camera in desktop + getHead()->reset(); + } setThrust(glm::vec3(0.0f)); if (andRecenter) { @@ -261,8 +265,9 @@ void MyAvatar::reset(bool andRecenter) { setPosition(worldBodyPos); setOrientation(worldBodyRot); - // now sample the new hmd orientation AFTER sensor reset. - updateFromHMDSensorMatrix(qApp->getHMDSensorPose()); + // now sample the new hmd orientation AFTER sensor reset, which should be identity. + glm::mat4 identity; + updateFromHMDSensorMatrix(identity); // update the body in sensor space using the new hmd sensor sample _bodySensorMatrix = deriveBodyFromHMDSensor(); @@ -729,6 +734,7 @@ void MyAvatar::saveData() { settings.setValue("displayName", _displayName); settings.setValue("collisionSoundURL", _collisionSoundURL); settings.setValue("useSnapTurn", _useSnapTurn); + settings.setValue("clearOverlayWhenDriving", _clearOverlayWhenDriving); settings.endGroup(); } @@ -849,6 +855,7 @@ void MyAvatar::loadData() { setDisplayName(settings.value("displayName").toString()); setCollisionSoundURL(settings.value("collisionSoundURL", DEFAULT_AVATAR_COLLISION_SOUND_URL).toString()); setSnapTurn(settings.value("useSnapTurn", _useSnapTurn).toBool()); + setClearOverlayWhenDriving(settings.value("clearOverlayWhenDriving", _clearOverlayWhenDriving).toBool()); settings.endGroup(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 1b335fe294..d3da32e0ed 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -94,7 +94,7 @@ public: AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; } AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; } - Q_INVOKABLE void reset(bool andRecenter = false); + Q_INVOKABLE void reset(bool andRecenter = false, bool andReload = true, bool andHead = true); void update(float deltaTime); virtual void postUpdate(float deltaTime) override; void preDisplaySide(RenderArgs* renderArgs); @@ -160,6 +160,8 @@ public: Q_INVOKABLE bool getSnapTurn() const { return _useSnapTurn; } Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; } + Q_INVOKABLE bool getClearOverlayWhenDriving() const { return _clearOverlayWhenDriving; } + Q_INVOKABLE void setClearOverlayWhenDriving(bool on) { _clearOverlayWhenDriving = on; } // get/set avatar data void saveData(); @@ -396,6 +398,7 @@ private: QString _fullAvatarModelName; QUrl _animGraphUrl {""}; bool _useSnapTurn { true }; + bool _clearOverlayWhenDriving { false }; // cache of the current HMD sensor position and orientation // in sensor space. diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 95054869e5..83d729779c 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -67,6 +67,40 @@ void OverlayConductor::update(float dt) { } void OverlayConductor::updateMode() { + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + if (myAvatar->getClearOverlayWhenDriving()) { + float speed = glm::length(myAvatar->getVelocity()); + const float MIN_DRIVING = 0.2f; + const float MAX_NOT_DRIVING = 0.01f; + const quint64 REQUIRED_USECS_IN_NEW_MODE_BEFORE_INVISIBLE = 200 * 1000; + const quint64 REQUIRED_USECS_IN_NEW_MODE_BEFORE_VISIBLE = 1000 * 1000; + bool nowDriving = _driving; // Assume current _driving mode unless... + if (speed > MIN_DRIVING) { // ... we're definitely moving... + nowDriving = true; + } else if (speed < MAX_NOT_DRIVING) { // ... or definitely not. + nowDriving = false; + } + // Check that we're in this new mode for long enough to really trigger a transition. + if (nowDriving == _driving) { // If there's no change in state, clear any attepted timer. + _timeInPotentialMode = 0; + } else if (_timeInPotentialMode == 0) { // We've just changed with no timer, so start timing now. + _timeInPotentialMode = usecTimestampNow(); + } else if ((usecTimestampNow() - _timeInPotentialMode) > (nowDriving ? REQUIRED_USECS_IN_NEW_MODE_BEFORE_INVISIBLE : REQUIRED_USECS_IN_NEW_MODE_BEFORE_VISIBLE)) { + _timeInPotentialMode = 0; // a real transition + if (nowDriving) { + _wantsOverlays = Menu::getInstance()->isOptionChecked(MenuOption::Overlays); + } else { // reset when coming out of driving + _mode = FLAT; // Seems appropriate to let things reset, below, after the following. + // All reset of, e.g., room-scale location as though by apostrophe key, without all the other adjustments. + qApp->getActiveDisplayPlugin()->resetSensors(); + myAvatar->reset(true, false, false); + } + if (_wantsOverlays) { + setEnabled(!nowDriving, false); + } + _driving = nowDriving; + } // Else haven't accumulated enough time in new mode, but keep timing. + } Mode newMode; if (qApp->isHMDMode()) { @@ -84,10 +118,9 @@ void OverlayConductor::updateMode() { qApp->getApplicationCompositor().setModelTransform(identity); break; } - case STANDING: { + case STANDING: { // STANDING mode is not currently used. // enter the STANDING state // place the overlay at the current hmd position in world space - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); auto camMat = cancelOutRollAndPitch(myAvatar->getSensorToWorldMatrix() * qApp->getHMDSensorPose()); Transform t; t.setTranslation(extractTranslation(camMat)); @@ -103,15 +136,18 @@ void OverlayConductor::updateMode() { } _mode = newMode; + } -void OverlayConductor::setEnabled(bool enabled) { +void OverlayConductor::setEnabled(bool enabled, bool toggleQmlEvents) { if (enabled == _enabled) { return; } - Menu::getInstance()->setIsOptionChecked(MenuOption::Overlays, enabled); + if (toggleQmlEvents) { // Could recurse on us with the wrong toggleQmlEvents flag, and not need in the !toggleQmlEvent case anyway. + Menu::getInstance()->setIsOptionChecked(MenuOption::Overlays, enabled); + } _enabled = enabled; // set the new value @@ -124,8 +160,10 @@ void OverlayConductor::setEnabled(bool enabled) { qApp->getOverlays().enable(); // enable QML events - auto offscreenUi = DependencyManager::get(); - offscreenUi->getRootItem()->setEnabled(true); + if (toggleQmlEvents) { + auto offscreenUi = DependencyManager::get(); + offscreenUi->getRootItem()->setEnabled(true); + } if (_mode == STANDING) { // place the overlay at the current hmd position in world space @@ -144,8 +182,10 @@ void OverlayConductor::setEnabled(bool enabled) { qApp->getOverlays().disable(); // disable QML events - auto offscreenUi = DependencyManager::get(); - offscreenUi->getRootItem()->setEnabled(false); + if (toggleQmlEvents) { // I'd really rather always do this, but it looses drive state. bugzid:501 + auto offscreenUi = DependencyManager::get(); + offscreenUi->getRootItem()->setEnabled(false); + } } } diff --git a/interface/src/ui/OverlayConductor.h b/interface/src/ui/OverlayConductor.h index b94c5be7dd..99f4b56584 100644 --- a/interface/src/ui/OverlayConductor.h +++ b/interface/src/ui/OverlayConductor.h @@ -17,7 +17,7 @@ public: ~OverlayConductor(); void update(float dt); - void setEnabled(bool enable); + void setEnabled(bool enable, bool toggleQmlEvents = true); bool getEnabled() const; private: @@ -31,6 +31,9 @@ private: Mode _mode { FLAT }; bool _enabled { false }; + bool _driving { false }; + quint64 _timeInPotentialMode { 0 }; + bool _wantsOverlays { true }; }; #endif diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index cb68b36c24..ce7bcc6323 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -61,6 +61,11 @@ void setupPreferences() { auto setter = [=](bool value) { myAvatar->setSnapTurn(value); }; preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Snap turn when in HMD", getter, setter)); } + { + auto getter = [=]()->bool {return myAvatar->getClearOverlayWhenDriving(); }; + auto setter = [=](bool value) { myAvatar->setClearOverlayWhenDriving(value); }; + preferences->addPreference(new CheckPreference(AVATAR_BASICS, "Clear overlays when driving", getter, setter)); + } { auto getter = []()->QString { return Snapshot::snapshotsLocation.get(); }; auto setter = [](const QString& value) { Snapshot::snapshotsLocation.set(value); }; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index a92c5b5b22..3b6545ae96 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -13,6 +13,8 @@ void OculusBaseDisplayPlugin::resetSensors() { ovr_RecenterTrackingOrigin(_session); + + _currentRenderFrameInfo.renderPose = glm::mat4(); // identity } void OculusBaseDisplayPlugin::beginFrameRender(uint32_t frameIndex) {