From fc018257e1c5cec851da80c0b5366db03c6db04d Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 9 Oct 2019 12:20:35 -0700 Subject: [PATCH 01/31] Select avatar to look using API. Blink when look at change --- interface/src/avatar/MyAvatar.cpp | 28 +++++++++++++------ interface/src/avatar/MyAvatar.h | 2 ++ .../src/avatars-renderer/Head.cpp | 7 +++-- libraries/avatars/src/HeadData.cpp | 16 +++++++++++ libraries/avatars/src/HeadData.h | 15 ++++++---- 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ea0efe29cb..f529f168f4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2188,15 +2188,20 @@ void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) { foreach (const AvatarSharedPointer& avatarData, hash) { std::shared_ptr avatar = std::static_pointer_cast(avatarData); if (!avatar->isMyAvatar() && avatar->isInitialized()) { - glm::vec3 otherForward = avatar->getHead()->getForwardDirection(); - glm::vec3 otherPosition = avatar->getHead()->getEyePosition(); - const float TIME_WITHOUT_TALKING_THRESHOLD = 1.0f; - bool otherIsTalking = avatar->getHead()->getTimeWithoutTalking() <= TIME_WITHOUT_TALKING_THRESHOLD; - bool lookingAtOtherAlready = _lookAtTargetAvatar.lock().get() == avatar.get(); - float cost = lookAtCostFunction(myForward, myPosition, otherForward, otherPosition, otherIsTalking, lookingAtOtherAlready); - if (cost < bestCost) { - bestCost = cost; + if (_forceTargetAvatarID.isNull() || avatar->getID() != _forceTargetAvatarID) { + glm::vec3 otherForward = avatar->getHead()->getForwardDirection(); + glm::vec3 otherPosition = avatar->getHead()->getEyePosition(); + const float TIME_WITHOUT_TALKING_THRESHOLD = 1.0f; + bool otherIsTalking = avatar->getHead()->getTimeWithoutTalking() <= TIME_WITHOUT_TALKING_THRESHOLD; + bool lookingAtOtherAlready = _lookAtTargetAvatar.lock().get() == avatar.get(); + float cost = lookAtCostFunction(myForward, myPosition, otherForward, otherPosition, otherIsTalking, lookingAtOtherAlready); + if (cost < bestCost) { + bestCost = cost; + bestAvatar = avatar; + } + } else { bestAvatar = avatar; + break; } } } @@ -6838,3 +6843,10 @@ void MyAvatar::resetPointAt() { } } +void MyAvatar::setLookAtAvatarID(const QUuid& avatarID) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "setLookAtAvatarID", + Q_ARG(const QUuid&, avatarID)); + } + _forceTargetAvatarID = avatarID; +} \ No newline at end of file diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index a7ba639461..d93ee776be 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -971,6 +971,7 @@ public: * @param {Uuid} entityID - The entity that the hand touch effect will be enabled for. */ Q_INVOKABLE void enableHandTouchForID(const QUuid& entityID); + Q_INVOKABLE void setLookAtAvatarID(const QUuid& avatarID); bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); } void setUseAdvancedMovementControls(bool useAdvancedMovementControls) @@ -2656,6 +2657,7 @@ private: AvatarWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; + QUuid _forceTargetAvatarID; bool _shouldRender { true }; float _oculusYawOffset; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp index 63d8e2981c..a9dde201af 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp @@ -96,10 +96,13 @@ void Head::simulate(float deltaTime) { // no blinking when brows are raised; blink less with increasing loudness const float BASE_BLINK_RATE = 15.0f / 60.0f; const float ROOT_LOUDNESS_TO_BLINK_INTERVAL = 0.25f; - if (forceBlink || (_browAudioLift < EPSILON && shouldDo(glm::max(1.0f, sqrt(fabs(_averageLoudness - _longTermAverageLoudness)) * + if (_forceBlink || forceBlink || (_browAudioLift < EPSILON && shouldDo(glm::max(1.0f, sqrt(fabs(_averageLoudness - _longTermAverageLoudness)) * ROOT_LOUDNESS_TO_BLINK_INTERVAL) / BASE_BLINK_RATE, deltaTime))) { float randSpeedVariability = randFloat(); float eyeBlinkVelocity = BLINK_SPEED + randSpeedVariability * BLINK_SPEED_VARIABILITY; + if (_forceBlink) { + eyeBlinkVelocity = 0.5f * eyeBlinkVelocity; + } _leftEyeBlinkVelocity = eyeBlinkVelocity; _rightEyeBlinkVelocity = eyeBlinkVelocity; if (randFloat() < 0.5f) { @@ -114,7 +117,7 @@ void Head::simulate(float deltaTime) { if (_leftEyeBlink == FULLY_CLOSED) { _leftEyeBlinkVelocity = -BLINK_SPEED; - + updateEyeLookAt(); } else if (_leftEyeBlink == FULLY_OPEN) { _leftEyeBlinkVelocity = 0.0f; } diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index c86e534929..f8a09905ef 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -233,3 +233,19 @@ void HeadData::setHasProceduralEyeMovement(bool hasProceduralEyeMovement) { void HeadData::setFaceTrackerConnected(bool value) { _isFaceTrackerConnected = value; } + +void HeadData::setLookAtPosition(const glm::vec3& lookAtPosition) { + if (_requestLookAtPosition != lookAtPosition) { + _lookAtPositionChanged = usecTimestampNow(); + glm::vec3 oldAvatarLookAtVector = _requestLookAtPosition - _owningAvatar->getWorldPosition(); + glm::vec3 newAvatarLookAtVector = lookAtPosition - _owningAvatar->getWorldPosition(); + const float MIN_BLINK_ANGLE = 0.35f; // 20 degrees + _forceBlink = angleBetween(oldAvatarLookAtVector, newAvatarLookAtVector) > MIN_BLINK_ANGLE; + _lookAtUpdated = false; + } + _requestLookAtPosition = lookAtPosition; + if (_lookAtUpdated) { + _forceBlink = false; + _lookAtPosition = lookAtPosition; + } +} \ No newline at end of file diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index dc5aaf2595..a8005b5659 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -64,12 +64,7 @@ public: void setBlendshapeCoefficients(const QVector& blendshapeCoefficients) { _blendshapeCoefficients = blendshapeCoefficients; } const glm::vec3& getLookAtPosition() const { return _lookAtPosition; } - void setLookAtPosition(const glm::vec3& lookAtPosition) { - if (_lookAtPosition != lookAtPosition) { - _lookAtPositionChanged = usecTimestampNow(); - } - _lookAtPosition = lookAtPosition; - } + void setLookAtPosition(const glm::vec3& lookAtPosition); bool lookAtPositionChangedSince(quint64 time) { return _lookAtPositionChanged >= time; } bool getHasProceduralEyeFaceMovement() const; @@ -84,6 +79,11 @@ public: void setFaceTrackerConnected(bool value); bool getFaceTrackerConnected() const { return _isFaceTrackerConnected; } + void updateEyeLookAt() { + _lookAtPosition = _requestLookAtPosition; + _lookAtUpdated = true; + } + friend class AvatarData; QJsonObject toJson() const; @@ -95,6 +95,7 @@ protected: float _basePitch; float _baseRoll; + glm::vec3 _requestLookAtPosition; glm::vec3 _lookAtPosition; quint64 _lookAtPositionChanged { 0 }; @@ -115,6 +116,8 @@ protected: QVector _summedBlendshapeCoefficients; QMap _blendshapeLookupMap; AvatarData* _owningAvatar; + bool _forceBlink { false }; + bool _lookAtUpdated { false }; private: // privatize copy ctor and assignment operator so copies of this object cannot be made From 505813b3c356bfee7835a96c89f8e5d02a3db9bf Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 14 Oct 2019 10:44:55 -0700 Subject: [PATCH 02/31] Fix blink async and other is talking bug --- interface/src/avatar/MyAvatar.cpp | 15 +++++---------- interface/src/avatar/MyAvatar.h | 1 - .../src/avatars-renderer/Head.cpp | 8 +++++--- libraries/avatars/src/AvatarData.cpp | 9 +++++++++ libraries/avatars/src/AvatarData.h | 1 + libraries/avatars/src/HeadData.cpp | 16 ++++++++++------ libraries/avatars/src/HeadData.h | 7 ++----- 7 files changed, 32 insertions(+), 25 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f529f168f4..0abbd4e324 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2150,7 +2150,7 @@ static float lookAtCostFunction(const glm::vec3& myForward, const glm::vec3& myP const float DISTANCE_FACTOR = 3.14f; const float MY_ANGLE_FACTOR = 1.0f; const float OTHER_ANGLE_FACTOR = 1.0f; - const float OTHER_IS_TALKING_TERM = otherIsTalking ? 1.0f : 0.0f; + const float OTHER_IS_TALKING_TERM = otherIsTalking ? -1.0f : 0.0f; const float LOOKING_AT_OTHER_ALREADY_TERM = lookingAtOtherAlready ? -0.2f : 0.0f; const float GREATEST_LOOKING_AT_DISTANCE = 10.0f; // meters @@ -2176,6 +2176,9 @@ static float lookAtCostFunction(const glm::vec3& myForward, const glm::vec3& myP void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) { glm::vec3 myForward = _lookAtYaw * IDENTITY_FORWARD; + if (_skeletonModel->isLoaded()) { + myForward = getHeadJointFrontVector(); + } glm::vec3 myPosition = getHead()->getEyePosition(); CameraMode mode = qApp->getCamera().getMode(); if (mode == CAMERA_MODE_FIRST_PERSON) { @@ -2189,7 +2192,7 @@ void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) { std::shared_ptr avatar = std::static_pointer_cast(avatarData); if (!avatar->isMyAvatar() && avatar->isInitialized()) { if (_forceTargetAvatarID.isNull() || avatar->getID() != _forceTargetAvatarID) { - glm::vec3 otherForward = avatar->getHead()->getForwardDirection(); + glm::vec3 otherForward = avatar->getHeadJointFrontVector(); glm::vec3 otherPosition = avatar->getHead()->getEyePosition(); const float TIME_WITHOUT_TALKING_THRESHOLD = 1.0f; bool otherIsTalking = avatar->getHead()->getTimeWithoutTalking() <= TIME_WITHOUT_TALKING_THRESHOLD; @@ -6842,11 +6845,3 @@ void MyAvatar::resetPointAt() { POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING); } } - -void MyAvatar::setLookAtAvatarID(const QUuid& avatarID) { - if (QThread::currentThread() != thread()) { - BLOCKING_INVOKE_METHOD(this, "setLookAtAvatarID", - Q_ARG(const QUuid&, avatarID)); - } - _forceTargetAvatarID = avatarID; -} \ No newline at end of file diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index d93ee776be..3f91222392 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -971,7 +971,6 @@ public: * @param {Uuid} entityID - The entity that the hand touch effect will be enabled for. */ Q_INVOKABLE void enableHandTouchForID(const QUuid& entityID); - Q_INVOKABLE void setLookAtAvatarID(const QUuid& avatarID); bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); } void setUseAdvancedMovementControls(bool useAdvancedMovementControls) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp index a9dde201af..8184804e1f 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp @@ -96,12 +96,15 @@ void Head::simulate(float deltaTime) { // no blinking when brows are raised; blink less with increasing loudness const float BASE_BLINK_RATE = 15.0f / 60.0f; const float ROOT_LOUDNESS_TO_BLINK_INTERVAL = 0.25f; - if (_forceBlink || forceBlink || (_browAudioLift < EPSILON && shouldDo(glm::max(1.0f, sqrt(fabs(_averageLoudness - _longTermAverageLoudness)) * + if (_blinkToRetarget || forceBlink || + (_browAudioLift < EPSILON && shouldDo(glm::max(1.0f, sqrt(fabs(_averageLoudness - _longTermAverageLoudness)) * ROOT_LOUDNESS_TO_BLINK_INTERVAL) / BASE_BLINK_RATE, deltaTime))) { float randSpeedVariability = randFloat(); float eyeBlinkVelocity = BLINK_SPEED + randSpeedVariability * BLINK_SPEED_VARIABILITY; - if (_forceBlink) { + if (_blinkToRetarget) { + // Slow down by half the blink if reseting eye target eyeBlinkVelocity = 0.5f * eyeBlinkVelocity; + _blinkToRetarget = false; } _leftEyeBlinkVelocity = eyeBlinkVelocity; _rightEyeBlinkVelocity = eyeBlinkVelocity; @@ -123,7 +126,6 @@ void Head::simulate(float deltaTime) { } if (_rightEyeBlink == FULLY_CLOSED) { _rightEyeBlinkVelocity = -BLINK_SPEED; - } else if (_rightEyeBlink == FULLY_OPEN) { _rightEyeBlinkVelocity = 0.0f; } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a91154ff15..69694a00c3 100755 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -3214,3 +3214,12 @@ void AvatarData::clearAvatarGrabData(const QUuid& grabID) { } }); } + +glm::vec3 AvatarData::getHeadJointFrontVector() const { + int headJointIndex = getJointIndex("Head"); + glm::quat headJointRotation = Quaternions::Y_180 * getAbsoluteJointRotationInObjectFrame(headJointIndex);// getAbsoluteJointRotationInRigFrame(headJointIndex, headJointRotation); + headJointRotation = getWorldOrientation() * headJointRotation; + float headYaw = safeEulerAngles(headJointRotation).y; + glm::quat headYawRotation = glm::angleAxis(headYaw, Vectors::UP); + return headYawRotation * IDENTITY_FORWARD; +} diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 59a2e2a53e..bfe775e972 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1484,6 +1484,7 @@ public: std::vector getSkeletonData() const; void sendSkeletonData() const; QVector getJointData() const; + glm::vec3 getHeadJointFrontVector() const; signals: diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index f8a09905ef..7d05a50143 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -240,12 +240,16 @@ void HeadData::setLookAtPosition(const glm::vec3& lookAtPosition) { glm::vec3 oldAvatarLookAtVector = _requestLookAtPosition - _owningAvatar->getWorldPosition(); glm::vec3 newAvatarLookAtVector = lookAtPosition - _owningAvatar->getWorldPosition(); const float MIN_BLINK_ANGLE = 0.35f; // 20 degrees - _forceBlink = angleBetween(oldAvatarLookAtVector, newAvatarLookAtVector) > MIN_BLINK_ANGLE; + _blinkToRetarget = angleBetween(oldAvatarLookAtVector, newAvatarLookAtVector) > MIN_BLINK_ANGLE; _lookAtUpdated = false; + } + if (_lookAtUpdated) { + _lookAtPosition = lookAtPosition; } _requestLookAtPosition = lookAtPosition; - if (_lookAtUpdated) { - _forceBlink = false; - _lookAtPosition = lookAtPosition; - } -} \ No newline at end of file +} + +void HeadData::updateEyeLookAt() { + _lookAtPosition = _requestLookAtPosition; + _lookAtUpdated = true; +} diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index a8005b5659..7b73f57113 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -79,10 +79,7 @@ public: void setFaceTrackerConnected(bool value); bool getFaceTrackerConnected() const { return _isFaceTrackerConnected; } - void updateEyeLookAt() { - _lookAtPosition = _requestLookAtPosition; - _lookAtUpdated = true; - } + void updateEyeLookAt(); friend class AvatarData; @@ -116,7 +113,7 @@ protected: QVector _summedBlendshapeCoefficients; QMap _blendshapeLookupMap; AvatarData* _owningAvatar; - bool _forceBlink { false }; + bool _blinkToRetarget { false }; bool _lookAtUpdated { false }; private: From b793e23cb096b922de2f793619e3c2de926ce94f Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 15 Oct 2019 15:24:41 +1300 Subject: [PATCH 03/31] Keyboard JSDoc --- .../scripting/KeyboardScriptingInterface.h | 61 ++++++++++++++++++- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/interface/src/scripting/KeyboardScriptingInterface.h b/interface/src/scripting/KeyboardScriptingInterface.h index 41c5ab7644..dc680b05cf 100644 --- a/interface/src/scripting/KeyboardScriptingInterface.h +++ b/interface/src/scripting/KeyboardScriptingInterface.h @@ -18,15 +18,23 @@ #include "DependencyManager.h" /**jsdoc - * The Keyboard API provides facilities to use 3D Physical keyboard. + * The Keyboard API provides facilities to use an in-world, virtual keyboard. When enabled, this keyboard is + * displayed instead of the 2D keyboard that raises at the bottom of the tablet or Web entities when a text input field has + * focus and you're in HMD mode. + * * @namespace Keyboard * * @hifi-interface * @hifi-client-entity * @hifi-avatar * - * @property {bool} raised - true If the keyboard is visible false otherwise - * @property {bool} password - true Will show * instead of characters in the text display false otherwise + * @property {boolean} raised - true if the virtual keyboard is visible, false if it isn't. + * @property {boolean} password - true if "*"s are displayed on the virtual keyboard's display + * instead of the characters typed, false if the actual characters are displayed. + * @property {boolean} use3DKeyboard - true if user settings have "Use Virtual Keyboard" enabled, + * false if it's disabled. Read-only. + * @property {boolean} preferMalletsOverLasers - true if user settings for the virtual keyboard have "Mallets" + * selected, false if "Lasers" is selected. Read-only. */ class KeyboardScriptingInterface : public QObject, public Dependency { @@ -39,14 +47,61 @@ class KeyboardScriptingInterface : public QObject, public Dependency { public: KeyboardScriptingInterface() = default; ~KeyboardScriptingInterface() = default; + + /**jsdoc + * Loads a JSON file that defines the virtual keyboard's layout. The default JSON file used is + * {@link https://github.com/highfidelity/hifi/blob/master/interface/resources/config/keyboard.json|https://github.com/highfidelity/hifi/.../keyboard.json}. + * @function Keyboard.loadKeyboardFile + * @param {string} path - The keyboard JSON file. + */ Q_INVOKABLE void loadKeyboardFile(const QString& string); + + /**jsdoc + * Enables the left mallet so that it is displayed when in HMD mode. + * @function Keyboard.enableLeftMallet + */ Q_INVOKABLE void enableLeftMallet(); + + /**jsdoc + * Enables the right mallet so that it is displayed when in HMD mode. + * @function Keyboard.enableRightMallet + */ Q_INVOKABLE void enableRightMallet(); + + /**jsdoc + * Disables the left mallet so that it is not displayed when in HMD mode. + * @function Keyboard.disableLeftMallet + */ Q_INVOKABLE void disableLeftMallet(); + + /**jsdoc + * Disables the right mallet so that it is not displayed when in HMD mode. + * @function Keyboard.disableRightMallet + */ Q_INVOKABLE void disableRightMallet(); + + /**jsdoc + * Configures the virtual keyboard to recognize a ray pointer as the left hand's laser. + * @function Keyboard.setLeftHandLaser + * @param {number} leftHandLaser - The ID of a ray pointer created by {@link Pointers.createPointer}. + */ Q_INVOKABLE void setLeftHandLaser(unsigned int leftHandLaser); + + /**jsdoc + * Configures the virtual keyboard to recognize a ray pointer as the right hand's laser. + * @function Keyboard.setRightHandLaser + * @param {number} rightHandLaser - The ID of a ray pointer created by {@link Pointers.createPointer}. + */ Q_INVOKABLE void setRightHandLaser(unsigned int rightHandLaser); + + /**jsdoc + * Checks whether an entity is part of the virtual keyboard. + * @function Keyboard.containsID + * @param {Uuid} entityID - The entity ID. + * @returns {boolean} true if the entity is part of the virtual keyboard, false if it isn't. + */ Q_INVOKABLE bool containsID(const QUuid& overlayID) const; + private: bool getPreferMalletsOverLasers() const; bool isRaised() const; From 9f0e82e1e65deeaf372645bac81443deb402f70a Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 16 Oct 2019 15:29:28 -0700 Subject: [PATCH 04/31] Improve eye's look at and blinking. Fix look at update --- interface/src/avatar/MyAvatar.cpp | 5 ++-- .../src/avatars-renderer/Head.cpp | 6 ++-- libraries/avatars/src/AvatarData.h | 1 + libraries/avatars/src/HeadData.cpp | 30 ++++++++++++------- libraries/avatars/src/HeadData.h | 4 +-- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 0abbd4e324..2bc0ae32d4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -6709,8 +6709,9 @@ void MyAvatar::updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera) if (headPose.isValid()) { lookAtSpot = transformPoint(headPose.getMatrix(), glm::vec3(0.0f, 0.0f, TREE_SCALE)); } else { - lookAtSpot = myHead->getEyePosition() + - (getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); + lookAtSpot = _shouldTurnToFaceCamera ? + myHead->getLookAtPosition() : + myHead->getEyePosition() + getHeadJointFrontVector() * (float)TREE_SCALE; } } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp index 8184804e1f..e2f5ef0c60 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp @@ -96,15 +96,15 @@ void Head::simulate(float deltaTime) { // no blinking when brows are raised; blink less with increasing loudness const float BASE_BLINK_RATE = 15.0f / 60.0f; const float ROOT_LOUDNESS_TO_BLINK_INTERVAL = 0.25f; - if (_blinkToRetarget || forceBlink || + if (_forceBlinkToRetarget || forceBlink || (_browAudioLift < EPSILON && shouldDo(glm::max(1.0f, sqrt(fabs(_averageLoudness - _longTermAverageLoudness)) * ROOT_LOUDNESS_TO_BLINK_INTERVAL) / BASE_BLINK_RATE, deltaTime))) { float randSpeedVariability = randFloat(); float eyeBlinkVelocity = BLINK_SPEED + randSpeedVariability * BLINK_SPEED_VARIABILITY; - if (_blinkToRetarget) { + if (_forceBlinkToRetarget) { // Slow down by half the blink if reseting eye target eyeBlinkVelocity = 0.5f * eyeBlinkVelocity; - _blinkToRetarget = false; + _forceBlinkToRetarget = false; } _leftEyeBlinkVelocity = eyeBlinkVelocity; _rightEyeBlinkVelocity = eyeBlinkVelocity; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index bfe775e972..61729f8db3 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1480,6 +1480,7 @@ public: void setIsNewAvatar(bool isNewAvatar) { _isNewAvatar = isNewAvatar; } bool getIsNewAvatar() { return _isNewAvatar; } void setIsClientAvatar(bool isClientAvatar) { _isClientAvatar = isClientAvatar; } + bool getIsClientAvatar() const { return _isClientAvatar; } void setSkeletonData(const std::vector& skeletonData); std::vector getSkeletonData() const; void sendSkeletonData() const; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index 7d05a50143..d9998883d7 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -235,21 +235,29 @@ void HeadData::setFaceTrackerConnected(bool value) { } void HeadData::setLookAtPosition(const glm::vec3& lookAtPosition) { - if (_requestLookAtPosition != lookAtPosition) { - _lookAtPositionChanged = usecTimestampNow(); - glm::vec3 oldAvatarLookAtVector = _requestLookAtPosition - _owningAvatar->getWorldPosition(); - glm::vec3 newAvatarLookAtVector = lookAtPosition - _owningAvatar->getWorldPosition(); - const float MIN_BLINK_ANGLE = 0.35f; // 20 degrees - _blinkToRetarget = angleBetween(oldAvatarLookAtVector, newAvatarLookAtVector) > MIN_BLINK_ANGLE; - _lookAtUpdated = false; - } - if (_lookAtUpdated) { + if (_owningAvatar->getIsClientAvatar() || _owningAvatar->isMyAvatar()) { + if (_isEyeLookAtUpdated && _requestLookAtPosition != lookAtPosition) { + _lookAtPositionChanged = usecTimestampNow(); + glm::vec3 oldAvatarLookAtVector = _requestLookAtPosition - _owningAvatar->getWorldPosition(); + glm::vec3 newAvatarLookAtVector = lookAtPosition - _owningAvatar->getWorldPosition(); + const float MIN_BLINK_ANGLE = 0.35f; // 20 degrees + _forceBlinkToRetarget = angleBetween(oldAvatarLookAtVector, newAvatarLookAtVector) > MIN_BLINK_ANGLE; + if (_forceBlinkToRetarget) { + _isEyeLookAtUpdated = false; + } else { + _lookAtPosition = lookAtPosition; + } + } + _requestLookAtPosition = lookAtPosition; + } else { + if (_lookAtPosition != lookAtPosition) { + _lookAtPositionChanged = usecTimestampNow(); + } _lookAtPosition = lookAtPosition; } - _requestLookAtPosition = lookAtPosition; } void HeadData::updateEyeLookAt() { _lookAtPosition = _requestLookAtPosition; - _lookAtUpdated = true; + _isEyeLookAtUpdated = true; } diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index 7b73f57113..190b179f25 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -113,8 +113,8 @@ protected: QVector _summedBlendshapeCoefficients; QMap _blendshapeLookupMap; AvatarData* _owningAvatar; - bool _blinkToRetarget { false }; - bool _lookAtUpdated { false }; + bool _forceBlinkToRetarget { false }; + bool _isEyeLookAtUpdated { false }; private: // privatize copy ctor and assignment operator so copies of this object cannot be made From 3bcb305f70b0ec3fd1ad4fa58da5ef56e96d32f3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 18 Oct 2019 11:51:51 +1300 Subject: [PATCH 05/31] Santize LODManager.setWorldQualityDetail() parameter value --- interface/src/LODManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 3e47d88f3c..9fd7b0851a 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -397,7 +397,7 @@ void LODManager::setWorldDetailQuality(float quality) { static const float MIN_FPS = 10; static const float LOW = 0.25f; - bool isLowestValue = quality == LOW; + bool isLowestValue = quality <= LOW; bool isHMDMode = qApp->isHMDMode(); float maxFPS = isHMDMode ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; From c7e1fdaeacac2d5ea2f4099a7f150f8cd3577f1d Mon Sep 17 00:00:00 2001 From: amerhifi Date: Tue, 15 Oct 2019 08:55:53 -0700 Subject: [PATCH 06/31] adding hmd audio device info to deviceslist changing locations one more merge working on the threading issue changing offices, working on qml simple qml filtering fixed spacing problem when item is removed --- .../simplifiedUI/settingsApp/audio/Audio.qml | 12 +++--- .../hifi/simplifiedUI/settingsApp/vr/VR.qml | 13 +++--- interface/src/scripting/AudioDevices.cpp | 37 +++++++++++++--- interface/src/scripting/AudioDevices.h | 1 + libraries/audio-client/CMakeLists.txt | 2 +- libraries/audio-client/src/AudioClient.cpp | 42 +++++++++++++++---- .../audio-client/src/HifiAudioDeviceInfo.cpp | 1 + .../audio-client/src/HifiAudioDeviceInfo.h | 19 +++++++-- .../plugins/src/plugins/PluginManager.cpp | 16 ++++++- libraries/plugins/src/plugins/PluginManager.h | 2 +- 10 files changed, 111 insertions(+), 34 deletions(-) diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml index 108016ef8c..345c124725 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml @@ -258,13 +258,12 @@ Flickable { Layout.preferredHeight: contentItem.height Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin interactive: false - spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons clip: true model: AudioScriptingInterface.devices.input delegate: Item { - width: parent.width - height: inputDeviceCheckbox.height - + width: parent.width + height: model.type != "hmd" ? inputDeviceCheckbox.height + simplifiedUI.margins.settings.spacingBetweenRadiobuttons : 0 + visible: model.type != "hmd" SimplifiedControls.RadioButton { id: inputDeviceCheckbox anchors.left: parent.left @@ -354,13 +353,12 @@ Flickable { Layout.preferredHeight: contentItem.height Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin interactive: false - spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons clip: true model: AudioScriptingInterface.devices.output delegate: Item { width: parent.width - height: outputDeviceCheckbox.height - + height: model.type != "hmd" ? outputDeviceCheckbox.height +simplifiedUI.margins.settings.spacingBetweenRadiobuttons : 0 + visible: model.type != "hmd" SimplifiedControls.RadioButton { id: outputDeviceCheckbox anchors.left: parent.left diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml index 420ee11a05..cc64f8bd9f 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml @@ -259,13 +259,13 @@ Flickable { Layout.preferredHeight: contentItem.height Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin interactive: false - spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons clip: true model: AudioScriptingInterface.devices.input delegate: Item { - width: parent.width - height: inputDeviceCheckbox.height - + width: parent.width + height: model.type != "desktop" ? inputDeviceCheckbox.height + simplifiedUI.margins.settings.spacingBetweenRadiobuttons : 0 + visible: model.type != "desktop" + SimplifiedControls.RadioButton { id: inputDeviceCheckbox anchors.left: parent.left @@ -355,13 +355,12 @@ Flickable { Layout.preferredHeight: contentItem.height Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin interactive: false - spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons clip: true model: AudioScriptingInterface.devices.output delegate: Item { width: parent.width - height: outputDeviceCheckbox.height - + height: model.type != "desktop" ? outputDeviceCheckbox.height + simplifiedUI.margins.settings.spacingBetweenRadiobuttons : 0 + visible: model.type != "desktop" SimplifiedControls.RadioButton { id: outputDeviceCheckbox anchors.left: parent.left diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 8cc45a3bf5..f4cae04a5e 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -44,7 +44,8 @@ enum AudioDeviceRole { SelectedDesktopRole, SelectedHMDRole, PeakRole, - InfoRole + InfoRole, + TypeRole }; QHash AudioDeviceList::_roles { @@ -52,7 +53,8 @@ QHash AudioDeviceList::_roles { { SelectedDesktopRole, "selectedDesktop" }, { SelectedHMDRole, "selectedHMD" }, { PeakRole, "peak" }, - { InfoRole, "info" } + { InfoRole, "info" }, + { TypeRole, "type"} }; static QString getTargetDevice(bool hmd, QAudio::Mode mode) { @@ -144,6 +146,8 @@ QVariant AudioDeviceList::data(const QModelIndex& index, int role) const { return _devices.at(index.row())->selectedHMD; } else if (role == InfoRole) { return QVariant::fromValue(_devices.at(index.row())->info); + } else if (role == TypeRole) { + return _devices.at(index.row())->type; } else { return QVariant(); } @@ -281,10 +285,18 @@ void AudioDeviceList::onDevicesChanged(const QList& devices device.info = deviceInfo; if (deviceInfo.isDefault()) { - if (deviceInfo.getMode() == QAudio::AudioInput) { - device.display = "Computer's default microphone (recommended)"; - } else { - device.display = "Computer's default audio (recommended)"; + if (deviceInfo.getDeviceType() == HifiAudioDeviceInfo::desktop) { + if (deviceInfo.getMode() == QAudio::AudioInput) { + device.display = "Computer's default microphone (recommended)"; + } else { + device.display = "Computer's default audio (recommended)"; + } + } else if (deviceInfo.getDeviceType() == HifiAudioDeviceInfo::hmd) { + if (deviceInfo.getMode() == QAudio::AudioInput) { + device.display = "Headset's default mic (recommended)"; + } else { + device.display = "Headset's default audio (recommended)"; + } } } else { device.display = device.info.deviceName() @@ -292,6 +304,19 @@ void AudioDeviceList::onDevicesChanged(const QList& devices .remove("Device") .replace(" )", ")"); } + + switch (deviceInfo.getDeviceType()) { + case HifiAudioDeviceInfo::hmd: + device.type = "hmd"; + break; + case HifiAudioDeviceInfo::desktop: + device.type = "desktop"; + break; + case HifiAudioDeviceInfo::both: + device.type = "both"; + break; + } + for (bool isHMD : {false, true}) { HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; diff --git a/interface/src/scripting/AudioDevices.h b/interface/src/scripting/AudioDevices.h index 13d97d53dd..3dc1949f80 100644 --- a/interface/src/scripting/AudioDevices.h +++ b/interface/src/scripting/AudioDevices.h @@ -29,6 +29,7 @@ public: QString display; bool selectedDesktop { false }; bool selectedHMD { false }; + QString type; }; class AudioDeviceList : public QAbstractListModel { diff --git a/libraries/audio-client/CMakeLists.txt b/libraries/audio-client/CMakeLists.txt index 6b88292dd4..03279b08f6 100644 --- a/libraries/audio-client/CMakeLists.txt +++ b/libraries/audio-client/CMakeLists.txt @@ -6,7 +6,7 @@ setup_hifi_library(Network Multimedia ${PLATFORM_QT_COMPONENTS}) link_hifi_libraries(audio plugins) include_hifi_library_headers(shared) include_hifi_library_headers(networking) - +include_hifi_library_headers(gpu) if (ANDROID) else () target_webrtc() diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index d29045c99b..344f52fc5a 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -47,7 +47,7 @@ #include #include #include - +#include #include "AudioClientLogging.h" #include "AudioLogging.h" #include "AudioHelpers.h" @@ -81,6 +81,21 @@ Mutex _recordMutex; HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode); +#include +static QString getHmdAudioDeviceName(QAudio::Mode mode) { + foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getAllDisplayPlugins()) { + if (displayPlugin && displayPlugin->isHmd()) { + if (mode == QAudio::AudioInput) { + return displayPlugin->getPreferredAudioInDevice(); + } else { + return displayPlugin->getPreferredAudioOutDevice(); + } + break; + } + } + return QString(); +} + // thread-safe QList getAvailableDevices(QAudio::Mode mode) { // NOTE: availableDevices() clobbers the Qt internal device list @@ -88,13 +103,26 @@ QList getAvailableDevices(QAudio::Mode mode) { auto devices = QAudioDeviceInfo::availableDevices(mode); QList newDevices; - for (auto& device : devices) { newDevices.push_back(HifiAudioDeviceInfo(device, false, mode)); } newDevices.push_front(defaultAudioDeviceForMode(mode)); - + + QString hmdDeviceName = getHmdAudioDeviceName(mode); + if (!hmdDeviceName.isNull() && !hmdDeviceName.isEmpty()) { + HifiAudioDeviceInfo hmdDevice; + foreach(auto device, newDevices) { + if (device.getDevice().deviceName() == hmdDeviceName) { + hmdDevice = HifiAudioDeviceInfo(device.getDevice(), true, mode, HifiAudioDeviceInfo::hmd); + break; + } + } + + if (!hmdDevice.getDevice().isNull()) { + newDevices.push_front(hmdDevice); + } + } return newDevices; } @@ -477,7 +505,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { // find a device in the list that matches the name we have and return it foreach(QAudioDeviceInfo audioDevice, devices){ if (audioDevice.deviceName() == CFStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman)) { - return HifiAudioDeviceInfo(audioDevice, true, mode); + return HifiAudioDeviceInfo(audioDevice, true, mode, HifiAudioDeviceInfo::desktop); } } } @@ -532,7 +560,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { HifiAudioDeviceInfo foundDevice; foreach(QAudioDeviceInfo audioDevice, devices) { if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { - foundDevice=HifiAudioDeviceInfo(audioDevice,true,mode); + foundDevice=HifiAudioDeviceInfo(audioDevice,true,mode, HifiAudioDeviceInfo::desktop); break; } } @@ -558,8 +586,8 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { } #endif // fallback for failed lookup is the default device - return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), true,mode) : - HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), true, mode); + return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), true,mode, HifiAudioDeviceInfo::desktop) : + HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), true, mode, HifiAudioDeviceInfo::desktop); } bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName) { diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.cpp b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp index 6e2d5fbe92..df18a2376e 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp @@ -22,6 +22,7 @@ HifiAudioDeviceInfo& HifiAudioDeviceInfo::operator=(const HifiAudioDeviceInfo& o _audioDeviceInfo = other.getDevice(); _mode = other.getMode(); _isDefault = other.isDefault(); + _deviceType = other.getDeviceType(); return *this; } diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 99520f1643..fadbbb6917 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -23,19 +23,28 @@ class HifiAudioDeviceInfo : public QObject { Q_OBJECT public: + enum deviceType { + desktop, + hmd, + both + }; + HifiAudioDeviceInfo() : QObject() {} HifiAudioDeviceInfo(const HifiAudioDeviceInfo &deviceInfo) : QObject(){ _audioDeviceInfo = deviceInfo.getDevice(); _mode = deviceInfo.getMode(); _isDefault = deviceInfo.isDefault(); + _deviceType = deviceInfo.getDeviceType(); } - HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode) : + + HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode, deviceType devType=both) : _audioDeviceInfo(deviceInfo), _isDefault(isDefault), - _mode(mode){ + _mode(mode), + _deviceType(devType){ } - + void setMode(QAudio::Mode mode) { _mode = mode; } void setIsDefault() { _isDefault = true; } void setDevice(QAudioDeviceInfo devInfo); @@ -52,15 +61,17 @@ public: QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } bool isDefault() const { return _isDefault; } QAudio::Mode getMode() const { return _mode; } - + deviceType getDeviceType() const { return _deviceType; } HifiAudioDeviceInfo& operator=(const HifiAudioDeviceInfo& other); bool operator==(const HifiAudioDeviceInfo& rhs) const; bool operator!=(const HifiAudioDeviceInfo& rhs) const; + private: QAudioDeviceInfo _audioDeviceInfo; bool _isDefault { false }; QAudio::Mode _mode { QAudio::AudioInput }; + deviceType _deviceType{ both }; public: static const QString DEFAULT_DEVICE_NAME; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 8f1184904e..1ecc4f1d45 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -221,7 +221,21 @@ const OculusPlatformPluginPointer PluginManager::getOculusPlatformPlugin() { return oculusPlatformPlugin; } -const DisplayPluginList& PluginManager::getDisplayPlugins() { +#include +#include + + +DisplayPluginList PluginManager::getAllDisplayPlugins() { + if (thread() != QThread::currentThread()) { + DisplayPluginList list; + QMetaObject::invokeMethod(this, "getAllDisplayPlugins", Qt::BlockingQueuedConnection, Q_RETURN_ARG(DisplayPluginList, list)); + return list; + } else { + return _displayPlugins; + } +} + + const DisplayPluginList& PluginManager::getDisplayPlugins() { static std::once_flag once; static auto deviceAddedCallback = [](QString deviceName) { qCDebug(plugins) << "Added device: " << deviceName; diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index eb377a2c8e..5ec82ea743 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -51,7 +51,7 @@ public: using PluginFilter = std::function; void setPluginFilter(PluginFilter pluginFilter) { _pluginFilter = pluginFilter; } - + Q_INVOKABLE DisplayPluginList getAllDisplayPlugins(); signals: void inputDeviceRunningChanged(const QString& pluginName, bool isRunning, const QStringList& runningDevices); From 421cff1cb21a7f75fe79232780adbc8a6e5f9b7c Mon Sep 17 00:00:00 2001 From: amerhifi Date: Fri, 18 Oct 2019 15:16:37 -0700 Subject: [PATCH 07/31] fixed naming to match standards --- interface/src/scripting/AudioDevices.cpp | 18 +++++++++--------- .../audio-client/src/HifiAudioDeviceInfo.cpp | 1 - .../audio-client/src/HifiAudioDeviceInfo.h | 8 ++++---- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index f4cae04a5e..7cabd49e93 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -306,15 +306,15 @@ void AudioDeviceList::onDevicesChanged(const QList& devices } switch (deviceInfo.getDeviceType()) { - case HifiAudioDeviceInfo::hmd: - device.type = "hmd"; - break; - case HifiAudioDeviceInfo::desktop: - device.type = "desktop"; - break; - case HifiAudioDeviceInfo::both: - device.type = "both"; - break; + case HifiAudioDeviceInfo::hmd: + device.type = "hmd"; + break; + case HifiAudioDeviceInfo::desktop: + device.type = "desktop"; + break; + case HifiAudioDeviceInfo::both: + device.type = "both"; + break; } diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.cpp b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp index df18a2376e..5cbb15ff73 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp @@ -26,7 +26,6 @@ HifiAudioDeviceInfo& HifiAudioDeviceInfo::operator=(const HifiAudioDeviceInfo& o return *this; } - bool HifiAudioDeviceInfo::operator==(const HifiAudioDeviceInfo& rhs) const { //Does the QAudioDeviceinfo match as well as is this the default device or return getDevice() == rhs.getDevice() && isDefault() == rhs.isDefault(); diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index fadbbb6917..9b77f77c9e 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -23,7 +23,7 @@ class HifiAudioDeviceInfo : public QObject { Q_OBJECT public: - enum deviceType { + enum DeviceType { desktop, hmd, both @@ -38,7 +38,7 @@ public: } - HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode, deviceType devType=both) : + HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode, DeviceType devType=both) : _audioDeviceInfo(deviceInfo), _isDefault(isDefault), _mode(mode), @@ -61,7 +61,7 @@ public: QAudioDeviceInfo getDevice() const { return _audioDeviceInfo; } bool isDefault() const { return _isDefault; } QAudio::Mode getMode() const { return _mode; } - deviceType getDeviceType() const { return _deviceType; } + DeviceType getDeviceType() const { return _deviceType; } HifiAudioDeviceInfo& operator=(const HifiAudioDeviceInfo& other); bool operator==(const HifiAudioDeviceInfo& rhs) const; bool operator!=(const HifiAudioDeviceInfo& rhs) const; @@ -71,7 +71,7 @@ private: QAudioDeviceInfo _audioDeviceInfo; bool _isDefault { false }; QAudio::Mode _mode { QAudio::AudioInput }; - deviceType _deviceType{ both }; + DeviceType _deviceType{ both }; public: static const QString DEFAULT_DEVICE_NAME; From ec7c8ce13c096705da241c97a281e622f397fa06 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Fri, 18 Oct 2019 16:50:36 -0700 Subject: [PATCH 08/31] updated default changes check to account for multiple devicetypes --- libraries/audio-client/src/AudioClient.cpp | 12 ++++++++++-- libraries/audio-client/src/AudioClient.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 344f52fc5a..418a45e5e9 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -138,8 +138,8 @@ void AudioClient::checkDevices() { auto inputDevices = getAvailableDevices(QAudio::AudioInput); auto outputDevices = getAvailableDevices(QAudio::AudioOutput); - QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, inputDevices.first()), Q_ARG(QAudio::Mode, QAudio::AudioInput)); - QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, outputDevices.first()), Q_ARG(QAudio::Mode, QAudio::AudioOutput)); + checkDefaultChanges(inputDevices); + checkDefaultChanges(outputDevices); Lock lock(_deviceMutex); if (inputDevices != _inputDevices) { @@ -153,6 +153,14 @@ void AudioClient::checkDevices() { } } +void AudioClient::checkDefaultChanges(QList& devices) { + foreach(auto device, devices) { + if (device.isDefault()) { + QMetaObject::invokeMethod(this, "changeDefault", Q_ARG(HifiAudioDeviceInfo, device), Q_ARG(QAudio::Mode, device.getMode())); + } + } +} + HifiAudioDeviceInfo AudioClient::getActiveAudioDevice(QAudio::Mode mode) const { Lock lock(_deviceMutex); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index b4ddb1018e..301b4d0fa5 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -238,6 +238,7 @@ public slots: bool shouldLoopbackInjectors() override { return _shouldEchoToServer; } Q_INVOKABLE void changeDefault(HifiAudioDeviceInfo newDefault, QAudio::Mode mode); + void checkDefaultChanges(QList& devices); // calling with a null QAudioDevice will use the system default bool switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo = HifiAudioDeviceInfo()); From a4fcb2c39e1fcc93df6c0d3883929580704b1a10 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 21 Oct 2019 14:31:15 -0700 Subject: [PATCH 09/31] Add eyesLookAtTarget set/get API methods --- interface/src/Application.cpp | 6 +++--- interface/src/Application.h | 2 +- interface/src/avatar/MyAvatar.cpp | 26 +++++++++++++++++++++++--- interface/src/avatar/MyAvatar.h | 23 +++++++++++++++++++++-- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4766353eba..7c0e822bed 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5814,14 +5814,14 @@ void Application::pushPostUpdateLambda(void* key, const std::function& f // to everyone. // The principal result is to call updateLookAtTargetAvatar() and then setLookAtPosition(). // Note that it is called BEFORE we update position or joints based on sensors, etc. -void Application::updateMyAvatarLookAtPosition() { +void Application::updateMyAvatarLookAtPosition(float deltaTime) { PerformanceTimer perfTimer("lookAt"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()"); auto myAvatar = getMyAvatar(); FaceTracker* faceTracker = getActiveFaceTracker(); - myAvatar->updateLookAtPosition(faceTracker, _myCamera); + myAvatar->updateEyesLookAtPosition(faceTracker, _myCamera, deltaTime); } void Application::updateThreads(float deltaTime) { @@ -6605,7 +6605,7 @@ void Application::update(float deltaTime) { { PROFILE_RANGE(simulation, "MyAvatar"); PerformanceTimer perfTimer("MyAvatar"); - qApp->updateMyAvatarLookAtPosition(); + qApp->updateMyAvatarLookAtPosition(deltaTime); avatarManager->updateMyAvatar(deltaTime); } } diff --git a/interface/src/Application.h b/interface/src/Application.h index af2348d1e9..2bb6c5ddb4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -298,7 +298,7 @@ public: virtual void pushPostUpdateLambda(void* key, const std::function& func) override; - void updateMyAvatarLookAtPosition(); + void updateMyAvatarLookAtPosition(float deltaTime); float getGameLoopRate() const { return _gameLoopCounter.rate(); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2bc0ae32d4..e152902b47 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2284,7 +2284,9 @@ void MyAvatar::updateLookAtTargetAvatar() { AvatarHash hash = DependencyManager::get()->getHashCopy(); // determine what the best look at target for my avatar should be. - computeMyLookAtTarget(hash); + if (!_scriptControlsEyesLookAt) { + computeMyLookAtTarget(hash); + } // snap look at position for avatars that are looking at me. snapOtherAvatarLookAtTargetsToMe(hash); @@ -6617,7 +6619,7 @@ bool MyAvatar::getIsJointOverridden(int jointIndex) const { return _skeletonModel->getIsJointOverridden(jointIndex); } -void MyAvatar::updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera) { +void MyAvatar::updateEyesLookAtPosition(FaceTracker* faceTracker, Camera& myCamera, float deltaTime) { updateLookAtTargetAvatar(); @@ -6647,6 +6649,13 @@ void MyAvatar::updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera) } else { lookAtSpot = myHead->getEyePosition() + glm::normalize(leftVec) * 1000.0f; } + } else if (_scriptControlsEyesLookAt) { + if (_scriptEyesControlTimer < MAX_LOOK_AT_TIME_SCRIPT_CONTROL) { + _scriptEyesControlTimer += deltaTime; + lookAtSpot = _eyesLookAtTarget; + } else { + _scriptControlsEyesLookAt = false; + } } else { controller::Pose leftEyePose = getControllerPoseInAvatarFrame(controller::Action::LEFT_EYE); controller::Pose rightEyePose = getControllerPoseInAvatarFrame(controller::Action::RIGHT_EYE); @@ -6731,7 +6740,7 @@ void MyAvatar::updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera) } } } - + _eyesLookAtTarget = lookAtSpot; getHead()->setLookAtPosition(lookAtSpot); } @@ -6814,6 +6823,17 @@ void MyAvatar::setHeadLookAt(const glm::vec3& lookAtTarget) { _lookAtScriptTarget = lookAtTarget; } +void MyAvatar::setEyesLookAt(const glm::vec3& lookAtTarget) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "setEyesLookAt", + Q_ARG(const glm::vec3&, lookAtTarget)); + return; + } + _eyesLookAtTarget = lookAtTarget; + _scriptEyesControlTimer = 0.0f; + _scriptControlsEyesLookAt = true; +} + glm::vec3 MyAvatar::getLookAtPivotPoint() { glm::vec3 avatarUp = getWorldOrientation() * Vectors::UP; glm::vec3 yAxisEyePosition = getWorldPosition() + avatarUp * glm::dot(avatarUp, _skeletonModel->getDefaultEyeModelPosition()); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 3f91222392..90c4157c3c 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1762,10 +1762,26 @@ public: /**jsdoc * Returns the current head look at target point in world coordinates. * @function MyAvatar.getHeadLookAt - * @returns {Vec3} Default position between your avatar's eyes in world coordinates. + * @returns {Vec3} The head's look at target in world coordinates. */ Q_INVOKABLE glm::vec3 getHeadLookAt() { return _lookAtCameraTarget; } + /**jsdoc + * Force the avatar's eyes to look to the specified location. + * Once this method is called, API calls will have full control of the eyes for a limited time. + * If this method is not called for two seconds, the engine will regain control of the eyes. + * @function MyAvatar.setEyesLookAt + * @param {Vec3} lookAtTarget - The target point in world coordinates. + */ + Q_INVOKABLE void setEyesLookAt(const glm::vec3& lookAtTarget); + + /**jsdoc + * Returns the current eyes look at target point in world coordinates. + * @function MyAvatar.getEyesLookAt + * @returns {Vec3} The eyes's look at target in world coordinates. + */ + Q_INVOKABLE glm::vec3 getEyesLookAt() { return _eyesLookAtTarget; } + /**jsdoc * Aims the pointing directional blending towards the provided target point. * The "point" reaction should be triggered before using this method. @@ -1903,7 +1919,7 @@ public: bool getFlowActive() const; bool getNetworkGraphActive() const; - void updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera); + void updateEyesLookAtPosition(FaceTracker* faceTracker, Camera& myCamera, float deltaTime); // sets the reaction enabled and triggered parameters of the passed in params // also clears internal reaction triggers @@ -2662,6 +2678,9 @@ private: eyeContactTarget _eyeContactTarget; float _eyeContactTargetTimer { 0.0f }; + glm::vec3 _eyesLookAtTarget; + bool _scriptControlsEyesLookAt{ false }; + float _scriptEyesControlTimer{ 0.0f }; glm::vec3 _trackedHeadPosition; From 6cb14219784d0cba05b2274d9bb5fb847cb4e9cf Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 21 Oct 2019 16:04:08 -0700 Subject: [PATCH 10/31] Qt patch for mac video --- tools/qt-builder/README.md | 9 +- tools/qt-builder/patches/mac-web-video.patch | 247 +++++++++++++++++++ 2 files changed, 253 insertions(+), 3 deletions(-) create mode 100644 tools/qt-builder/patches/mac-web-video.patch diff --git a/tools/qt-builder/README.md b/tools/qt-builder/README.md index 956dda4534..59db078aa9 100644 --- a/tools/qt-builder/README.md +++ b/tools/qt-builder/README.md @@ -1,8 +1,10 @@ # General This document describes the process to build Qt 5.12.3. -Note that there are three patches. The first (to qfloat16.h) is needed to compile QT 5.12.3 on Visual Studio 2017 due to a bug in Visual Studio (*bitset* will not compile. Note that there is a change in CMakeLists.txt to support this. -The second patch is to OpenSL ES audio. -The third is a patch to QScriptEngine to prevent crashes in QScriptEnginePrivate::reportAdditionalMemoryCost, during garbage collection. See https://bugreports.qt.io/browse/QTBUG-76176 +Note that there are several patches. +* The first (to qfloat16.h) is needed to compile QT 5.12.3 on Visual Studio 2017 due to a bug in Visual Studio (*bitset* will not compile. Note that there is a change in CMakeLists.txt to support this. +* The second patch is to OpenSL ES audio and allow audio echo cancelllation on Android. +* The third is a patch to QScriptEngine to prevent crashes in QScriptEnginePrivate::reportAdditionalMemoryCost, during garbage collection. See https://bugreports.qt.io/browse/QTBUG-76176 +* The fourth is a patch which fixes video playback on WebEngineViews on mac. See https://bugreports.qt.io/browse/QTBUG-70967 ## Requirements ### Windows 1. Visual Studio 2017 @@ -222,6 +224,7 @@ git clone --recursive git://code.qt.io/qt/qt5.git -b 5.12.3 --single-branch `cd qt5` `git apply --ignore-space-change --ignore-whitespace patches/aec.patch` `git apply --ignore-space-change --ignore-whitespace patches/qtscript-crash-fix.patch` +`git apply --ignore-space-change --ignore-whitespace patches/mac-web-video.patch` `cd ..` #### Configuring `mkdir qt5-install` diff --git a/tools/qt-builder/patches/mac-web-video.patch b/tools/qt-builder/patches/mac-web-video.patch new file mode 100644 index 0000000000..2ea81ce18b --- /dev/null +++ b/tools/qt-builder/patches/mac-web-video.patch @@ -0,0 +1,247 @@ +Submodule qtwebengine contains modified content +diff --git a/qtwebengine/src/core/stream_video_node.cpp b/qtwebengine/src/core/stream_video_node.cpp +index 29922f86..baa39d3b 100644 +--- a/qtwebengine/src/core/stream_video_node.cpp ++++ b/qtwebengine/src/core/stream_video_node.cpp +@@ -62,38 +62,45 @@ protected: + const char *vertexShader() const override { + // Keep in sync with cc::VertexShaderVideoTransform + static const char *shader = +- "attribute highp vec4 a_position;\n" +- "attribute mediump vec2 a_texCoord;\n" +- "uniform highp mat4 matrix;\n" +- "uniform highp mat4 texMatrix;\n" +- "varying mediump vec2 v_texCoord;\n" +- "void main() {\n" +- " gl_Position = matrix * a_position;\n" +- " v_texCoord = vec4(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0)).xy;\n" +- "}"; ++ R"SHADER(#version 150 core ++in vec4 a_position; ++in vec2 a_texCoord; ++uniform mat4 matrix; ++uniform mat4 texMatrix; ++out vec2 v_texCoord; ++void main() { ++ gl_Position = matrix * a_position; ++ v_texCoord = vec4(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0)).xy; ++} ++ )SHADER"; + return shader; + } + + const char *fragmentShader() const override { + // Keep in sync with cc::FragmentShaderRGBATexAlpha + static const char *shaderExternal = +- "#extension GL_OES_EGL_image_external : require\n" +- "varying mediump vec2 v_texCoord;\n" +- "uniform samplerExternalOES s_texture;\n" +- "uniform lowp float alpha;\n" +- "void main() {\n" +- " lowp vec4 texColor = texture2D(s_texture, v_texCoord);\n" +- " gl_FragColor = texColor * alpha;\n" +- "}"; ++ R"SHADER(#version 150 core ++#extension GL_OES_EGL_image_external : require ++in vec2 v_texCoord; ++uniform samplerExternalOES s_texture; ++uniform float alpha; ++out vec4 fragColor; ++void main() { ++ vec4 texColor = texture(s_texture, v_texCoord); ++ fragColor = texColor * alpha; ++} ++ )SHADER"; + static const char *shader2DRect = +- "#extension GL_ARB_texture_rectangle : require\n" +- "varying mediump vec2 v_texCoord;\n" +- "uniform sampler2DRect s_texture;\n" +- "uniform lowp float alpha;\n" +- "void main() {\n" +- " lowp vec4 texColor = texture2DRect(s_texture, v_texCoord);\n" +- " gl_FragColor = texColor * alpha;\n" +- "}"; ++ R"SHADER(#version 150 core ++in vec2 v_texCoord; ++uniform sampler2D s_texture; ++uniform float alpha; ++out vec4 fragColor; ++void main() { ++ vec4 texColor = texture(s_texture, v_texCoord); ++ fragColor = texColor * alpha; ++} ++ )SHADER"; + if (m_target == ExternalTarget) + return shaderExternal; + else +diff --git a/qtwebengine/src/core/yuv_video_node.cpp b/qtwebengine/src/core/yuv_video_node.cpp +index 4a436d95..dc4b6ff9 100644 +--- a/qtwebengine/src/core/yuv_video_node.cpp ++++ b/qtwebengine/src/core/yuv_video_node.cpp +@@ -59,39 +59,41 @@ public: + YUVVideoMaterialShader(const gfx::ColorSpace &colorSpace) + { + static const char *shaderHead = +- "varying mediump vec2 v_yaTexCoord;\n" +- "varying mediump vec2 v_uvTexCoord;\n" +- "uniform sampler2D y_texture;\n" +- "uniform sampler2D u_texture;\n" +- "uniform sampler2D v_texture;\n" +- "uniform mediump float alpha;\n" +- "uniform mediump vec4 ya_clamp_rect;\n" +- "uniform mediump vec4 uv_clamp_rect;\n"; +- static const char *shader = +- "void main() {\n" +- " mediump vec2 ya_clamped =\n" +- " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n" +- " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n" +- " mediump vec2 uv_clamped =\n" +- " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n" +- " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n" +- " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n" +- " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);\n" +- " mediump vec3 rgb = DoColorConversion(yuv);\n" +- " gl_FragColor = vec4(rgb, 1.0) * alpha;\n" +- "}"; ++ R"SHADER(#version 150 core ++in vec2 v_yaTexCoord; ++in vec2 v_uvTexCoord; ++uniform sampler2D y_texture; ++uniform sampler2D u_texture; ++uniform sampler2D v_texture; ++uniform float alpha; ++uniform vec4 ya_clamp_rect; ++uniform vec4 uv_clamp_rect; ++out vec4 fragColor; ++ )SHADER"; ++ ++ static const char *shader = R"SHADER( ++void main() { ++ vec2 ya_clamped = ++ max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); ++ float y_raw = texture(y_texture, ya_clamped).x; ++ vec2 uv_clamped = ++ max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); ++ float u_unsigned = texture(u_texture, uv_clamped).x; ++ float v_unsigned = texture(v_texture, uv_clamped).x; ++ vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned); ++ vec3 rgb = DoColorConversion(yuv); ++ fragColor = vec4(rgb, 1.0) * alpha; ++} ++ )SHADER"; ++ + // Invalid or unspecified color spaces should be treated as REC709. + gfx::ColorSpace src = colorSpace.IsValid() ? colorSpace : gfx::ColorSpace::CreateREC709(); + gfx::ColorSpace dst = gfx::ColorSpace::CreateSRGB(); + std::unique_ptr transform = + gfx::ColorTransform::NewColorTransform(src, dst, gfx::ColorTransform::Intent::INTENT_PERCEPTUAL); + +- QByteArray header(shaderHead); +- if (QOpenGLContext::currentContext()->isOpenGLES()) +- header = QByteArray("precision mediump float;\n") + header; +- + m_csShader = QByteArray::fromStdString(transform->GetShaderSource()); +- m_fragmentShader = header + m_csShader + QByteArray(shader); ++ m_fragmentShader = QByteArray(shaderHead) + m_csShader + QByteArray(shader); + } + void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; + +@@ -108,20 +110,22 @@ protected: + const char *vertexShader() const override { + // Keep in sync with logic in VertexShader in components/viz/service/display/shader.cc + const char *shader = +- "attribute highp vec4 a_position;\n" +- "attribute mediump vec2 a_texCoord;\n" +- "uniform highp mat4 matrix;\n" +- "varying mediump vec2 v_yaTexCoord;\n" +- "varying mediump vec2 v_uvTexCoord;\n" +- "uniform mediump vec2 yaTexScale;\n" +- "uniform mediump vec2 yaTexOffset;\n" +- "uniform mediump vec2 uvTexScale;\n" +- "uniform mediump vec2 uvTexOffset;\n" +- "void main() {\n" +- " gl_Position = matrix * a_position;\n" +- " v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset;\n" +- " v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset;\n" +- "}"; ++ R"SHADER(#version 150 core ++in vec4 a_position; ++in vec2 a_texCoord; ++uniform mat4 matrix; ++out vec2 v_yaTexCoord; ++out vec2 v_uvTexCoord; ++uniform vec2 yaTexScale; ++uniform vec2 yaTexOffset; ++uniform vec2 uvTexScale; ++uniform vec2 uvTexOffset; ++void main() { ++ gl_Position = matrix * a_position; ++ v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset; ++ v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset; ++} ++ )SHADER"; + return shader; + } + +@@ -168,33 +172,35 @@ public: + YUVAVideoMaterialShader(const gfx::ColorSpace &colorSpace) : YUVVideoMaterialShader(colorSpace) + { + static const char *shaderHead = +- "varying mediump vec2 v_yaTexCoord;\n" +- "varying mediump vec2 v_uvTexCoord;\n" +- "uniform sampler2D y_texture;\n" +- "uniform sampler2D u_texture;\n" +- "uniform sampler2D v_texture;\n" +- "uniform sampler2D a_texture;\n" +- "uniform mediump float alpha;\n" +- "uniform mediump vec4 ya_clamp_rect;\n" +- "uniform mediump vec4 uv_clamp_rect;\n"; ++ R"SHADER(#version 150 core ++in vec2 v_yaTexCoord; ++in vec2 v_uvTexCoord; ++uniform sampler2D y_texture; ++uniform sampler2D u_texture; ++uniform sampler2D v_texture; ++uniform sampler2D a_texture; ++uniform float alpha; ++uniform vec4 ya_clamp_rect; ++uniform vec4 uv_clamp_rect; ++out vec4 fragColor; ++ )SHADER"; + static const char *shader = +- "void main() {\n" +- " mediump vec2 ya_clamped =\n" +- " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n" +- " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n" +- " mediump vec2 uv_clamped =\n" +- " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n" +- " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n" +- " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n" +- " mediump float a_raw = texture2D(a_texture, ya_clamped).x;\n" +- " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);\n" +- " mediump vec3 rgb = DoColorConversion(yuv);\n" +- " gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);\n" +- "}"; +- QByteArray header(shaderHead); +- if (QOpenGLContext::currentContext()->isOpenGLES()) +- header = QByteArray("precision mediump float;\n") + header; +- m_fragmentShader = header + m_csShader + QByteArray(shader); ++ R"SHADER( ++void main() { ++ vec2 ya_clamped = ++ max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); ++ float y_raw = texture(y_texture, ya_clamped).x; ++ vec2 uv_clamped = ++ max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); ++ float u_unsigned = texture(u_texture, uv_clamped).x; ++ float v_unsigned = texture(v_texture, uv_clamped).x; ++ float a_raw = texture(a_texture, ya_clamped).x; ++ vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned); ++ vec3 rgb = DoColorConversion(yuv); ++ fragColor = vec4(rgb, 1.0) * (alpha * a_raw); ++} ++ )SHADER"; ++ m_fragmentShader = QByteArray(shaderHead) + m_csShader + QByteArray(shader); + } + void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; + From d8aa5fcc30c7241eb5128b7d1f49f278eda1f9ed Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 21 Oct 2019 16:10:56 -0700 Subject: [PATCH 11/31] Updated test code for video on mac --- tests-manual/qml/qml/MacQml.qml | 18 +++++++++++------- tests-manual/qml/src/MacQml.cpp | 2 +- tests-manual/qml/src/MacQml.h | 2 +- tests-manual/qml/src/StressWeb.h | 2 +- tests-manual/qml/src/TestCase.h | 6 +++--- tests-manual/qml/src/main.cpp | 14 ++++++++++++-- 6 files changed, 29 insertions(+), 15 deletions(-) diff --git a/tests-manual/qml/qml/MacQml.qml b/tests-manual/qml/qml/MacQml.qml index bb7e3a0dff..14749bb826 100644 --- a/tests-manual/qml/qml/MacQml.qml +++ b/tests-manual/qml/qml/MacQml.qml @@ -61,17 +61,21 @@ Item { Rectangle { width: 5 height: 5 - color: "red" - ColorAnimation on color { loops: Animation.Infinite; from: "red"; to: "yellow"; duration: 1000 } + color: "blue" + ColorAnimation on color { loops: Animation.Infinite; from: "blue"; to: "yellow"; duration: 1000 } } - WebEngineView { id: root - url: "https://google.com/" - x: 6; y: 6; - width: parent.width * 0.8 - height: parent.height * 0.8 + url: "https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/#19583796789766627" +// url: "https://vimeo.com/108650530" +// url: "https://www.youtube.com/watch?v=7EWQOeQf32U&autoplay=1&loop=1" +// x: 6; y: 6; + anchors.fill: parent +// width: parent.width * 0.8 +// height: parent.height * 0.8 } + + } diff --git a/tests-manual/qml/src/MacQml.cpp b/tests-manual/qml/src/MacQml.cpp index 9c5f91041e..aa732b7209 100644 --- a/tests-manual/qml/src/MacQml.cpp +++ b/tests-manual/qml/src/MacQml.cpp @@ -39,7 +39,7 @@ void MacQml::init() { _surface->load(url, callback); _surface->resize(_window->size()); _surface->resume(); - + _window->installEventFilter(_surface.get()); } void MacQml::draw() { diff --git a/tests-manual/qml/src/MacQml.h b/tests-manual/qml/src/MacQml.h index 50f71cb72e..b46349440e 100644 --- a/tests-manual/qml/src/MacQml.h +++ b/tests-manual/qml/src/MacQml.h @@ -9,7 +9,7 @@ public: QmlPtr _surface; GLuint _fbo{ 0 }; - MacQml(const QWindow* window) : Parent(window) {} + MacQml(QWindow* window) : Parent(window) {} void update() override; void init() override; void draw() override; diff --git a/tests-manual/qml/src/StressWeb.h b/tests-manual/qml/src/StressWeb.h index a68e34d0c1..eb4aa80ba0 100644 --- a/tests-manual/qml/src/StressWeb.h +++ b/tests-manual/qml/src/StressWeb.h @@ -24,7 +24,7 @@ public: std::array, DIVISIONS_X> _surfaces; GLuint _fbo{ 0 }; - StressWeb(const QWindow* window) : Parent(window) {} + StressWeb(QWindow* window) : Parent(window) {} static QString getSourceUrl(bool video); void buildSurface(QmlInfo& qmlInfo, bool video); void destroySurface(QmlInfo& qmlInfo); diff --git a/tests-manual/qml/src/TestCase.h b/tests-manual/qml/src/TestCase.h index 191eecb408..084e306bb5 100644 --- a/tests-manual/qml/src/TestCase.h +++ b/tests-manual/qml/src/TestCase.h @@ -8,8 +8,8 @@ class TestCase { public: using QmlPtr = QSharedPointer; - using Builder = std::function; - TestCase(const QWindow* window) : _window(window) {} + using Builder = std::function; + TestCase(QWindow* window) : _window(window) {} virtual void init(); virtual void destroy(); virtual void update(); @@ -18,6 +18,6 @@ public: protected: QOpenGLFunctions_4_1_Core _glf; - const QWindow* _window; + QWindow* _window; std::function _discardLamdba; }; diff --git a/tests-manual/qml/src/main.cpp b/tests-manual/qml/src/main.cpp index 1d98ebf8c8..f2229f138f 100644 --- a/tests-manual/qml/src/main.cpp +++ b/tests-manual/qml/src/main.cpp @@ -205,12 +205,22 @@ void TestWindow::resizeEvent(QResizeEvent* ev) { int main(int argc, char** argv) { +#ifdef Q_OS_MAC auto format = getDefaultOpenGLSurfaceFormat(); - format.setVersion(4, 1); + // Deal with some weirdness in the chromium context sharing on Mac. + // The primary share context needs to be 3.2, so that the Chromium will + // succeed in it's creation of it's command stub contexts. + format.setVersion(3, 2); + // This appears to resolve the issues with corrupted fonts on OSX. No + // idea why. + qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "true"); + // https://i.kym-cdn.com/entries/icons/original/000/008/342/ihave.jpg QSurfaceFormat::setDefaultFormat(format); +#endif + QGuiApplication app(argc, argv); - TestCase::Builder builder = [](const QWindow* window)->TestCase*{ return new MacQml(window); }; + TestCase::Builder builder = [](QWindow* window)->TestCase*{ return new MacQml(window); }; TestWindow window(builder); return app.exec(); } From 378c47d16cb953d465a167ff7fcad910dd87cfdf Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 22 Oct 2019 19:18:11 +1300 Subject: [PATCH 12/31] Replace world detail quality float with enum --- .../dialogs/graphics/GraphicsSettings.qml | 14 +--- interface/src/Application.cpp | 1 + interface/src/LODManager.cpp | 78 +++++++------------ interface/src/LODManager.h | 57 ++++++++++---- interface/src/PerformanceManager.cpp | 6 +- interface/src/ui/PreferencesDialog.cpp | 17 ++-- 6 files changed, 88 insertions(+), 85 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml b/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml index 8634648d17..3b6502cc98 100644 --- a/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml +++ b/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml @@ -133,15 +133,12 @@ Item { ListElement { text: "Low World Detail" - worldDetailQualityValue: 0.25 } ListElement { text: "Medium World Detail" - worldDetailQualityValue: 0.5 } ListElement { text: "Full World Detail" - worldDetailQualityValue: 0.75 } } @@ -158,14 +155,7 @@ Item { currentIndex: -1 function refreshWorldDetailDropdown() { - var currentWorldDetailQuality = LODManager.worldDetailQuality; - if (currentWorldDetailQuality <= 0.25) { - worldDetailDropdown.currentIndex = 0; - } else if (currentWorldDetailQuality <= 0.5) { - worldDetailDropdown.currentIndex = 1; - } else { - worldDetailDropdown.currentIndex = 2; - } + worldDetailDropdown.currentIndex = LODManager.worldDetailQuality; } Component.onCompleted: { @@ -173,7 +163,7 @@ Item { } onCurrentIndexChanged: { - LODManager.worldDetailQuality = model.get(currentIndex).worldDetailQualityValue; + LODManager.worldDetailQuality = currentIndex; worldDetailDropdown.displayText = model.get(currentIndex).text; } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a10e17c010..257808c683 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7508,6 +7508,7 @@ void Application::registerScriptEngineWithApplicationServices(const ScriptEngine scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get().data()); scriptEngine->registerGlobalObject("LODManager", DependencyManager::get().data()); + qScriptRegisterMetaType(scriptEngine.data(), worldDetailQualityToScriptValue, worldDetailQualityFromScriptValue); scriptEngine->registerGlobalObject("Keyboard", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Performance", new PerformanceScriptingInterface()); diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 9fd7b0851a..1a72dffe20 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -19,11 +19,8 @@ #include "ui/DialogsManager.h" #include "InterfaceLogging.h" -const float LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS = LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS; -const float LODManager::DEFAULT_HMD_LOD_DOWN_FPS = LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS; - -Setting::Handle desktopLODDecreaseFPS("desktopLODDecreaseFPS", LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS); -Setting::Handle hmdLODDecreaseFPS("hmdLODDecreaseFPS", LODManager::DEFAULT_HMD_LOD_DOWN_FPS); +Setting::Handle desktopWorldDetailQuality("desktopWorldDetailQuality", (int)DEFAULT_WORLD_DETAIL_QUALITY); +Setting::Handle hmdWorldDetailQuality("hmdWorldDetailQuality", (int)DEFAULT_WORLD_DETAIL_QUALITY); LODManager::LODManager() { } @@ -326,19 +323,21 @@ QString LODManager::getLODFeedbackText() { } void LODManager::loadSettings() { - setDesktopLODTargetFPS(desktopLODDecreaseFPS.get()); - Setting::Handle firstRun { Settings::firstRun, true }; + auto desktopQuality = static_cast(desktopWorldDetailQuality.get()); + auto hmdQuality = static_cast(hmdWorldDetailQuality.get()); + + Setting::Handle firstRun{ Settings::firstRun, true }; if (qApp->property(hifi::properties::OCULUS_STORE).toBool() && firstRun.get()) { - const float LOD_HIGH_QUALITY_LEVEL = 0.75f; - setHMDLODTargetFPS(LOD_HIGH_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS); - } else { - setHMDLODTargetFPS(hmdLODDecreaseFPS.get()); + hmdQuality = WORLD_DETAIL_HIGH; } + + setWorldDetailQuality(desktopQuality, false); + setWorldDetailQuality(hmdQuality, true); } void LODManager::saveSettings() { - desktopLODDecreaseFPS.set(getDesktopLODTargetFPS()); - hmdLODDecreaseFPS.set(getHMDLODTargetFPS()); + desktopWorldDetailQuality.set((int)_desktopWorldDetailQuality); + hmdWorldDetailQuality.set((int)_hmdWorldDetailQuality); } const float MIN_DECREASE_FPS = 0.5f; @@ -393,54 +392,35 @@ float LODManager::getLODTargetFPS() const { } } -void LODManager::setWorldDetailQuality(float quality) { +void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode) { static const float MIN_FPS = 10; - static const float LOW = 0.25f; - - bool isLowestValue = quality <= LOW; - bool isHMDMode = qApp->isHMDMode(); - - float maxFPS = isHMDMode ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; - float desiredFPS = maxFPS; - - if (!isLowestValue) { - float calculatedFPS = (maxFPS - (maxFPS * quality)); - desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; - } + float desiredFPS = isHMDMode ? QUALITY_TO_FPS_HMD[quality] : QUALITY_TO_FPS_DESKTOP[quality]; if (isHMDMode) { + _hmdWorldDetailQuality = quality; setHMDLODTargetFPS(desiredFPS); } else { + _desktopWorldDetailQuality = quality; setDesktopLODTargetFPS(desiredFPS); } - +} + +void LODManager::setWorldDetailQuality(WorldDetailQuality quality) { + setWorldDetailQuality(quality, qApp->isHMDMode()); emit worldDetailQualityChanged(); } -float LODManager::getWorldDetailQuality() const { +WorldDetailQuality LODManager::getWorldDetailQuality() const { + return qApp->isHMDMode() ? _hmdWorldDetailQuality : _desktopWorldDetailQuality; +} - static const float LOW = 0.25f; - static const float MEDIUM = 0.5f; - static const float HIGH = 0.75f; +QScriptValue worldDetailQualityToScriptValue(QScriptEngine* engine, const WorldDetailQuality& worldDetailQuality) { + return worldDetailQuality; +} - bool inHMD = qApp->isHMDMode(); - - float targetFPS = 0.0f; - if (inHMD) { - targetFPS = getHMDLODTargetFPS(); - } else { - targetFPS = getDesktopLODTargetFPS(); - } - float maxFPS = inHMD ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; - float percentage = 1.0f - targetFPS / maxFPS; - - if (percentage <= LOW) { - return LOW; - } else if (percentage <= MEDIUM) { - return MEDIUM; - } - - return HIGH; +void worldDetailQualityFromScriptValue(const QScriptValue& object, WorldDetailQuality& worldDetailQuality) { + worldDetailQuality = + static_cast(std::min(std::max(object.toInt32(), (int)WORLD_DETAIL_LOW), (int)WORLD_DETAIL_HIGH)); } void LODManager::setLODQualityLevel(float quality) { diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 3dafa8c800..1a516e0410 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -23,26 +23,52 @@ #include +/**jsdoc + *

The world detail quality rendered.

+ * + * + * + * + * + * + * + * + * + *
ValueDescription
0Low world detail quality.
1Medium world detail quality.
2High world detail quality.
+ * @typedef {number} LODManager.WorldDetailQuality + */ +enum WorldDetailQuality { + WORLD_DETAIL_LOW = 0, + WORLD_DETAIL_MEDIUM, + WORLD_DETAIL_HIGH +}; +Q_DECLARE_METATYPE(WorldDetailQuality); + #ifdef Q_OS_ANDROID const float LOD_DEFAULT_QUALITY_LEVEL = 0.2f; // default quality level setting is High (lower framerate) #else const float LOD_DEFAULT_QUALITY_LEVEL = 0.5f; // default quality level setting is Mid #endif -const float LOD_MAX_LIKELY_DESKTOP_FPS = 60.0f; // this is essentially, V-synch fps + #ifdef Q_OS_ANDROID -const float LOD_MAX_LIKELY_HMD_FPS = 36.0f; // this is essentially, V-synch fps +const WorldDetailQuality DEFAULT_WORLD_DETAIL_QUALITY = WORLD_DETAIL_LOW; +const std::vector QUALITY_TO_FPS_DESKTOP = { 60.0f, 30.0f, 15.0f }; +const std::vector QUALITY_TO_FPS_HMD = { 25.0f, 16.0f, 10.0f }; #else -const float LOD_MAX_LIKELY_HMD_FPS = 90.0f; // this is essentially, V-synch fps +const WorldDetailQuality DEFAULT_WORLD_DETAIL_QUALITY = WORLD_DETAIL_MEDIUM; +const std::vector QUALITY_TO_FPS_DESKTOP = { 60.0f, 30.0f, 15.0f }; +const std::vector QUALITY_TO_FPS_HMD = { 90.0f, 45.0f, 22.5f }; #endif const float LOD_OFFSET_FPS = 5.0f; // offset of FPS to add for computing the target framerate class AABox; + /**jsdoc * The LOD class manages your Level of Detail functions within Interface. * @namespace LODManager - * + * * @hifi-interface * @hifi-client-entity * @hifi-avatar @@ -51,12 +77,12 @@ class AABox; * @property {number} engineRunTime Read-only. * @property {number} gpuTime Read-only. */ - class LODManager : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY - Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) + Q_PROPERTY(WorldDetailQuality worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality + NOTIFY worldDetailQualityChanged) Q_PROPERTY(float lodQualityLevel READ getLODQualityLevel WRITE setLODQualityLevel NOTIFY lodQualityLevelChanged) @@ -193,8 +219,8 @@ public: float getSmoothRenderTime() const { return _smoothRenderTime; }; float getSmoothRenderFPS() const { return (_smoothRenderTime > 0.0f ? (float)MSECS_PER_SECOND / _smoothRenderTime : 0.0f); }; - void setWorldDetailQuality(float quality); - float getWorldDetailQuality() const; + void setWorldDetailQuality(WorldDetailQuality quality); + WorldDetailQuality getWorldDetailQuality() const; void setLODQualityLevel(float quality); float getLODQualityLevel() const; @@ -220,9 +246,6 @@ public: float getPidOd() const; float getPidO() const; - static const float DEFAULT_DESKTOP_LOD_DOWN_FPS; - static const float DEFAULT_HMD_LOD_DOWN_FPS; - signals: /**jsdoc @@ -244,6 +267,8 @@ signals: private: LODManager(); + void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode); + std::mutex _automaticLODLock; bool _automaticLODAdjust = true; @@ -258,8 +283,11 @@ private: float _lodQualityLevel{ LOD_DEFAULT_QUALITY_LEVEL }; - float _desktopTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS }; - float _hmdTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS }; + WorldDetailQuality _desktopWorldDetailQuality { DEFAULT_WORLD_DETAIL_QUALITY }; + WorldDetailQuality _hmdWorldDetailQuality { DEFAULT_WORLD_DETAIL_QUALITY }; + + float _desktopTargetFPS { QUALITY_TO_FPS_DESKTOP[_desktopWorldDetailQuality] }; + float _hmdTargetFPS { QUALITY_TO_FPS_HMD[_hmdWorldDetailQuality] }; float _lodHalfAngle = getHalfAngleFromVisibilityDistance(DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT); int _boundaryLevelAdjust = 0; @@ -269,4 +297,7 @@ private: glm::vec4 _pidOutputs{ 0.0f }; }; +QScriptValue worldDetailQualityToScriptValue(QScriptEngine* engine, const WorldDetailQuality& worldDetailQuality); +void worldDetailQualityFromScriptValue(const QScriptValue& object, WorldDetailQuality& worldDetailQuality); + #endif // hifi_LODManager_h diff --git a/interface/src/PerformanceManager.cpp b/interface/src/PerformanceManager.cpp index 80c09e3fec..a7b9eff7cc 100644 --- a/interface/src/PerformanceManager.cpp +++ b/interface/src/PerformanceManager.cpp @@ -92,7 +92,7 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP RenderScriptingInterface::getInstance()->setShadowsEnabled(true); qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::REALTIME); - DependencyManager::get()->setWorldDetailQuality(0.75f); + DependencyManager::get()->setWorldDetailQuality(WORLD_DETAIL_HIGH); break; case PerformancePreset::MID: @@ -104,7 +104,7 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP RenderScriptingInterface::getInstance()->setShadowsEnabled(false); qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::INTERACTIVE); - DependencyManager::get()->setWorldDetailQuality(0.5f); + DependencyManager::get()->setWorldDetailQuality(WORLD_DETAIL_MEDIUM); break; case PerformancePreset::LOW: @@ -114,7 +114,7 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP RenderScriptingInterface::getInstance()->setViewportResolutionScale(recommandedPpiScale); - DependencyManager::get()->setWorldDetailQuality(0.25f); + DependencyManager::get()->setWorldDetailQuality(WORLD_DETAIL_LOW); break; case PerformancePreset::UNKNOWN: diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index ec15dd8111..b7b5342066 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -58,18 +58,19 @@ void setupPreferences() { static const QString GRAPHICS_QUALITY { "Graphics Quality" }; { auto getter = []()->float { - return DependencyManager::get()->getWorldDetailQuality(); + return (int)DependencyManager::get()->getWorldDetailQuality(); }; - auto setter = [](float value) { - DependencyManager::get()->setWorldDetailQuality(value); + auto setter = [](int value) { + DependencyManager::get()->setWorldDetailQuality(static_cast(value)); }; - auto wodSlider = new SliderPreference(GRAPHICS_QUALITY, "World Detail", getter, setter); - wodSlider->setMin(0.25f); - wodSlider->setMax(0.75f); - wodSlider->setStep(0.25f); - preferences->addPreference(wodSlider); + auto wodButtons = new RadioButtonsPreference(GRAPHICS_QUALITY, "World Detail", getter, setter); + QStringList items; + items << "Low World Detail" << "Medium World Detail" << "High World Detail"; + wodButtons->setHeading("World Detail"); + wodButtons->setItems(items); + preferences->addPreference(wodButtons); auto getterShadow = []()->bool { auto menu = Menu::getInstance(); From 6a2e67ca54f0763b78bdf78bdad8e9580fc792c9 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 22 Oct 2019 21:07:04 +1300 Subject: [PATCH 13/31] Typo --- interface/src/LODManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 1a516e0410..4708deb61b 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -267,7 +267,7 @@ signals: private: LODManager(); - void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode); + void setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode); std::mutex _automaticLODLock; bool _automaticLODAdjust = true; From a8602195d4cb5c602672dbb186415245202d6772 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Tue, 22 Oct 2019 07:17:57 -0700 Subject: [PATCH 14/31] addressing comments --- interface/src/scripting/AudioDevices.cpp | 22 ++++++++----------- libraries/audio-client/CMakeLists.txt | 1 + libraries/audio-client/src/AudioClient.cpp | 8 ++++--- .../audio-client/src/HifiAudioDeviceInfo.cpp | 3 +-- .../audio-client/src/HifiAudioDeviceInfo.h | 2 -- .../plugins/src/plugins/PluginManager.cpp | 6 ++--- libraries/plugins/src/plugins/PluginManager.h | 1 + 7 files changed, 19 insertions(+), 24 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 7cabd49e93..4aa1018c23 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -62,12 +62,6 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) { auto& setting = getSetting(hmd, mode); if (setting.isSet()) { deviceName = setting.get(); - } else if (hmd) { - if (mode == QAudio::AudioInput) { - deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioInDevice(); - } else { // if (_mode == QAudio::AudioOutput) - deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioOutDevice(); - } } else { deviceName = HifiAudioDeviceInfo::DEFAULT_DEVICE_NAME; } @@ -269,13 +263,15 @@ void AudioDeviceList::onDevicesChanged(const QList& devices bool hmdIsSelected = false; bool desktopIsSelected = false; - foreach(const HifiAudioDeviceInfo& deviceInfo, devices) { - for (bool isHMD : {false, true}) { - auto& backupSelectedDeviceName = isHMD ? _backupSelectedHMDDeviceName : _backupSelectedDesktopDeviceName; - if (deviceInfo.deviceName() == backupSelectedDeviceName) { - HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; - selectedDevice = deviceInfo; - backupSelectedDeviceName.clear(); + if (!_backupSelectedDesktopDeviceName.isEmpty() && !_backupSelectedHMDDeviceName.isEmpty()) { + foreach(const HifiAudioDeviceInfo& deviceInfo, devices) { + for (bool isHMD : {false, true}) { + auto& backupSelectedDeviceName = isHMD ? _backupSelectedHMDDeviceName : _backupSelectedDesktopDeviceName; + if (deviceInfo.deviceName() == backupSelectedDeviceName) { + HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; + selectedDevice = deviceInfo; + backupSelectedDeviceName.clear(); + } } } } diff --git a/libraries/audio-client/CMakeLists.txt b/libraries/audio-client/CMakeLists.txt index 03279b08f6..e1d90334ff 100644 --- a/libraries/audio-client/CMakeLists.txt +++ b/libraries/audio-client/CMakeLists.txt @@ -7,6 +7,7 @@ link_hifi_libraries(audio plugins) include_hifi_library_headers(shared) include_hifi_library_headers(networking) include_hifi_library_headers(gpu) + if (ANDROID) else () target_webrtc() diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 418a45e5e9..cb8128bbc9 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #include #include + #include "AudioClientLogging.h" #include "AudioLogging.h" #include "AudioHelpers.h" @@ -81,7 +83,7 @@ Mutex _recordMutex; HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode); -#include + static QString getHmdAudioDeviceName(QAudio::Mode mode) { foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getAllDisplayPlugins()) { if (displayPlugin && displayPlugin->isHmd()) { @@ -568,7 +570,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { HifiAudioDeviceInfo foundDevice; foreach(QAudioDeviceInfo audioDevice, devices) { if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { - foundDevice=HifiAudioDeviceInfo(audioDevice,true,mode, HifiAudioDeviceInfo::desktop); + foundDevice=HifiAudioDeviceInfo(audioDevice, true, mode, HifiAudioDeviceInfo::desktop); break; } } @@ -594,7 +596,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { } #endif // fallback for failed lookup is the default device - return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), true,mode, HifiAudioDeviceInfo::desktop) : + return (mode == QAudio::AudioInput) ? HifiAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice(), true, mode, HifiAudioDeviceInfo::desktop) : HifiAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice(), true, mode, HifiAudioDeviceInfo::desktop); } diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.cpp b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp index 5cbb15ff73..73d0670fa6 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.cpp +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.cpp @@ -32,5 +32,4 @@ bool HifiAudioDeviceInfo::operator==(const HifiAudioDeviceInfo& rhs) const { } bool HifiAudioDeviceInfo::operator!=(const HifiAudioDeviceInfo& rhs) const { return getDevice() != rhs.getDevice() || isDefault() != rhs.isDefault(); -} - +} \ No newline at end of file diff --git a/libraries/audio-client/src/HifiAudioDeviceInfo.h b/libraries/audio-client/src/HifiAudioDeviceInfo.h index 9b77f77c9e..5bc7125574 100644 --- a/libraries/audio-client/src/HifiAudioDeviceInfo.h +++ b/libraries/audio-client/src/HifiAudioDeviceInfo.h @@ -37,7 +37,6 @@ public: _deviceType = deviceInfo.getDeviceType(); } - HifiAudioDeviceInfo(QAudioDeviceInfo deviceInfo, bool isDefault, QAudio::Mode mode, DeviceType devType=both) : _audioDeviceInfo(deviceInfo), _isDefault(isDefault), @@ -66,7 +65,6 @@ public: bool operator==(const HifiAudioDeviceInfo& rhs) const; bool operator!=(const HifiAudioDeviceInfo& rhs) const; - private: QAudioDeviceInfo _audioDeviceInfo; bool _isDefault { false }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 1ecc4f1d45..660159d9bd 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -13,6 +13,7 @@ #include #include #include +#include //#define HIFI_PLUGINMANAGER_DEBUG #if defined(HIFI_PLUGINMANAGER_DEBUG) @@ -21,6 +22,7 @@ #include #include +#include #include "RuntimePlugin.h" #include "CodecPlugin.h" @@ -221,10 +223,6 @@ const OculusPlatformPluginPointer PluginManager::getOculusPlatformPlugin() { return oculusPlatformPlugin; } -#include -#include - - DisplayPluginList PluginManager::getAllDisplayPlugins() { if (thread() != QThread::currentThread()) { DisplayPluginList list; diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index 5ec82ea743..f0aa662634 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -52,6 +52,7 @@ public: using PluginFilter = std::function; void setPluginFilter(PluginFilter pluginFilter) { _pluginFilter = pluginFilter; } Q_INVOKABLE DisplayPluginList getAllDisplayPlugins(); + signals: void inputDeviceRunningChanged(const QString& pluginName, bool isRunning, const QStringList& runningDevices); From 5bf2365a5e384dde44754eadd687370880b795a4 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 21 Oct 2019 17:29:44 -0700 Subject: [PATCH 15/31] Update Qt URL and force vcpkg hash change --- cmake/ports/hifi-deps/CONTROL | 2 +- hifi_vcpkg.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/ports/hifi-deps/CONTROL b/cmake/ports/hifi-deps/CONTROL index 2441de9002..4cf952ccf0 100644 --- a/cmake/ports/hifi-deps/CONTROL +++ b/cmake/ports/hifi-deps/CONTROL @@ -1,4 +1,4 @@ Source: hifi-deps -Version: 0.1 +Version: 0.3 Description: Collected dependencies for High Fidelity applications Build-Depends: bullet3, draco, etc2comp, glm, nvtt, openexr (!android), openssl (windows), tbb (!android&!osx), zlib, webrtc (!android) diff --git a/hifi_vcpkg.py b/hifi_vcpkg.py index 7bb261faa0..ebecca6226 100644 --- a/hifi_vcpkg.py +++ b/hifi_vcpkg.py @@ -265,7 +265,7 @@ endif() if platform.system() == 'Windows': url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows3.tar.gz' elif platform.system() == 'Darwin': - url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos3.tar.gz' + url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz?versionId=bLAgnoJ8IMKpqv8NFDcAu8hsyQy3Rwwz' elif platform.system() == 'Linux': if platform.linux_distribution()[1][:3] == '16.': url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz' From 0410a45da1430f88617704e25b019a6b8fff2a11 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 22 Oct 2019 11:11:13 -0700 Subject: [PATCH 16/31] fixed selection issue --- interface/src/scripting/AudioDevices.cpp | 21 ++++++++++++++++----- libraries/audio-client/src/AudioClient.cpp | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 4aa1018c23..7fc129de3c 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -268,9 +268,14 @@ void AudioDeviceList::onDevicesChanged(const QList& devices for (bool isHMD : {false, true}) { auto& backupSelectedDeviceName = isHMD ? _backupSelectedHMDDeviceName : _backupSelectedDesktopDeviceName; if (deviceInfo.deviceName() == backupSelectedDeviceName) { - HifiAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice; - selectedDevice = deviceInfo; - backupSelectedDeviceName.clear(); + if (isHMD && deviceInfo.getDeviceType() != HifiAudioDeviceInfo::desktop) { + _selectedHMDDevice= deviceInfo; + backupSelectedDeviceName.clear(); + } else if (!isHMD && deviceInfo.getDeviceType() != HifiAudioDeviceInfo::hmd) { + _selectedDesktopDevice = deviceInfo; + backupSelectedDeviceName.clear(); + } + } } } @@ -323,8 +328,14 @@ void AudioDeviceList::onDevicesChanged(const QList& devices } else { //no selected device for context. fallback to saved - const QString& savedDeviceName = isHMD ? _hmdSavedDeviceName : _desktopSavedDeviceName; - isSelected = (device.info.deviceName() == savedDeviceName); + QString& savedDeviceName = isHMD ? _hmdSavedDeviceName : _desktopSavedDeviceName; + + if (device.info.deviceName() == savedDeviceName) { + if ((isHMD && device.info.getDeviceType() != HifiAudioDeviceInfo::desktop) || + (!isHMD && device.info.getDeviceType() != HifiAudioDeviceInfo::hmd)) { + isSelected = true; + } + } } if (isSelected) { diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index cb8128bbc9..3e1557e09b 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -570,7 +570,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { HifiAudioDeviceInfo foundDevice; foreach(QAudioDeviceInfo audioDevice, devices) { if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { - foundDevice=HifiAudioDeviceInfo(audioDevice, true, mode, HifiAudioDeviceInfo::desktop); + foundDevice = HifiAudioDeviceInfo(audioDevice, true, mode, HifiAudioDeviceInfo::desktop); break; } } From f6aa4a2dd4af4842f0206b097449149deb423906 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 22 Oct 2019 11:42:19 -0700 Subject: [PATCH 17/31] Head look at should update before rig --- interface/src/avatar/MyAvatar.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6e0bfab69b..fa3f6c2461 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -906,6 +906,21 @@ void MyAvatar::simulate(float deltaTime, bool inView) { updateViewBoom(); } + // Head's look at blending needs updating + // before we perform rig animations and IK. + CameraMode mode = qApp->getCamera().getMode(); + if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || + mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { + if (!_pointAtActive || !_isPointTargetValid) { + updateHeadLookAt(deltaTime); + } else { + resetHeadLookAt(); + } + } else if (_headLookAtActive) { + resetHeadLookAt(); + _headLookAtActive = false; + } + // update sensorToWorldMatrix for camera and hand controllers // before we perform rig animations and IK. updateSensorToWorldMatrix(); @@ -957,18 +972,6 @@ void MyAvatar::simulate(float deltaTime, bool inView) { head->setPosition(headPosition); head->setScale(getModelScale()); head->simulate(deltaTime); - CameraMode mode = qApp->getCamera().getMode(); - if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || - mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { - if (!_pointAtActive || !_isPointTargetValid) { - updateHeadLookAt(deltaTime); - } else { - resetHeadLookAt(); - } - } else if (_headLookAtActive){ - resetHeadLookAt(); - _headLookAtActive = false; - } } // Record avatars movements. From ea864e4e9740b473989c8496f7b315c3d32fae31 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 23 Oct 2019 08:13:46 +1300 Subject: [PATCH 18/31] Remove unused variable --- interface/src/LODManager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 1a72dffe20..4cd5025fc1 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -393,9 +393,7 @@ float LODManager::getLODTargetFPS() const { } void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode) { - static const float MIN_FPS = 10; float desiredFPS = isHMDMode ? QUALITY_TO_FPS_HMD[quality] : QUALITY_TO_FPS_DESKTOP[quality]; - if (isHMDMode) { _hmdWorldDetailQuality = quality; setHMDLODTargetFPS(desiredFPS); From e1fa10b4de1473b0c93d4ab198f2e911bc833117 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Tue, 22 Oct 2019 14:14:41 -0700 Subject: [PATCH 19/31] Updated Qt 5.12.3 WASAPI plugin. Reverted patch that applied "eCommunications" role to our audio streams. --- cmake/externals/wasapi/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/wasapi/CMakeLists.txt b/cmake/externals/wasapi/CMakeLists.txt index 18d93bde40..286d18e2b5 100644 --- a/cmake/externals/wasapi/CMakeLists.txt +++ b/cmake/externals/wasapi/CMakeLists.txt @@ -6,8 +6,8 @@ if (WIN32) include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/qtaudio_wasapi12.zip - URL_MD5 9e2eef41165f85344808f754b48bf08d + URL https://public.highfidelity.com/dependencies/qtaudio_wasapi13.zip + URL_MD5 aa56a45f19c18caee13d29a40d1d7d28 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From df782edcd9aafb8a988bcc68774c639f5ab17739 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 23 Oct 2019 11:14:22 -0700 Subject: [PATCH 20/31] DEV-2541: Update 'Jump To' top bar expanded text --- .../resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml index 65a5eb0c80..812971dc3a 100644 --- a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml +++ b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml @@ -429,7 +429,7 @@ Rectangle { SimplifiedControls.TextField { id: goToTextField readonly property string shortPlaceholderText: "Jump to..." - readonly property string longPlaceholderText: "Type the name of a location to quickly jump there..." + readonly property string longPlaceholderText: "Quickly jump to a location by typing '/LocationName'" anchors.centerIn: parent width: Math.min(parent.width, 445) height: 35 From f847d364a84dc5fd9b4476f48ff091a0e5090c10 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 23 Oct 2019 11:48:19 -0700 Subject: [PATCH 21/31] DEV-2498: Fix a crash in MenuScriptingInterface --- interface/src/scripting/MenuScriptingInterface.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/scripting/MenuScriptingInterface.cpp b/interface/src/scripting/MenuScriptingInterface.cpp index ae6a7c7d67..1020c12733 100644 --- a/interface/src/scripting/MenuScriptingInterface.cpp +++ b/interface/src/scripting/MenuScriptingInterface.cpp @@ -41,7 +41,8 @@ void MenuScriptingInterface::removeMenu(const QString& menu) { bool MenuScriptingInterface::menuExists(const QString& menu) { if (QThread::currentThread() == qApp->thread()) { - return Menu::getInstance()->menuExists(menu); + Menu* menuInstance = Menu::getInstance(); + return menuInstance && menuInstance->menuExists(menu); } bool result { false }; BLOCKING_INVOKE_METHOD(Menu::getInstance(), "menuExists", @@ -84,7 +85,8 @@ void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString& bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString& menuitem) { if (QThread::currentThread() == qApp->thread()) { - return Menu::getInstance()->menuItemExists(menu, menuitem); + Menu* menuInstance = Menu::getInstance(); + return menuInstance && menuInstance->menuItemExists(menu, menuitem); } bool result { false }; BLOCKING_INVOKE_METHOD(Menu::getInstance(), "menuItemExists", @@ -96,7 +98,8 @@ bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString& bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) { if (QThread::currentThread() == qApp->thread()) { - return Menu::getInstance()->isOptionChecked(menuOption); + Menu* menuInstance = Menu::getInstance(); + return menuInstance && menuInstance->isOptionChecked(menuOption); } bool result { false }; BLOCKING_INVOKE_METHOD(Menu::getInstance(), "isOptionChecked", @@ -113,7 +116,8 @@ void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool bool MenuScriptingInterface::isMenuEnabled(const QString& menuOption) { if (QThread::currentThread() == qApp->thread()) { - return Menu::getInstance()->isOptionChecked(menuOption); + Menu* menuInstance = Menu::getInstance(); + return menuInstance && menuInstance->isMenuEnabled(menuOption); } bool result { false }; BLOCKING_INVOKE_METHOD(Menu::getInstance(), "isMenuEnabled", From 9849205ca03e47c4968f43a250669699ec552d99 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 23 Oct 2019 12:32:16 -0700 Subject: [PATCH 22/31] Add perf timer to code block --- interface/src/avatar/MyAvatar.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index fa3f6c2461..55ce778b4f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -908,17 +908,21 @@ void MyAvatar::simulate(float deltaTime, bool inView) { // Head's look at blending needs updating // before we perform rig animations and IK. - CameraMode mode = qApp->getCamera().getMode(); - if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || - mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { - if (!_pointAtActive || !_isPointTargetValid) { - updateHeadLookAt(deltaTime); - } else { + { + PerformanceTimer perfTimer("lookat"); + + CameraMode mode = qApp->getCamera().getMode(); + if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || + mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { + if (!_pointAtActive || !_isPointTargetValid) { + updateHeadLookAt(deltaTime); + } else { + resetHeadLookAt(); + } + } else if (_headLookAtActive) { resetHeadLookAt(); + _headLookAtActive = false; } - } else if (_headLookAtActive) { - resetHeadLookAt(); - _headLookAtActive = false; } // update sensorToWorldMatrix for camera and hand controllers From 179f5e0873ff65c5960ef2d3b7e4846083bb8a47 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 23 Oct 2019 12:56:43 -0700 Subject: [PATCH 23/31] fixed context switching issue with hmd. included additional output info for other audio crash issues --- interface/src/scripting/AudioDevices.cpp | 4 ++-- libraries/audio-client/src/AudioClient.cpp | 27 ++++++++++++++-------- libraries/audio-client/src/AudioClient.h | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index 7fc129de3c..76c871fa5c 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -164,8 +164,8 @@ void AudioDeviceList::resetDevice(bool contextIsHMD) { QString deviceName = getTargetDevice(contextIsHMD, _mode); // FIXME can't use blocking connections here, so we can't determine whether the switch succeeded or not // We need to have the AudioClient emit signals on switch success / failure - QMetaObject::invokeMethod(client, "switchAudioDevice", - Q_ARG(QAudio::Mode, _mode), Q_ARG(QString, deviceName)); + QMetaObject::invokeMethod(client, "switchAudioDevice", + Q_ARG(QAudio::Mode, _mode), Q_ARG(QString, deviceName), Q_ARG(bool, contextIsHMD)); #if 0 bool switchResult = false; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 3e1557e09b..9ae751d6c3 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -424,12 +424,14 @@ void AudioClient::setAudioPaused(bool pause) { } } -HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { +HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName, bool isHmd=false) { HifiAudioDeviceInfo result; foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { - result = audioDevice; - break; + if ((!isHmd && audioDevice.getDeviceType() != HifiAudioDeviceInfo::hmd) || (isHmd && audioDevice.getDeviceType() != HifiAudioDeviceInfo::desktop)) { + result = audioDevice; + break; + } } } return result; @@ -986,13 +988,18 @@ void AudioClient::selectAudioFormat(const QString& selectedCodecName) { void AudioClient::changeDefault(HifiAudioDeviceInfo newDefault, QAudio::Mode mode) { HifiAudioDeviceInfo currentDevice = mode == QAudio::AudioInput ? _inputDeviceInfo : _outputDeviceInfo; - if (currentDevice.isDefault() && currentDevice.getDevice() != newDefault.getDevice()) { + if (currentDevice.isDefault() && currentDevice.getDeviceType() == newDefault.getDeviceType() && currentDevice.getDevice() != newDefault.getDevice()) { switchAudioDevice(mode, newDefault); } } bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo) { auto device = deviceInfo; + if (deviceInfo.getDevice().isNull()) { + qCDebug(audioclient) << __FUNCTION__ << " switching to null device :" + << deviceInfo.deviceName() << " : " << deviceInfo.getDevice().deviceName(); + } + if (mode == QAudio::AudioInput) { return switchInputToAudioDevice(device); } else { @@ -1000,8 +1007,8 @@ bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo } } -bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QString& deviceName) { - return switchAudioDevice(mode, getNamedAudioDeviceForMode(mode, deviceName)); +bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QString& deviceName, bool isHmd) { + return switchAudioDevice(mode, getNamedAudioDeviceForMode(mode, deviceName, isHmd)); } void AudioClient::configureReverb() { @@ -1809,7 +1816,8 @@ void AudioClient::outputFormatChanged() { bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); - qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << _inputDeviceInfo.deviceName() <<"----"< Date: Wed, 23 Oct 2019 14:23:29 -0700 Subject: [PATCH 24/31] Move changes to Head and remove leftover code --- interface/src/avatar/MyAvatar.cpp | 27 ++++++++----------- interface/src/avatar/MyAvatar.h | 5 ++-- .../src/avatars-renderer/Head.cpp | 21 +++++++++++++++ .../src/avatars-renderer/Head.h | 7 +++++ libraries/avatars/src/AvatarData.h | 1 - libraries/avatars/src/HeadData.cpp | 27 ------------------- libraries/avatars/src/HeadData.h | 12 ++++----- 7 files changed, 47 insertions(+), 53 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e152902b47..9c9505323f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2191,20 +2191,15 @@ void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) { foreach (const AvatarSharedPointer& avatarData, hash) { std::shared_ptr avatar = std::static_pointer_cast(avatarData); if (!avatar->isMyAvatar() && avatar->isInitialized()) { - if (_forceTargetAvatarID.isNull() || avatar->getID() != _forceTargetAvatarID) { - glm::vec3 otherForward = avatar->getHeadJointFrontVector(); - glm::vec3 otherPosition = avatar->getHead()->getEyePosition(); - const float TIME_WITHOUT_TALKING_THRESHOLD = 1.0f; - bool otherIsTalking = avatar->getHead()->getTimeWithoutTalking() <= TIME_WITHOUT_TALKING_THRESHOLD; - bool lookingAtOtherAlready = _lookAtTargetAvatar.lock().get() == avatar.get(); - float cost = lookAtCostFunction(myForward, myPosition, otherForward, otherPosition, otherIsTalking, lookingAtOtherAlready); - if (cost < bestCost) { - bestCost = cost; - bestAvatar = avatar; - } - } else { + glm::vec3 otherForward = avatar->getHeadJointFrontVector(); + glm::vec3 otherPosition = avatar->getHead()->getEyePosition(); + const float TIME_WITHOUT_TALKING_THRESHOLD = 1.0f; + bool otherIsTalking = avatar->getHead()->getTimeWithoutTalking() <= TIME_WITHOUT_TALKING_THRESHOLD; + bool lookingAtOtherAlready = _lookAtTargetAvatar.lock().get() == avatar.get(); + float cost = lookAtCostFunction(myForward, myPosition, otherForward, otherPosition, otherIsTalking, lookingAtOtherAlready); + if (cost < bestCost) { + bestCost = cost; bestAvatar = avatar; - break; } } } @@ -6652,7 +6647,7 @@ void MyAvatar::updateEyesLookAtPosition(FaceTracker* faceTracker, Camera& myCame } else if (_scriptControlsEyesLookAt) { if (_scriptEyesControlTimer < MAX_LOOK_AT_TIME_SCRIPT_CONTROL) { _scriptEyesControlTimer += deltaTime; - lookAtSpot = _eyesLookAtTarget; + lookAtSpot = _eyesLookAtTarget.get(); } else { _scriptControlsEyesLookAt = false; } @@ -6740,7 +6735,7 @@ void MyAvatar::updateEyesLookAtPosition(FaceTracker* faceTracker, Camera& myCame } } } - _eyesLookAtTarget = lookAtSpot; + _eyesLookAtTarget.set(lookAtSpot); getHead()->setLookAtPosition(lookAtSpot); } @@ -6829,7 +6824,7 @@ void MyAvatar::setEyesLookAt(const glm::vec3& lookAtTarget) { Q_ARG(const glm::vec3&, lookAtTarget)); return; } - _eyesLookAtTarget = lookAtTarget; + _eyesLookAtTarget.set(lookAtTarget); _scriptEyesControlTimer = 0.0f; _scriptControlsEyesLookAt = true; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 90c4157c3c..c0fa15b624 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1780,7 +1780,7 @@ public: * @function MyAvatar.getEyesLookAt * @returns {Vec3} The eyes's look at target in world coordinates. */ - Q_INVOKABLE glm::vec3 getEyesLookAt() { return _eyesLookAtTarget; } + Q_INVOKABLE glm::vec3 getEyesLookAt() { return _eyesLookAtTarget.get(); } /**jsdoc * Aims the pointing directional blending towards the provided target point. @@ -2672,13 +2672,12 @@ private: AvatarWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; - QUuid _forceTargetAvatarID; bool _shouldRender { true }; float _oculusYawOffset; eyeContactTarget _eyeContactTarget; float _eyeContactTargetTimer { 0.0f }; - glm::vec3 _eyesLookAtTarget; + ThreadSafeValueCache _eyesLookAtTarget { glm::vec3() }; bool _scriptControlsEyesLookAt{ false }; float _scriptEyesControlTimer{ 0.0f }; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp index e2f5ef0c60..aa6dc779d5 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp @@ -355,3 +355,24 @@ float Head::getFinalPitch() const { float Head::getFinalRoll() const { return glm::clamp(_baseRoll + _deltaRoll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } + +void Head::setLookAtPosition(const glm::vec3& lookAtPosition) { + if (_isEyeLookAtUpdated && _requestLookAtPosition != lookAtPosition) { + _lookAtPositionChanged = usecTimestampNow(); + glm::vec3 oldAvatarLookAtVector = _requestLookAtPosition - _owningAvatar->getWorldPosition(); + glm::vec3 newAvatarLookAtVector = lookAtPosition - _owningAvatar->getWorldPosition(); + const float MIN_BLINK_ANGLE = 0.35f; // 20 degrees + _forceBlinkToRetarget = angleBetween(oldAvatarLookAtVector, newAvatarLookAtVector) > MIN_BLINK_ANGLE; + if (_forceBlinkToRetarget) { + _isEyeLookAtUpdated = false; + } else { + _lookAtPosition = lookAtPosition; + } + } + _requestLookAtPosition = lookAtPosition; +} + +void Head::updateEyeLookAt() { + _lookAtPosition = _requestLookAtPosition; + _isEyeLookAtUpdated = true; +} diff --git a/libraries/avatars-renderer/src/avatars-renderer/Head.h b/libraries/avatars-renderer/src/avatars-renderer/Head.h index e3c8d7d2b5..98b2fbb3a0 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Head.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Head.h @@ -79,6 +79,9 @@ public: float getTimeWithoutTalking() const { return _timeWithoutTalking; } + virtual void setLookAtPosition(const glm::vec3& lookAtPosition) override; + void updateEyeLookAt(); + protected: // disallow copies of the Head, copy of owning Avatar is disallowed too Head(const Head&); @@ -123,6 +126,10 @@ protected: int _leftEyeLookAtID; int _rightEyeLookAtID; + glm::vec3 _requestLookAtPosition; + bool _forceBlinkToRetarget { false }; + bool _isEyeLookAtUpdated { false }; + // private methods void calculateMouthShapes(float timeRatio); void applyEyelidOffset(glm::quat headOrientation); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 61729f8db3..bfe775e972 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1480,7 +1480,6 @@ public: void setIsNewAvatar(bool isNewAvatar) { _isNewAvatar = isNewAvatar; } bool getIsNewAvatar() { return _isNewAvatar; } void setIsClientAvatar(bool isClientAvatar) { _isClientAvatar = isClientAvatar; } - bool getIsClientAvatar() const { return _isClientAvatar; } void setSkeletonData(const std::vector& skeletonData); std::vector getSkeletonData() const; void sendSkeletonData() const; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index d9998883d7..7e1d13511e 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -234,30 +234,3 @@ void HeadData::setFaceTrackerConnected(bool value) { _isFaceTrackerConnected = value; } -void HeadData::setLookAtPosition(const glm::vec3& lookAtPosition) { - if (_owningAvatar->getIsClientAvatar() || _owningAvatar->isMyAvatar()) { - if (_isEyeLookAtUpdated && _requestLookAtPosition != lookAtPosition) { - _lookAtPositionChanged = usecTimestampNow(); - glm::vec3 oldAvatarLookAtVector = _requestLookAtPosition - _owningAvatar->getWorldPosition(); - glm::vec3 newAvatarLookAtVector = lookAtPosition - _owningAvatar->getWorldPosition(); - const float MIN_BLINK_ANGLE = 0.35f; // 20 degrees - _forceBlinkToRetarget = angleBetween(oldAvatarLookAtVector, newAvatarLookAtVector) > MIN_BLINK_ANGLE; - if (_forceBlinkToRetarget) { - _isEyeLookAtUpdated = false; - } else { - _lookAtPosition = lookAtPosition; - } - } - _requestLookAtPosition = lookAtPosition; - } else { - if (_lookAtPosition != lookAtPosition) { - _lookAtPositionChanged = usecTimestampNow(); - } - _lookAtPosition = lookAtPosition; - } -} - -void HeadData::updateEyeLookAt() { - _lookAtPosition = _requestLookAtPosition; - _isEyeLookAtUpdated = true; -} diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index 190b179f25..020827c4d9 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -64,7 +64,12 @@ public: void setBlendshapeCoefficients(const QVector& blendshapeCoefficients) { _blendshapeCoefficients = blendshapeCoefficients; } const glm::vec3& getLookAtPosition() const { return _lookAtPosition; } - void setLookAtPosition(const glm::vec3& lookAtPosition); + virtual void setLookAtPosition(const glm::vec3& lookAtPosition) { + if (_lookAtPosition != lookAtPosition) { + _lookAtPositionChanged = usecTimestampNow(); + } + _lookAtPosition = lookAtPosition; + } bool lookAtPositionChangedSince(quint64 time) { return _lookAtPositionChanged >= time; } bool getHasProceduralEyeFaceMovement() const; @@ -79,8 +84,6 @@ public: void setFaceTrackerConnected(bool value); bool getFaceTrackerConnected() const { return _isFaceTrackerConnected; } - void updateEyeLookAt(); - friend class AvatarData; QJsonObject toJson() const; @@ -92,7 +95,6 @@ protected: float _basePitch; float _baseRoll; - glm::vec3 _requestLookAtPosition; glm::vec3 _lookAtPosition; quint64 _lookAtPositionChanged { 0 }; @@ -113,8 +115,6 @@ protected: QVector _summedBlendshapeCoefficients; QMap _blendshapeLookupMap; AvatarData* _owningAvatar; - bool _forceBlinkToRetarget { false }; - bool _isEyeLookAtUpdated { false }; private: // privatize copy ctor and assignment operator so copies of this object cannot be made From 9432a375675e6aa5b87ca26e87d22e80c0d837b3 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 23 Oct 2019 14:26:53 -0700 Subject: [PATCH 25/31] Undo changes in HeadData.cpp --- libraries/avatars/src/HeadData.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index 7e1d13511e..c86e534929 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -233,4 +233,3 @@ void HeadData::setHasProceduralEyeMovement(bool hasProceduralEyeMovement) { void HeadData::setFaceTrackerConnected(bool value) { _isFaceTrackerConnected = value; } - From a6bcbe4c66c31a962114da4de5d7ed5012c19961 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 23 Oct 2019 14:32:03 -0700 Subject: [PATCH 26/31] DEV-2463: Put FTUE users in an empty serverless domain instead of the tutorial --- interface/resources/serverless/empty.json | 10 ++++++++++ scripts/simplifiedUI/ui/simplifiedUI.js | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 interface/resources/serverless/empty.json diff --git a/interface/resources/serverless/empty.json b/interface/resources/serverless/empty.json new file mode 100644 index 0000000000..6431284d9b --- /dev/null +++ b/interface/resources/serverless/empty.json @@ -0,0 +1,10 @@ +{ + "DataVersion": 3, + "Paths": { + "/": "/0, 0, 0/0,0,0,0" + }, + "Entities": [ + ], + "Id": "{5807d519-eb7d-496d-b22a-0820811291c9}", + "Version": 120 +} diff --git a/scripts/simplifiedUI/ui/simplifiedUI.js b/scripts/simplifiedUI/ui/simplifiedUI.js index 3025b938cb..2ce6a3e073 100644 --- a/scripts/simplifiedUI/ui/simplifiedUI.js +++ b/scripts/simplifiedUI/ui/simplifiedUI.js @@ -377,7 +377,7 @@ function displayInitialLaunchWindow() { initialLaunchWindow.fromQml.connect(onMessageFromInitialLaunchWindow); - Window.location = "file:///~/serverless/tutorial.json"; + Window.location = "file:///~/serverless/empty.json"; } var SECOND_LAUNCH_QML_PATH = Script.resolvePath("simplifiedFTUE/SecondLaunchWindow.qml"); @@ -405,7 +405,7 @@ function displaySecondLaunchWindow() { secondLaunchWindow.fromQml.connect(onMessageFromSecondLaunchWindow); - Window.location = "file:///~/serverless/tutorial.json"; + Window.location = "file:///~/serverless/empty.json"; } function closeInitialLaunchWindow() { From d7996c77f44eef2b6d84033f077a238d1621db85 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 23 Oct 2019 14:48:25 -0700 Subject: [PATCH 27/31] android build fix --- libraries/audio-client/src/AudioClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 9ae751d6c3..4a00dd9bf3 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -2005,9 +2005,9 @@ void AudioClient::setHeadsetPluggedIn(bool pluggedIn) { bool aecEnabled = enableAEC.get(); if ((pluggedIn || !aecEnabled) && _inputDeviceInfo.deviceName() != VOICE_RECOGNITION) { - switchAudioDevice(QAudio::AudioInput, VOICE_RECOGNITION); + switchAudioDevice(QAudio::AudioInput, VOICE_RECOGNITION, false); } else if (!pluggedIn && aecEnabled && _inputDeviceInfo.deviceName() != VOICE_COMMUNICATION) { - switchAudioDevice(QAudio::AudioInput, VOICE_COMMUNICATION); + switchAudioDevice(QAudio::AudioInput, VOICE_COMMUNICATION, false); } } _isHeadsetPluggedIn = pluggedIn; From ed4df09a261ce4cfd0069bf0608990b1dbe64194 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 23 Oct 2019 15:15:41 -0700 Subject: [PATCH 28/31] updated logging added clarifying comment for emit --- libraries/audio-client/src/AudioClient.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 4a00dd9bf3..169a975f96 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1816,8 +1816,8 @@ void AudioClient::outputFormatChanged() { bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); - qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << _inputDeviceInfo.deviceName() << ":" << _inputDeviceInfo.getDevice().deviceName() - <<"-- new device: "<< inputDeviceInfo.deviceName() <<":"<< inputDeviceInfo.getDevice().deviceName() << "]"; + qCDebug(audioclient) << __FUNCTION__ << "_inputDeviceInfo: [" << _inputDeviceInfo.deviceName() << ":" << _inputDeviceInfo.getDevice().deviceName() + << "-- inputDeviceInfo: " << inputDeviceInfo.deviceName() << ":" << inputDeviceInfo.getDevice().deviceName() << "]"; bool supportedFormat = false; // NOTE: device start() uses the Qt internal device list @@ -1869,8 +1869,9 @@ bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDevice } if (!inputDeviceInfo.getDevice().isNull()) { - qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << "is available."; + qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << ":" << inputDeviceInfo.getDevice().deviceName() << " is available."; + //do not update UI that we're changing devices if default or same device bool doEmit = _inputDeviceInfo.deviceName() != inputDeviceInfo.deviceName(); _inputDeviceInfo = inputDeviceInfo; if (doEmit) { @@ -2053,8 +2054,8 @@ void AudioClient::noteAwakening() { bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) { Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); - qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << _outputDeviceInfo.deviceName() << ":" << _outputDeviceInfo.getDevice().deviceName() - << "-- new device: " << outputDeviceInfo.deviceName() << ":" << outputDeviceInfo.getDevice().deviceName() << "]"; + qCDebug(audioclient) << __FUNCTION__ << "_outputdeviceInfo: [" << _outputDeviceInfo.deviceName() << ":" << _outputDeviceInfo.getDevice().deviceName() + << "-- outputDeviceInfo: " << outputDeviceInfo.deviceName() << ":" << outputDeviceInfo.getDevice().deviceName() << "]"; bool supportedFormat = false; // NOTE: device start() uses the Qt internal device list @@ -2110,7 +2111,9 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi } if (!outputDeviceInfo.getDevice().isNull()) { - qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << "is available."; + qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << ":" << outputDeviceInfo.getDevice().deviceName() << " is available."; + + //do not update UI that we're changing devices if default or same device bool doEmit = _outputDeviceInfo.deviceName() != outputDeviceInfo.deviceName(); _outputDeviceInfo = outputDeviceInfo; if (doEmit) { From ac8b664537ca25b6fbf2b2c3215985818c5594d6 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 23 Oct 2019 15:39:38 -0700 Subject: [PATCH 29/31] addresing pr comments --- libraries/audio-client/src/AudioClient.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 169a975f96..995fe20886 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1817,7 +1817,7 @@ bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDevice Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); qCDebug(audioclient) << __FUNCTION__ << "_inputDeviceInfo: [" << _inputDeviceInfo.deviceName() << ":" << _inputDeviceInfo.getDevice().deviceName() - << "-- inputDeviceInfo: " << inputDeviceInfo.deviceName() << ":" << inputDeviceInfo.getDevice().deviceName() << "]"; + << "-- inputDeviceInfo:" << inputDeviceInfo.deviceName() << ":" << inputDeviceInfo.getDevice().deviceName() << "]"; bool supportedFormat = false; // NOTE: device start() uses the Qt internal device list @@ -1869,7 +1869,7 @@ bool AudioClient::switchInputToAudioDevice(const HifiAudioDeviceInfo inputDevice } if (!inputDeviceInfo.getDevice().isNull()) { - qCDebug(audioclient) << "The audio input device " << inputDeviceInfo.deviceName() << ":" << inputDeviceInfo.getDevice().deviceName() << " is available."; + qCDebug(audioclient) << "The audio input device" << inputDeviceInfo.deviceName() << ":" << inputDeviceInfo.getDevice().deviceName() << "is available."; //do not update UI that we're changing devices if default or same device bool doEmit = _inputDeviceInfo.deviceName() != inputDeviceInfo.deviceName(); @@ -2055,7 +2055,7 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); qCDebug(audioclient) << __FUNCTION__ << "_outputdeviceInfo: [" << _outputDeviceInfo.deviceName() << ":" << _outputDeviceInfo.getDevice().deviceName() - << "-- outputDeviceInfo: " << outputDeviceInfo.deviceName() << ":" << outputDeviceInfo.getDevice().deviceName() << "]"; + << "-- outputDeviceInfo:" << outputDeviceInfo.deviceName() << ":" << outputDeviceInfo.getDevice().deviceName() << "]"; bool supportedFormat = false; // NOTE: device start() uses the Qt internal device list @@ -2111,7 +2111,7 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi } if (!outputDeviceInfo.getDevice().isNull()) { - qCDebug(audioclient) << "The audio output device " << outputDeviceInfo.deviceName() << ":" << outputDeviceInfo.getDevice().deviceName() << " is available."; + qCDebug(audioclient) << "The audio output device" << outputDeviceInfo.deviceName() << ":" << outputDeviceInfo.getDevice().deviceName() << "is available."; //do not update UI that we're changing devices if default or same device bool doEmit = _outputDeviceInfo.deviceName() != outputDeviceInfo.deviceName(); From 5dd5447095e05ea222fb3a2279e3f3ac50d74b75 Mon Sep 17 00:00:00 2001 From: amerhifi Date: Thu, 24 Oct 2019 15:03:55 -0700 Subject: [PATCH 30/31] moved call to hmd device name prior to locking device mutex --- libraries/audio-client/src/AudioClient.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 995fe20886..18e8d11fc9 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -83,7 +83,6 @@ Mutex _recordMutex; HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode); - static QString getHmdAudioDeviceName(QAudio::Mode mode) { foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getAllDisplayPlugins()) { if (displayPlugin && displayPlugin->isHmd()) { @@ -100,6 +99,10 @@ static QString getHmdAudioDeviceName(QAudio::Mode mode) { // thread-safe QList getAvailableDevices(QAudio::Mode mode) { + //get hmd device name prior to locking device mutex. in case of shutdown, this thread will be locked and audio client + //cannot properly shut down. + QString hmdDeviceName = getHmdAudioDeviceName(mode); + // NOTE: availableDevices() clobbers the Qt internal device list Lock lock(_deviceMutex); auto devices = QAudioDeviceInfo::availableDevices(mode); @@ -110,8 +113,7 @@ QList getAvailableDevices(QAudio::Mode mode) { } newDevices.push_front(defaultAudioDeviceForMode(mode)); - - QString hmdDeviceName = getHmdAudioDeviceName(mode); + if (!hmdDeviceName.isNull() && !hmdDeviceName.isEmpty()) { HifiAudioDeviceInfo hmdDevice; foreach(auto device, newDevices) { @@ -803,6 +805,7 @@ void AudioClient::stop() { // Destruction of the pointers will occur when the parent object (this) is destroyed) { Lock lock(_checkDevicesMutex); + _checkDevicesTimer->stop(); _checkDevicesTimer = nullptr; } { From a67904212d3c921ea5e0719731311f7185a0da03 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 24 Oct 2019 15:52:44 -0700 Subject: [PATCH 31/31] Remove AvatarTransit log spam --- libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index bea9f979b8..277b293728 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -165,9 +165,6 @@ AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& av _status = Status::ENDED; } - if (previousStatus != _status) { - qDebug(avatars_renderer) << "AvatarTransit " << avatarTransitStatusToStringMap[(int)previousStatus] << "->" << avatarTransitStatusToStringMap[_status]; - } return _status; }