From a5c10abcac248dbce018f6b46de8bdbe111ed0a3 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 3 Oct 2019 17:04:40 -0700 Subject: [PATCH 01/37] Working on improving the material inspector --- libraries/fbx/src/FBXSerializer.cpp | 4 + .../utilities/render/materialInspector.qml | 101 ++++++++++++------ 2 files changed, 75 insertions(+), 30 deletions(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index f8339ddd31..6b30c59595 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -177,6 +177,10 @@ glm::mat4 getGlobalTransform(const QMultiMap& _connectionParen break; } } + if (fbxModel.hasGeometricOffset && visitedNodes.size() > 1) { + qCWarning(modelformat) << "Here is a parent node with Geometric offset ?????" << url; + } + } return globalTransform; } diff --git a/scripts/developer/utilities/render/materialInspector.qml b/scripts/developer/utilities/render/materialInspector.qml index d4dad203cd..91e4617216 100644 --- a/scripts/developer/utilities/render/materialInspector.qml +++ b/scripts/developer/utilities/render/materialInspector.qml @@ -13,12 +13,19 @@ import QtQuick.Layouts 1.3 import stylesUit 1.0 import controlsUit 1.0 as HifiControls +import "../lib/prop" as Prop Rectangle { HifiConstants { id: hifi;} color: Qt.rgba(hifi.colors.baseGray.r, hifi.colors.baseGray.g, hifi.colors.baseGray.b, 0.8); id: root; + property var theMaterial: {} + property var theMaterialAttributes: {} + property var hasMaterial: false + + property var isReadOnly: true + function fromScript(message) { switch (message.method) { case "setObjectInfo": @@ -26,40 +33,74 @@ Rectangle { break; case "setMaterialJSON": materialJSONText.text = message.params.materialJSONText; + + theObject = JSON.parse(message.params.materialJSONText) + theMaterialAttributes = theObject.materials + console.log(JSON.stringify(theOtheMaterialAttributesbject)) + hasMaterial = (theMaterial !== undefined) break; } } - - Rectangle { - id: entityIDContainer - height: 52 - width: root.width - color: Qt.rgba(root.color.r * 0.7, root.color.g * 0.7, root.color.b * 0.7, 0.8); - TextEdit { - id: entityIDInfo - text: "Type: Unknown\nID: None\nMesh Part: Unknown" - font.pointSize: 9 - color: "#FFFFFF" - readOnly: true - selectByMouse: true - } - } - - Original.ScrollView { - anchors.top: entityIDContainer.bottom - height: root.height - entityIDContainer.height - width: root.width - clip: true - Original.ScrollBar.horizontal.policy: Original.ScrollBar.AlwaysOff - TextEdit { - id: materialJSONText - text: "Click an object to get material JSON" + + Column { + + anchors.left: parent.left + anchors.right: parent.right + + Rectangle { + id: entityIDContainer + height: 52 width: root.width - font.pointSize: 10 - color: "#FFFFFF" - readOnly: true - selectByMouse: true - wrapMode: Text.WordWrap + color: Qt.rgba(root.color.r * 0.7, root.color.g * 0.7, root.color.b * 0.7, 0.8); + TextEdit { + id: entityIDInfo + text: "Type: Unknown\nID: None\nMesh Part: Unknown" + font.pointSize: 9 + color: "#FFFFFF" + readOnly: true + selectByMouse: true + } + } + + Prop.PropScalar { + visible: hasMaterial && ("roughness" in theMaterialAttributes) + label: "roughness" + object: theMaterialAttributes + property: "roughness" + readOnly: isReadOnly + } + Prop.PropScalar { + visible: hasMaterial && ("opacity" in theMaterialAttributes) + label: "opacity" + object: theMaterialAttributes + property: "opacity" + readOnly: isReadOnly + } + + Prop.PropString { + visible: hasMaterial && ("albedoMap" in theMaterialAttributes) + label: "roughness" + object: theMaterialAttributes + property: "roughness" + readOnly: isReadOnly + } + + Original.ScrollView { + // anchors.top: entityIDContainer.bottom + height: root.height - entityIDContainer.height + width: root.width + clip: true + Original.ScrollBar.horizontal.policy: Original.ScrollBar.AlwaysOff + TextEdit { + id: materialJSONText + text: "Click an object to get material JSON" + width: root.width + font.pointSize: 10 + color: "#FFFFFF" + readOnly: true + selectByMouse: true + wrapMode: Text.WordWrap + } } } } From a5ccd0734756cb633d15a611eef5f68c84d73e01 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 3 Oct 2019 22:43:44 -0700 Subject: [PATCH 02/37] Adding the material fields ui yeah, todo: many errors for undefined fields --- .../utilities/lib/prop/PropColor.qml | 43 ++++++ .../utilities/render/materialInspector.qml | 145 ++++++++++++++++-- 2 files changed, 178 insertions(+), 10 deletions(-) diff --git a/scripts/developer/utilities/lib/prop/PropColor.qml b/scripts/developer/utilities/lib/prop/PropColor.qml index e69de29bb2..bda19f44d6 100644 --- a/scripts/developer/utilities/lib/prop/PropColor.qml +++ b/scripts/developer/utilities/lib/prop/PropColor.qml @@ -0,0 +1,43 @@ +// +// PropItem.qml +// +// Created by Sam Gateau on 3/2/2019 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.7 + + +PropItem { + Global { id: global } + id: root + + // Scalar Prop + // property bool integral: false + // property var numDigits: 2 + + Rectangle { + id: valueLabel + + anchors.left: root.splitter.right + anchors.right: root.right + anchors.verticalCenter: root.verticalCenter + // horizontalAlignment: global.valueTextAlign + height: global.slimHeight + + function getColor() { + var c = root.valueVarGetter(); + return Qt.rgba(c.red, c.green, c.blue, 1.0); + } + + // background: Rectangle { + color: { return getColor() } + border.color: global.colorBorderLight + border.width: global.valueBorderWidth + radius: global.valueBorderRadius + // } + } +} diff --git a/scripts/developer/utilities/render/materialInspector.qml b/scripts/developer/utilities/render/materialInspector.qml index 91e4617216..4d9370dc72 100644 --- a/scripts/developer/utilities/render/materialInspector.qml +++ b/scripts/developer/utilities/render/materialInspector.qml @@ -34,9 +34,8 @@ Rectangle { case "setMaterialJSON": materialJSONText.text = message.params.materialJSONText; - theObject = JSON.parse(message.params.materialJSONText) - theMaterialAttributes = theObject.materials - console.log(JSON.stringify(theOtheMaterialAttributesbject)) + theMaterial = JSON.parse(message.params.materialJSONText) + theMaterialAttributes = theMaterial.materials hasMaterial = (theMaterial !== undefined) break; } @@ -62,6 +61,81 @@ Rectangle { } } + Prop.PropString { + visible: hasMaterial && ("name" in theMaterialAttributes) + label: "name" + object: theMaterialAttributes + property: "name" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("model" in theMaterialAttributes) + label: "model" + object: theMaterialAttributes + property: "model" + readOnly: isReadOnly + } + + Prop.PropColor { + visible: hasMaterial && ("albedo" in theMaterialAttributes) + label: "albedo" + object: theMaterialAttributes + property: "albedo" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("albedoMap" in theMaterialAttributes) + label: "albedoMap" + object: theMaterialAttributes + property: "albedoMap" + readOnly: isReadOnly + } + + Prop.PropScalar { + visible: hasMaterial && ("opacity" in theMaterialAttributes) + label: "opacity" + object: theMaterialAttributes + property: "opacity" + readOnly: isReadOnly + } + Prop.PropEnum { + visible: hasMaterial && ("opacityMapMode" in theMaterialAttributes) + label: "opacityMapMode" + object: theMaterialAttributes + property: "opacityMapMode" + readOnly: isReadOnly + enums: ["None", "Mask", "Blend"] + } + Prop.PropScalar { + visible: hasMaterial && ("opacityCutoff" in theMaterialAttributes) + label: "opacity Cutoff" + object: theMaterialAttributes + property: "opacityCutoff" + readOnly: isReadOnly + } + + Prop.PropString { + visible: hasMaterial && ("occlusionMap" in theMaterialAttributes) + label: "occlusionMap" + object: theMaterialAttributes + property: "occlusionMap" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("normalMap" in theMaterialAttributes) + label: "normalMap" + object: theMaterialAttributes + property: "normalMap" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("bumpMap" in theMaterialAttributes) + label: "normalMap from bumpMap" + object: theMaterialAttributes + property: "bumpMap" + readOnly: isReadOnly + } + Prop.PropScalar { visible: hasMaterial && ("roughness" in theMaterialAttributes) label: "roughness" @@ -70,18 +144,69 @@ Rectangle { readOnly: isReadOnly } Prop.PropScalar { - visible: hasMaterial && ("opacity" in theMaterialAttributes) - label: "opacity" + visible: hasMaterial && ("metallic" in theMaterialAttributes) + label: "metallic" object: theMaterialAttributes - property: "opacity" + property: "metallic" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("roughnessMap" in theMaterialAttributes) + label: "roughnessMap" + object: theMaterialAttributes + property: "roughnessMap" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("glossMap" in theMaterialAttributes) + label: "roughnessMap from glossMap" + object: theMaterialAttributes + property: "glossMap" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("metallicMap" in theMaterialAttributes) + label: "metallicMap" + object: theMaterialAttributes + property: "metallicMap" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("specularMap" in theMaterialAttributes) + label: "metallicMap from specularMap" + object: theMaterialAttributes + property: "specularMap" readOnly: isReadOnly } - Prop.PropString { - visible: hasMaterial && ("albedoMap" in theMaterialAttributes) - label: "roughness" + Prop.PropScalar { + visible: hasMaterial && ("scattering" in theMaterialAttributes) + label: "scattering" object: theMaterialAttributes - property: "roughness" + property: "scattering" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("scatteringMap" in theMaterialAttributes) + label: "scatteringMap" + object: theMaterialAttributes + property: "scatteringMap" + readOnly: isReadOnly + } + + + Prop.PropColor { + visible: hasMaterial && ("emissive" in theMaterialAttributes) + label: "emissive" + object: theMaterialAttributes + property: "emissive" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("emissiveMap" in theMaterialAttributes) + label: "emissiveMap" + object: theMaterialAttributes + property: "emissiveMap" readOnly: isReadOnly } From d714cc6da6ad8c54d1228619b778c1e46635837b Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 4 Oct 2019 17:55:37 -0700 Subject: [PATCH 03/37] FIxing some stuff ? --- .../utilities/render/materialInspector.qml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/scripts/developer/utilities/render/materialInspector.qml b/scripts/developer/utilities/render/materialInspector.qml index 4d9370dc72..31d5651dd9 100644 --- a/scripts/developer/utilities/render/materialInspector.qml +++ b/scripts/developer/utilities/render/materialInspector.qml @@ -98,14 +98,28 @@ Rectangle { property: "opacity" readOnly: isReadOnly } - Prop.PropEnum { + Prop.PropString { + visible: hasMaterial && ("opacityMap" in theMaterialAttributes) + label: "opacityMap" + object: theMaterialAttributes + property: "opacityMap" + readOnly: isReadOnly + } + Prop.PropString { + visible: hasMaterial && ("opacityMapMode" in theMaterialAttributes) + label: "opacityMapMode" + object: theMaterialAttributes + property: "opacityMapMode" + readOnly: isReadOnly + } + /*Prop.PropEnum { visible: hasMaterial && ("opacityMapMode" in theMaterialAttributes) label: "opacityMapMode" object: theMaterialAttributes property: "opacityMapMode" readOnly: isReadOnly enums: ["None", "Mask", "Blend"] - } + } */ Prop.PropScalar { visible: hasMaterial && ("opacityCutoff" in theMaterialAttributes) label: "opacity Cutoff" From fc018257e1c5cec851da80c0b5366db03c6db04d Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 9 Oct 2019 12:20:35 -0700 Subject: [PATCH 04/37] 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 05/37] 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 e708cb98bb0f6813cedc343f33b67d23d01ec67b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 15 Oct 2019 11:29:49 +1300 Subject: [PATCH 06/37] Fix crash in Recorder.stopRecording() when no recording is being made --- libraries/script-engine/src/RecordingScriptingInterface.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/script-engine/src/RecordingScriptingInterface.cpp b/libraries/script-engine/src/RecordingScriptingInterface.cpp index f95edb482b..21bb7fca3f 100644 --- a/libraries/script-engine/src/RecordingScriptingInterface.cpp +++ b/libraries/script-engine/src/RecordingScriptingInterface.cpp @@ -195,6 +195,11 @@ void RecordingScriptingInterface::startRecording() { } void RecordingScriptingInterface::stopRecording() { + if (!_recorder->isRecording()) { + qCWarning(scriptengine) << "Recorder is not running"; + return; + } + _recorder->stop(); _lastClip = _recorder->getClip(); _lastClip->seek(0); From b793e23cb096b922de2f793619e3c2de926ce94f Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 15 Oct 2019 15:24:41 +1300 Subject: [PATCH 07/37] 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 185d6990ebc7360a31d54331d06765d2e9a1065a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 16 Oct 2019 09:17:29 +1300 Subject: [PATCH 08/37] Add missing threading checks to Recording API methods --- .../src/RecordingScriptingInterface.cpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/libraries/script-engine/src/RecordingScriptingInterface.cpp b/libraries/script-engine/src/RecordingScriptingInterface.cpp index 21bb7fca3f..cbcf94662e 100644 --- a/libraries/script-engine/src/RecordingScriptingInterface.cpp +++ b/libraries/script-engine/src/RecordingScriptingInterface.cpp @@ -64,6 +64,11 @@ void RecordingScriptingInterface::playClip(NetworkClipLoaderPointer clipLoader, } void RecordingScriptingInterface::loadRecording(const QString& url, QScriptValue callback) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "loadRecording", Q_ARG(const QString&, url), Q_ARG(QScriptValue, callback)); + return; + } + auto clipLoader = DependencyManager::get()->getClipLoader(url); if (clipLoader->isLoaded()) { @@ -117,6 +122,11 @@ void RecordingScriptingInterface::startPlaying() { } void RecordingScriptingInterface::setPlayerVolume(float volume) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "setPlayerVolume", Q_ARG(float, volume)); + return; + } + _player->setVolume(std::min(std::max(volume, 0.0f), 1.0f)); } @@ -137,6 +147,11 @@ void RecordingScriptingInterface::setPlayFromCurrentLocation(bool playFromCurren } void RecordingScriptingInterface::setPlayerLoop(bool loop) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "setPlayerLoop", Q_ARG(bool, loop)); + return; + } + _player->loop(loop); } @@ -200,6 +215,11 @@ void RecordingScriptingInterface::stopRecording() { return; } + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "stopRecording"); + return; + } + _recorder->stop(); _lastClip = _recorder->getClip(); _lastClip->seek(0); From 93a1adc736a649c7a004867ac20700a18548267c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 15 Oct 2019 18:25:33 -0700 Subject: [PATCH 09/37] Fix camera position in first person --- interface/src/Application.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 47 +++++++++++++++++++++++++++++++ interface/src/avatar/MyAvatar.h | 4 +++ libraries/animation/src/Rig.h | 20 +++++++------ 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 92bc54d43f..ba7cf472ed 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3618,7 +3618,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _myCamera.setPosition(extractTranslation(camMat)); _myCamera.setOrientation(glmExtractRotation(camMat)); } else { - _myCamera.setPosition(myAvatar->getLookAtPivotPoint()); + _myCamera.setPosition(myAvatar->getCameraEyesPosition(deltaTime)); _myCamera.setOrientation(myAvatar->getLookAtRotation()); } } else if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 74305975ae..70c8d7f422 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -6812,6 +6812,53 @@ glm::vec3 MyAvatar::getLookAtPivotPoint() { return yAxisEyePosition; } +glm::vec3 MyAvatar::getCameraEyesPosition(float deltaTime) { + glm::vec3 defaultEyesPosition = getLookAtPivotPoint(); + if (isFlying()) { + return defaultEyesPosition; + } + glm::vec3 avatarFrontVector = getWorldOrientation() * Vectors::FRONT; + glm::vec3 avatarUpVector = getWorldOrientation() * Vectors::UP; + // Compute the offset between the default and real eye positions. + glm::vec3 defaultEyesToEyesVector = getHead()->getEyePosition() - defaultEyesPosition; + float FRONT_OFFSET_IDLE_MULTIPLIER = 2.0f; + float FRONT_OFFSET_JUMP_MULTIPLIER = 1.5f; + float frontOffset = FRONT_OFFSET_IDLE_MULTIPLIER * glm::length(defaultEyesPosition - getDefaultEyePosition()); + + // Looking down will aproximate move the camera forward to meet the real eye position + float mixAlpha = glm::dot(_lookAtPitch * Vectors::FRONT, -avatarUpVector); + + // When jumping the camera should follow the real eye on the Y coordenate + float upOffset = 0.0f; + if (isJumping() || _characterController.getState() == CharacterController::State::Takeoff) { + upOffset = glm::dot(defaultEyesToEyesVector, avatarUpVector); + + frontOffset = glm::dot(defaultEyesToEyesVector, avatarFrontVector) * FRONT_OFFSET_JUMP_MULTIPLIER; + mixAlpha = 1.0f; + } else { + // Limit the range effect from 45 to 90 degrees + const float HEAD_OFFSET_DOT_THRESHOLD = 0.7f; // 45 degrees aprox + mixAlpha = mixAlpha < HEAD_OFFSET_DOT_THRESHOLD ? 0.0f : (mixAlpha - HEAD_OFFSET_DOT_THRESHOLD) / + (1.0f - HEAD_OFFSET_DOT_THRESHOLD); + } + const float FPS = 60.0f; + float timeScale = deltaTime * FPS; + frontOffset = frontOffset < 0.0f ? 0.0f : mixAlpha * frontOffset; + glm::vec3 cameraOffset = upOffset * Vectors::UP + frontOffset * Vectors::FRONT; + const float TAU = 0.1f; + _cameraEyesOffset = _cameraEyesOffset + (cameraOffset - _cameraEyesOffset) * TAU * timeScale; + glm::vec3 estimatedCameraPosition = defaultEyesPosition + getWorldOrientation() * _cameraEyesOffset; + return estimatedCameraPosition; +} + +bool MyAvatar::isJumping() { + if (_skeletonModel->isLoaded()) { + return (_skeletonModel->getRig().getState() == Rig::RigRole::InAir || + _skeletonModel->getRig().getState() == Rig::RigRole::Takeoff) && !isFlying(); + } + return false; +} + bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { if (QThread::currentThread() != thread()) { bool result = false; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 0f139ddbff..00ad0af398 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1919,6 +1919,8 @@ public: bool getIsJointOverridden(int jointIndex) const; glm::vec3 getLookAtPivotPoint(); + glm::vec3 getCameraEyesPosition(float deltaTime); + bool isJumping(); public slots: @@ -2973,6 +2975,8 @@ private: // used to prevent character from jumping after endSit is called. bool _endSitKeyPressComplete { false }; + + glm::vec3 _cameraEyesOffset; }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 8f5eddac00..f47dbc37e1 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -115,6 +115,16 @@ public: Seated }; + enum class RigRole { + Idle = 0, + Turn, + Move, + Hover, + Takeoff, + InAir, + Seated + }; + Rig(); virtual ~Rig(); @@ -257,6 +267,7 @@ public: bool getFlowActive() const; bool getNetworkGraphActive() const; void setDirectionalBlending(const QString& targetName, const glm::vec3& blendingTarget, const QString& alphaName, float alpha); + const RigRole getState() const { return _state; } signals: void onLoadComplete(); @@ -339,15 +350,6 @@ protected: AnimVariantMap _animVars; AnimVariantMap _networkVars; - enum class RigRole { - Idle = 0, - Turn, - Move, - Hover, - Takeoff, - InAir, - Seated - }; RigRole _state { RigRole::Idle }; RigRole _desiredState { RigRole::Idle }; float _desiredStateAge { 0.0f }; From 02837be13fcbaefc1353583bfa04c7e3e5a6e1ad Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 16 Oct 2019 09:04:03 -0700 Subject: [PATCH 10/37] Get state using CharacterController --- interface/src/avatar/MyAvatar.cpp | 9 +++------ libraries/animation/src/Rig.h | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 70c8d7f422..1c87e301a4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -6846,17 +6846,14 @@ glm::vec3 MyAvatar::getCameraEyesPosition(float deltaTime) { frontOffset = frontOffset < 0.0f ? 0.0f : mixAlpha * frontOffset; glm::vec3 cameraOffset = upOffset * Vectors::UP + frontOffset * Vectors::FRONT; const float TAU = 0.1f; - _cameraEyesOffset = _cameraEyesOffset + (cameraOffset - _cameraEyesOffset) * TAU * timeScale; + _cameraEyesOffset = _cameraEyesOffset + (cameraOffset - _cameraEyesOffset) * min(1.0f, TAU * timeScale); glm::vec3 estimatedCameraPosition = defaultEyesPosition + getWorldOrientation() * _cameraEyesOffset; return estimatedCameraPosition; } bool MyAvatar::isJumping() { - if (_skeletonModel->isLoaded()) { - return (_skeletonModel->getRig().getState() == Rig::RigRole::InAir || - _skeletonModel->getRig().getState() == Rig::RigRole::Takeoff) && !isFlying(); - } - return false; + return (_characterController.getState() == CharacterController::State::InAir || + _characterController.getState() == CharacterController::State::Takeoff) && !isFlying(); } bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index f47dbc37e1..5f881fb8e7 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -115,16 +115,6 @@ public: Seated }; - enum class RigRole { - Idle = 0, - Turn, - Move, - Hover, - Takeoff, - InAir, - Seated - }; - Rig(); virtual ~Rig(); @@ -267,7 +257,6 @@ public: bool getFlowActive() const; bool getNetworkGraphActive() const; void setDirectionalBlending(const QString& targetName, const glm::vec3& blendingTarget, const QString& alphaName, float alpha); - const RigRole getState() const { return _state; } signals: void onLoadComplete(); @@ -350,6 +339,16 @@ protected: AnimVariantMap _animVars; AnimVariantMap _networkVars; + enum class RigRole { + Idle = 0, + Turn, + Move, + Hover, + Takeoff, + InAir, + Seated + }; + RigRole _state { RigRole::Idle }; RigRole _desiredState { RigRole::Idle }; float _desiredStateAge { 0.0f }; From a9aeceff55da7787ece3f05f3e82a6ecfe7618c4 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 16 Oct 2019 09:09:22 -0700 Subject: [PATCH 11/37] Undo rig changes --- libraries/animation/src/Rig.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 5f881fb8e7..8f5eddac00 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -348,7 +348,6 @@ protected: InAir, Seated }; - RigRole _state { RigRole::Idle }; RigRole _desiredState { RigRole::Idle }; float _desiredStateAge { 0.0f }; From 9f0e82e1e65deeaf372645bac81443deb402f70a Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 16 Oct 2019 15:29:28 -0700 Subject: [PATCH 12/37] 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 e83ac8c0ddc372dea9e9e86d309cca7f6398f9d2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Oct 2019 16:13:38 -0700 Subject: [PATCH 13/37] Remove call to processEvents on Mac in ~Application --- interface/src/Application.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 92bc54d43f..7649ec1c99 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2959,13 +2959,29 @@ Application::~Application() { qInstallMessageHandler(LogHandler::verboseMessageHandler); #ifdef Q_OS_MAC + // 10/16/2019 - Disabling this call. This causes known crashes (A), and it is not + // fully understood whether it might cause other unknown crashes (B). + // + // (A) Although we try to shutdown the ScriptEngine threads in onAboutToQuit, there is + // currently no guarantee that they have stopped. Waiting on them to stop has so far appeared to + // never return on Mac, causing the application to hang on shutdown. Because ScriptEngines + // may still be running, they may end up receiving events that are triggered from this processEvents call, + // and then try to access resources that are no longer available at this point in time. + // If the ScriptEngine threads were fully destroyed before getting here, this would + // not be an issue. + // + // (B) It seems likely that a bunch of potential event handlers are dependent on Application + // and other common dependencies to be available and not destroyed or in the middle of being + // destroyed. + + // Clear the event queue before application is totally destructed. // This will drain the messasge queue of pending "deleteLaters" queued up // during shutdown of the script engines. // We do this here because there is a possiblty that [NSApplication terminate:] // will be called during processEvents which will invoke all static destructors. // We want to postpone this utill the last possible moment. - QCoreApplication::processEvents(); + //QCoreApplication::processEvents(); #endif } From 84eab3cdd47c08d2ea911b39254640e237ba6b1c Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 16 Oct 2019 16:58:37 -0700 Subject: [PATCH 14/37] Remove excessive avatar-mixer logging --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 46ca51219d..32c944f5b8 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -448,13 +448,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // or that somehow we haven't sent if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) { ++numAvatarsHeldBack; - - // BUGZ-781 verbose debugging: - auto usecLastTimeSent = destinationNodeData->getLastOtherAvatarEncodeTime(sourceAvatarNodeData->getNodeLocalID()); - if (usecLastTimeSent != 0 && startIgnoreCalculation - usecLastTimeSent > 10 * USECS_PER_SECOND) { - qCDebug(avatars) << "Not sent avatar" << *sourceAvatarNode << "to Node" << *destinationNode << "in > 10 s"; - } - sendAvatar = false; } else if (lastSeqFromSender == 0) { // We have have not yet received any data about this avatar. Ignore it for now From 9000b4c7f8d39df325f642c1a8e430cf5e79744c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 16 Oct 2019 17:28:34 -0700 Subject: [PATCH 15/37] Tweak camera position in first person to further hide neck --- interface/src/avatar/MyAvatar.cpp | 34 +++++++++++++++++++++++-------- interface/src/avatar/MyAvatar.h | 1 + 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7055ec0246..207460c0c4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -6821,32 +6821,48 @@ glm::vec3 MyAvatar::getCameraEyesPosition(float deltaTime) { glm::vec3 avatarUpVector = getWorldOrientation() * Vectors::UP; // Compute the offset between the default and real eye positions. glm::vec3 defaultEyesToEyesVector = getHead()->getEyePosition() - defaultEyesPosition; - float FRONT_OFFSET_IDLE_MULTIPLIER = 2.0f; + float FRONT_OFFSET_IDLE_MULTIPLIER = 2.5f; float FRONT_OFFSET_JUMP_MULTIPLIER = 1.5f; float frontOffset = FRONT_OFFSET_IDLE_MULTIPLIER * glm::length(defaultEyesPosition - getDefaultEyePosition()); // Looking down will aproximate move the camera forward to meet the real eye position float mixAlpha = glm::dot(_lookAtPitch * Vectors::FRONT, -avatarUpVector); - + bool isLanding = false; // When jumping the camera should follow the real eye on the Y coordenate float upOffset = 0.0f; if (isJumping() || _characterController.getState() == CharacterController::State::Takeoff) { upOffset = glm::dot(defaultEyesToEyesVector, avatarUpVector); - frontOffset = glm::dot(defaultEyesToEyesVector, avatarFrontVector) * FRONT_OFFSET_JUMP_MULTIPLIER; mixAlpha = 1.0f; + _landingAfterJumpTime = 0.0f; } else { - // Limit the range effect from 45 to 90 degrees - const float HEAD_OFFSET_DOT_THRESHOLD = 0.7f; // 45 degrees aprox - mixAlpha = mixAlpha < HEAD_OFFSET_DOT_THRESHOLD ? 0.0f : (mixAlpha - HEAD_OFFSET_DOT_THRESHOLD) / - (1.0f - HEAD_OFFSET_DOT_THRESHOLD); + // Limit the range effect from 45 to 0 degrees + // between the front camera and the down vectors + const float HEAD_OFFSET_RANGE_IN_DEGREES = 45.0f; + const float HEAD_OFFSET_RANGE_OUT_DEGREES = 0.0f; + float rangeIn = glm::cos(glm::radians(HEAD_OFFSET_RANGE_IN_DEGREES)); + float rangeOut = glm::cos(glm::radians(HEAD_OFFSET_RANGE_OUT_DEGREES)); + mixAlpha = mixAlpha < rangeIn ? 0.0f : (mixAlpha - rangeIn) / (rangeOut - rangeIn); + const float WAIT_TO_LAND_TIME = 1.0f; + if (_landingAfterJumpTime < WAIT_TO_LAND_TIME) { + _landingAfterJumpTime += deltaTime; + isLanding = true; + } } const float FPS = 60.0f; float timeScale = deltaTime * FPS; frontOffset = frontOffset < 0.0f ? 0.0f : mixAlpha * frontOffset; glm::vec3 cameraOffset = upOffset * Vectors::UP + frontOffset * Vectors::FRONT; - const float TAU = 0.1f; - _cameraEyesOffset = _cameraEyesOffset + (cameraOffset - _cameraEyesOffset) * min(1.0f, TAU * timeScale); + const float JUMPING_TAU = 0.1f; + const float NO_JUMP_TAU = 0.3f; + const float LANDING_TAU = 0.05f; + float tau = NO_JUMP_TAU; + if (isJumping()) { + tau = JUMPING_TAU; + } else if (isLanding) { + tau = LANDING_TAU; + } + _cameraEyesOffset = _cameraEyesOffset + (cameraOffset - _cameraEyesOffset) * min(1.0f, tau * timeScale); glm::vec3 estimatedCameraPosition = defaultEyesPosition + getWorldOrientation() * _cameraEyesOffset; return estimatedCameraPosition; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 00ad0af398..081fd00d5b 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -2977,6 +2977,7 @@ private: bool _endSitKeyPressComplete { false }; glm::vec3 _cameraEyesOffset; + float _landingAfterJumpTime { 0.0f }; }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); From 63c2b4192993da7a8c6bf79dea2b62e4967cf0bb Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 17 Oct 2019 13:26:42 -0700 Subject: [PATCH 16/37] Restate legacy first person camera mode --- .../settingsApp/general/General.qml | 6 +-- interface/src/Application.cpp | 50 +++++++++++-------- interface/src/Menu.cpp | 2 +- interface/src/Menu.h | 3 +- interface/src/avatar/MyAvatar.cpp | 28 ++++++----- .../src/avatars-renderer/Avatar.cpp | 3 +- libraries/shared/src/shared/Camera.cpp | 14 +++++- libraries/shared/src/shared/Camera.h | 1 + scripts/simplifiedUI/ui/simplifiedUI.js | 2 +- scripts/system/firstPersonHMD.js | 2 +- scripts/system/interstitialPage.js | 2 +- scripts/system/libraries/WebTablet.js | 4 +- scripts/system/miniTablet.js | 4 +- 13 files changed, 72 insertions(+), 49 deletions(-) diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml index 7a98849b95..6a59816af8 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml @@ -225,9 +225,9 @@ Flickable { SimplifiedControls.RadioButton { id: firstPerson text: "First Person View" - checked: Camera.mode === "first person" + checked: Camera.mode === "first person look at" onClicked: { - Camera.mode = "first person" + Camera.mode = "first person look at" } } @@ -254,7 +254,7 @@ Flickable { target: Camera onModeUpdated: { - if (Camera.mode === "first person") { + if (Camera.mode === "first person look at") { firstPerson.checked = true } else if (Camera.mode === "look at") { thirdPerson.checked = true diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a10e17c010..d11c1ac5e0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -717,7 +717,8 @@ private: static const QString STATE_IN_HMD = "InHMD"; static const QString STATE_CAMERA_FULL_SCREEN_MIRROR = "CameraFSM"; -static const QString STATE_CAMERA_FIRST_PERSON = "CameraFirstPerson"; +static const QString STATE_CAMERA_FIRST_PERSON = "CameraFirstPersonLegacy"; +static const QString STATE_CAMERA_FIRST_PERSON_LOOK_AT = "CameraFirstPersonLookat"; static const QString STATE_CAMERA_THIRD_PERSON = "CameraThirdPerson"; static const QString STATE_CAMERA_ENTITY = "CameraEntity"; static const QString STATE_CAMERA_INDEPENDENT = "CameraIndependent"; @@ -939,7 +940,8 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR, - STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE, + STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_FIRST_PERSON_LOOK_AT, STATE_CAMERA_THIRD_PERSON, + STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE, STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED, STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID, STATE_LEFT_HAND_DOMINANT, STATE_RIGHT_HAND_DOMINANT, STATE_STRAFE_ENABLED } }); DependencyManager::set(); @@ -1887,6 +1889,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _applicationStateDevice->setInputVariant(STATE_CAMERA_FIRST_PERSON, []() -> float { return qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON ? 1 : 0; }); + _applicationStateDevice->setInputVariant(STATE_CAMERA_FIRST_PERSON_LOOK_AT, []() -> float { + return qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON_LOOK_AT ? 1 : 0; + }); _applicationStateDevice->setInputVariant(STATE_CAMERA_THIRD_PERSON, []() -> float { return qApp->getCamera().getMode() == CAMERA_MODE_THIRD_PERSON ? 1 : 0; }); @@ -1996,7 +2001,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo settingsTimer->start(); }, QThread::LowestPriority); - if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { + if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPersonLookAt)) { getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); // So that camera doesn't auto-switch to third person. } @@ -3627,12 +3632,15 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { // Using the latter will cause the camera to wobble with idle animations, // or with changes from the face tracker CameraMode mode = _myCamera.getMode(); - if (mode == CAMERA_MODE_FIRST_PERSON) { + if (mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) { _thirdPersonHMDCameraBoomValid= false; if (isHMDMode()) { mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); _myCamera.setPosition(extractTranslation(camMat)); _myCamera.setOrientation(glmExtractRotation(camMat)); + } else if (mode == CAMERA_MODE_FIRST_PERSON) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); } else { _myCamera.setPosition(myAvatar->getCameraEyesPosition(deltaTime)); _myCamera.setOrientation(myAvatar->getLookAtRotation()); @@ -4423,7 +4431,7 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_1: { Menu* menu = Menu::getInstance(); - menu->triggerOption(MenuOption::FirstPerson); + menu->triggerOption(MenuOption::FirstPersonLookAt); break; } case Qt::Key_2: { @@ -5508,7 +5516,7 @@ void Application::loadSettings() { isFirstPerson = menu->isOptionChecked(MenuOption::FirstPersonHMD); } else { // if HMD is not active, only use first person if the menu option is checked - isFirstPerson = menu->isOptionChecked(MenuOption::FirstPerson); + isFirstPerson = menu->isOptionChecked(MenuOption::FirstPersonLookAt); } } } @@ -5523,9 +5531,9 @@ void Application::loadSettings() { // finish initializing the camera, based on everything we checked above. Third person camera will be used if no settings // dictated that we should be in first person - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, isFirstPerson); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPersonLookAt, isFirstPerson); Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !isFirstPerson); - _myCamera.setMode((isFirstPerson) ? CAMERA_MODE_FIRST_PERSON : CAMERA_MODE_LOOK_AT); + _myCamera.setMode((isFirstPerson) ? CAMERA_MODE_FIRST_PERSON_LOOK_AT : CAMERA_MODE_LOOK_AT); cameraMenuChanged(); auto inputs = pluginManager->getInputPlugins(); @@ -5689,7 +5697,7 @@ void Application::pauseUntilLoginDetermined() { menu->getMenu("Developer")->setVisible(false); } _previousCameraMode = _myCamera.getMode(); - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON_LOOK_AT); cameraModeChanged(); // disconnect domain handler. @@ -5878,11 +5886,11 @@ void Application::cycleCamera() { if (menu->isOptionChecked(MenuOption::FullscreenMirror)) { menu->setIsOptionChecked(MenuOption::FullscreenMirror, false); - menu->setIsOptionChecked(MenuOption::FirstPerson, true); + menu->setIsOptionChecked(MenuOption::FirstPersonLookAt, true); - } else if (menu->isOptionChecked(MenuOption::FirstPerson)) { + } else if (menu->isOptionChecked(MenuOption::FirstPersonLookAt)) { - menu->setIsOptionChecked(MenuOption::FirstPerson, false); + menu->setIsOptionChecked(MenuOption::FirstPersonLookAt, false); menu->setIsOptionChecked(MenuOption::LookAtCamera, true); } else if (menu->isOptionChecked(MenuOption::LookAtCamera)) { @@ -5901,8 +5909,8 @@ void Application::cycleCamera() { void Application::cameraModeChanged() { switch (_myCamera.getMode()) { - case CAMERA_MODE_FIRST_PERSON: - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true); + case CAMERA_MODE_FIRST_PERSON_LOOK_AT: + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPersonLookAt, true); break; case CAMERA_MODE_LOOK_AT: Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, true); @@ -5922,12 +5930,12 @@ void Application::changeViewAsNeeded(float boomLength) { // This is called when the boom length has changed bool boomLengthGreaterThanMinimum = (boomLength > MyAvatar::ZOOM_MIN); - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON && boomLengthGreaterThanMinimum) { - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false); + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON_LOOK_AT && boomLengthGreaterThanMinimum) { + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPersonLookAt, false); Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, true); cameraMenuChanged(); } else if (_myCamera.getMode() == CAMERA_MODE_LOOK_AT && !boomLengthGreaterThanMinimum) { - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPersonLookAt, true); Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, false); cameraMenuChanged(); } @@ -5935,9 +5943,9 @@ void Application::changeViewAsNeeded(float boomLength) { void Application::cameraMenuChanged() { auto menu = Menu::getInstance(); - if (menu->isOptionChecked(MenuOption::FirstPerson)) { - if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + if (menu->isOptionChecked(MenuOption::FirstPersonLookAt)) { + if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON_LOOK_AT) { + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON_LOOK_AT); getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); } } else if (menu->isOptionChecked(MenuOption::LookAtCamera)) { @@ -9038,7 +9046,7 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) { } if (isHmd && menu->isOptionChecked(MenuOption::FirstPersonHMD)) { - menu->setIsOptionChecked(MenuOption::FirstPerson, true); + menu->setIsOptionChecked(MenuOption::FirstPersonLookAt, true); cameraMenuChanged(); } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5be4db46a0..5a3bb36ca2 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -172,7 +172,7 @@ Menu::Menu() { // View > First Person auto firstPersonAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash( - viewMenu, MenuOption::FirstPerson, 0, + viewMenu, MenuOption::FirstPersonLookAt, 0, true, qApp, SLOT(cameraMenuChanged()))); firstPersonAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup)); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index e3080e60aa..4a2a97b168 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -111,7 +111,8 @@ namespace MenuOption { const QString ExpandSimulationTiming = "Expand /simulation"; const QString ExpandPhysicsTiming = "Expand /physics"; const QString ExpandUpdateTiming = "Expand /update"; - const QString FirstPerson = "First Person"; + const QString FirstPerson = "First Person Legacy"; + const QString FirstPersonLookAt = "First Person"; const QString FirstPersonHMD = "Enter First Person Mode in HMD"; const QString FivePointCalibration = "5 Point Calibration"; const QString FixGaze = "Fix Gaze (no saccade)"; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 207460c0c4..6e0bfab69b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -958,7 +958,8 @@ void MyAvatar::simulate(float deltaTime, bool inView) { head->setScale(getModelScale()); head->simulate(deltaTime); CameraMode mode = qApp->getCamera().getMode(); - if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { + 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 { @@ -2178,7 +2179,7 @@ void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) { glm::vec3 myForward = _lookAtYaw * IDENTITY_FORWARD; glm::vec3 myPosition = getHead()->getEyePosition(); CameraMode mode = qApp->getCamera().getMode(); - if (mode == CAMERA_MODE_FIRST_PERSON) { + if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON) { myPosition = qApp->getCamera().getPosition(); } @@ -2719,7 +2720,7 @@ void MyAvatar::updateMotors() { if (_characterController.getState() == CharacterController::State::Hover || _characterController.computeCollisionMask() == BULLET_COLLISION_MASK_COLLISIONLESS) { CameraMode mode = qApp->getCamera().getMode(); - if (!qApp->isHMDMode() && (mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE)) { + if (!qApp->isHMDMode() && (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE)) { motorRotation = getLookAtRotation(); } else { motorRotation = getMyHead()->getHeadOrientation(); @@ -3399,7 +3400,8 @@ bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const { bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { bool defaultMode = renderArgs->_renderMode == RenderArgs::DEFAULT_RENDER_MODE; - bool firstPerson = qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON; + bool firstPerson = qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON_LOOK_AT || + qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON; bool overrideAnim = _skeletonModel ? _skeletonModel->getRig().isPlayingOverrideAnimation() : false; bool insideHead = cameraInsideHead(renderArgs->getViewFrustum().getPosition()); return !defaultMode || (!firstPerson && !insideHead) || (overrideAnim && !insideHead); @@ -3444,8 +3446,8 @@ void MyAvatar::updateOrientation(float deltaTime) { float targetSpeed = getDriveKey(YAW) * _yawSpeed; CameraMode mode = qApp->getCamera().getMode(); bool computeLookAt = isReadyForPhysics() && !qApp->isHMDMode() && - (mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE); - bool smoothCameraYaw = computeLookAt && mode != CAMERA_MODE_FIRST_PERSON; + (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE); + bool smoothCameraYaw = computeLookAt && mode != CAMERA_MODE_FIRST_PERSON_LOOK_AT; if (smoothCameraYaw) { // For "Look At" and "Selfie" camera modes we also smooth the yaw rotation from right-click mouse movement. float speedFromDeltaYaw = deltaTime > FLT_EPSILON ? getDriveKey(DELTA_YAW) / deltaTime : 0.0f; @@ -3569,11 +3571,11 @@ void MyAvatar::updateOrientation(float deltaTime) { if (isMovingFwdBwd) { if (isMovingSideways) { // Reorient avatar to face camera diagonal - blend = mode == CAMERA_MODE_FIRST_PERSON ? 1.0f : DIAGONAL_TURN_BLEND; + blend = mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT ? 1.0f : DIAGONAL_TURN_BLEND; float turnSign = getDriveKey(TRANSLATE_Z) < 0.0f ? -1.0f : 1.0f; turnSign = getDriveKey(TRANSLATE_X) > 0.0f ? -turnSign : turnSign; faceRotation = _lookAtYaw * glm::angleAxis(turnSign * 0.25f * PI, Vectors::UP); - } else if (mode == CAMERA_MODE_FIRST_PERSON) { + } else if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) { blend = 1.0f; } } @@ -3644,11 +3646,11 @@ void MyAvatar::updateOrientation(float deltaTime) { glm::vec3 ajustedYawVector = cameraYawVector; float limitAngle = 0.0f; float triggerAngle = -glm::sin(glm::radians(TRIGGER_REORIENT_ANGLE)); - if (mode == CAMERA_MODE_FIRST_PERSON) { + if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) { limitAngle = glm::sin(glm::radians(90.0f - FIRST_PERSON_TRIGGER_REORIENT_ANGLE)); triggerAngle = limitAngle; } - float reorientAngle = mode == CAMERA_MODE_FIRST_PERSON ? FIRST_PERSON_REORIENT_ANGLE : DEFAULT_REORIENT_ANGLE; + float reorientAngle = mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT ? FIRST_PERSON_REORIENT_ANGLE : DEFAULT_REORIENT_ANGLE; if (frontBackDot < limitAngle) { if (frontBackDot < 0.0f) { ajustedYawVector = (leftRightDot < 0.0f ? -avatarVectorRight : avatarVectorRight); @@ -3684,7 +3686,7 @@ void MyAvatar::updateOrientation(float deltaTime) { } _headLookAtActive = true; const float FIRST_PERSON_RECENTER_SECONDS = 15.0f; - if (mode == CAMERA_MODE_FIRST_PERSON) { + if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) { if (getDriveKey(YAW) + getDriveKey(STEP_YAW) + getDriveKey(DELTA_YAW) == 0.0f) { if (_firstPersonSteadyHeadTimer < FIRST_PERSON_RECENTER_SECONDS) { if (_firstPersonSteadyHeadTimer > 0.0f) { @@ -3772,7 +3774,7 @@ glm::vec3 MyAvatar::scaleMotorSpeed(const glm::vec3 forward, const glm::vec3 rig // Desktop mode. direction = (zSpeed * forward) + (xSpeed * right); CameraMode mode = qApp->getCamera().getMode(); - if ((mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_SELFIE) && + if ((mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_SELFIE) && zSpeed != 0.0f && xSpeed != 0.0f && !isFlying()){ direction = (zSpeed * forward); } @@ -5437,7 +5439,7 @@ glm::quat MyAvatar::getOrientationForAudio() { case AudioListenerMode::FROM_HEAD: { // Using the camera's orientation instead, when the current mode is controlling the avatar's head. CameraMode mode = qApp->getCamera().getMode(); - bool headFollowsCamera = mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE; + bool headFollowsCamera = mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE; result = headFollowsCamera ? qApp->getCamera().getOrientation() : getHead()->getFinalOrientationInWorldFrame(); break; } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 7a2ea5321f..d6db75180d 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -854,7 +854,8 @@ void Avatar::render(RenderArgs* renderArgs) { float distanceToTarget = glm::length(toTarget); const float DISPLAYNAME_DISTANCE = 20.0f; updateDisplayNameAlpha(distanceToTarget < DISPLAYNAME_DISTANCE); - if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) { + if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON_LOOK_AT + || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) { auto& frustum = renderArgs->getViewFrustum(); auto textPosition = getDisplayNamePosition(); if (frustum.pointIntersectsFrustum(textPosition)) { diff --git a/libraries/shared/src/shared/Camera.cpp b/libraries/shared/src/shared/Camera.cpp index b39b8b9169..6727f89d29 100644 --- a/libraries/shared/src/shared/Camera.cpp +++ b/libraries/shared/src/shared/Camera.cpp @@ -25,8 +25,14 @@ * * First Person * "first person" - * The camera is positioned such that you have the same view as your avatar. The camera moves and rotates with your - * avatar. + * Legacy first person camera mode. The camera is positioned such that you have the same view as your avatar. + * The camera moves and rotates with your avatar. + * + * + * First Person Look At + * "first person look at" + * Default first person camera mode. The camera is positioned such that you have the same view as your avatar. + * The camera moves and rotates with your avatar's head. * * * Third Person @@ -73,6 +79,8 @@ CameraMode stringToMode(const QString& mode) { return CAMERA_MODE_THIRD_PERSON; } else if (mode == "first person") { return CAMERA_MODE_FIRST_PERSON; + } else if (mode == "first person look at") { + return CAMERA_MODE_FIRST_PERSON_LOOK_AT; } else if (mode == "mirror") { return CAMERA_MODE_MIRROR; } else if (mode == "independent") { @@ -92,6 +100,8 @@ QString modeToString(CameraMode mode) { return "third person"; } else if (mode == CAMERA_MODE_FIRST_PERSON) { return "first person"; + } else if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) { + return "first person look at"; } else if (mode == CAMERA_MODE_MIRROR) { return "mirror"; } else if (mode == CAMERA_MODE_INDEPENDENT) { diff --git a/libraries/shared/src/shared/Camera.h b/libraries/shared/src/shared/Camera.h index eecad34838..48cd814d86 100644 --- a/libraries/shared/src/shared/Camera.h +++ b/libraries/shared/src/shared/Camera.h @@ -19,6 +19,7 @@ enum CameraMode { CAMERA_MODE_NULL = -1, CAMERA_MODE_THIRD_PERSON, + CAMERA_MODE_FIRST_PERSON_LOOK_AT, CAMERA_MODE_FIRST_PERSON, CAMERA_MODE_MIRROR, CAMERA_MODE_INDEPENDENT, diff --git a/scripts/simplifiedUI/ui/simplifiedUI.js b/scripts/simplifiedUI/ui/simplifiedUI.js index fc0dd9fddd..3025b938cb 100644 --- a/scripts/simplifiedUI/ui/simplifiedUI.js +++ b/scripts/simplifiedUI/ui/simplifiedUI.js @@ -663,7 +663,7 @@ function handleSecondLaunchWindowVisibleChanged(shouldBeVisible) { function onDisplayModeChanged(isHMDMode) { if (isHMDMode) { - Camera.setModeString("first person"); + Camera.setModeString("first person look at"); } if (isHMDMode) { diff --git a/scripts/system/firstPersonHMD.js b/scripts/system/firstPersonHMD.js index 5fdee1b7b5..5e81d53f6b 100644 --- a/scripts/system/firstPersonHMD.js +++ b/scripts/system/firstPersonHMD.js @@ -16,7 +16,7 @@ // Automatically enter first person mode when entering HMD mode HMD.displayModeChanged.connect(function(isHMDMode) { if (isHMDMode) { - Camera.setModeString("first person"); + Camera.setModeString("first person look at"); } }); diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 8ecc982dab..2d225fd2a6 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -272,7 +272,7 @@ currentProgress = 0.0; connectionToDomainFailed = false; previousCameraMode = Camera.mode; - Camera.mode = "first person"; + Camera.mode = "first person look at"; updateProgressBar(0.0); scaleInterstitialPage(MyAvatar.sensorToWorldScale); timer = Script.setTimeout(update, 2000); diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index 0ee5259ffa..a92fbf1065 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -52,8 +52,8 @@ function calcSpawnInfo(hand, landscape) { var LEFT_HAND = Controller.Standard.LeftHand; var sensorToWorldScale = MyAvatar.sensorToWorldScale; - var headPos = (HMD.active && Camera.mode === "first person") ? HMD.position : Camera.position; - var headRot = Quat.cancelOutRollAndPitch((HMD.active && Camera.mode === "first person") ? + var headPos = (HMD.active && (Camera.mode === "first person" || Camera.mode === "first person look at")) ? HMD.position : Camera.position; + var headRot = Quat.cancelOutRollAndPitch((HMD.active && (Camera.mode === "first person" || Camera.mode === "first person look at")) ? HMD.orientation : Camera.orientation); var right = Quat.getRight(headRot); diff --git a/scripts/system/miniTablet.js b/scripts/system/miniTablet.js index 91c8b1edcf..f5b5ecf0a1 100644 --- a/scripts/system/miniTablet.js +++ b/scripts/system/miniTablet.js @@ -53,7 +53,7 @@ function handJointName(hand) { var jointName; if (hand === LEFT_HAND) { - if (Camera.mode === "first person") { + if (Camera.mode === "first person" || Camera.mode === "first person look at") { jointName = "_CONTROLLER_LEFTHAND"; } else if (Camera.mode === "third person") { jointName = "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"; @@ -61,7 +61,7 @@ jointName = "LeftHand"; } } else { - if (Camera.mode === "first person") { + if (Camera.mode === "first person" || Camera.mode === "first person look at") { jointName = "_CONTROLLER_RIGHTHAND"; } else if (Camera.mode === "third person") { jointName = "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"; From 8aa1bddceea341ac1e00bfa12e61575361a1e842 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 17 Oct 2019 14:11:18 -0700 Subject: [PATCH 17/37] RenderSecondView shadow config follows that of RenderMainView --- interface/src/scripting/RenderScriptingInterface.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/interface/src/scripting/RenderScriptingInterface.cpp b/interface/src/scripting/RenderScriptingInterface.cpp index f23dc598a9..56e9a93377 100644 --- a/interface/src/scripting/RenderScriptingInterface.cpp +++ b/interface/src/scripting/RenderScriptingInterface.cpp @@ -82,11 +82,18 @@ void RenderScriptingInterface::forceShadowsEnabled(bool enabled) { _shadowsEnabled = (enabled); _shadowsEnabledSetting.set(enabled); - auto lightingModelConfig = qApp->getRenderEngine()->getConfiguration()->getConfig("RenderMainView.LightingModel"); + auto renderConfig = qApp->getRenderEngine()->getConfiguration(); + assert(renderConfig); + auto lightingModelConfig = renderConfig->getConfig("RenderMainView.LightingModel"); if (lightingModelConfig) { Menu::getInstance()->setIsOptionChecked(MenuOption::Shadows, enabled); lightingModelConfig->setShadow(enabled); } + auto secondaryLightingModelConfig = renderConfig->getConfig("RenderSecondView.LightingModel"); + if (secondaryLightingModelConfig) { + Menu::getInstance()->setIsOptionChecked(MenuOption::Shadows, enabled); + secondaryLightingModelConfig->setShadow(enabled); + } }); } From 33ea63c70862db215168823eb62b154fd90cb1df Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 17 Oct 2019 15:06:12 -0700 Subject: [PATCH 18/37] Fix warnings and update controls --- .../resources/controllers/keyboardMouse.json | 31 ++++++++++++++++++- interface/src/Application.cpp | 2 +- .../src/avatars-renderer/Avatar.cpp | 4 +-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index eb07c9a6dd..d6ecc540c2 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -78,6 +78,15 @@ "to": "Actions.Yaw" }, + { "from": { "makeAxis" : [ + ["Keyboard.Left"], + ["Keyboard.Right"] + ] + }, + "when": ["Application.CameraFirstPersonLookat", "!Keyboard.Shift"], + "to": "Actions.Yaw" + }, + { "from": { "makeAxis" : [ ["Keyboard.Left"], ["Keyboard.Right"] @@ -113,7 +122,16 @@ "when": ["Application.CameraFirstPerson", "!Keyboard.Control"], "to": "Actions.Yaw" }, - + + { "from": { "makeAxis" : [ + ["Keyboard.A"], + ["Keyboard.D"] + ] + }, + "when": ["Application.CameraFirstPersonLookat", "!Keyboard.Control"], + "to": "Actions.Yaw" + }, + { "from": { "makeAxis" : [ ["Keyboard.A"], ["Keyboard.D"] @@ -149,6 +167,15 @@ "when": "Application.CameraFirstPerson", "to": "Actions.Yaw" }, + + { "from": { "makeAxis" : [ + ["Keyboard.TouchpadLeft"], + ["Keyboard.TouchpadRight"] + ] + }, + "when": "Application.CameraFirstPersonLookat", + "to": "Actions.Yaw" + }, { "from": { "makeAxis" : [ ["Keyboard.TouchpadLeft"], @@ -222,10 +249,12 @@ { "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Right", "when": "Keyboard.Shift", "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.Up", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_FORWARD" }, + { "from": "Keyboard.Up", "when": "Application.CameraFirstPersonLookat", "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.Up", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.Up", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.Up", "when": "Application.CameraSelfie", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.Down", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_BACKWARD" }, + { "from": "Keyboard.Down", "when": "Application.CameraFirstPersonLookat", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.Down", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.Down", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.Down", "when": "Application.CameraSelfie", "to": "Actions.LONGITUDINAL_FORWARD" }, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d11c1ac5e0..994c9c7fd3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -717,7 +717,7 @@ private: static const QString STATE_IN_HMD = "InHMD"; static const QString STATE_CAMERA_FULL_SCREEN_MIRROR = "CameraFSM"; -static const QString STATE_CAMERA_FIRST_PERSON = "CameraFirstPersonLegacy"; +static const QString STATE_CAMERA_FIRST_PERSON = "CameraFirstPerson"; static const QString STATE_CAMERA_FIRST_PERSON_LOOK_AT = "CameraFirstPersonLookat"; static const QString STATE_CAMERA_THIRD_PERSON = "CameraThirdPerson"; static const QString STATE_CAMERA_ENTITY = "CameraEntity"; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index d6db75180d..bea9f979b8 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -854,8 +854,8 @@ void Avatar::render(RenderArgs* renderArgs) { float distanceToTarget = glm::length(toTarget); const float DISPLAYNAME_DISTANCE = 20.0f; updateDisplayNameAlpha(distanceToTarget < DISPLAYNAME_DISTANCE); - if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON_LOOK_AT - || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) { + if (!isMyAvatar() || !(renderArgs->_cameraMode == (int8_t)CAMERA_MODE_FIRST_PERSON_LOOK_AT + || renderArgs->_cameraMode == (int8_t)CAMERA_MODE_FIRST_PERSON)) { auto& frustum = renderArgs->getViewFrustum(); auto textPosition = getDisplayNamePosition(); if (frustum.pointIntersectsFrustum(textPosition)) { From 6101f54d4bc1040c0a3eeda572cb5bc027c7a97a Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Fri, 18 Oct 2019 06:11:00 -0700 Subject: [PATCH 19/37] Rebase WASAPI audio plugin on Qt 5.12.3 --- 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 9e22e28f58..18d93bde40 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_wasapi11.zip - URL_MD5 d0eb8489455e7f79d59155535a2c8861 + URL https://public.highfidelity.com/dependencies/qtaudio_wasapi12.zip + URL_MD5 9e2eef41165f85344808f754b48bf08d CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From d65538a11b2a4050bbd98cab5309834c762924c3 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 18 Oct 2019 12:41:19 -0700 Subject: [PATCH 20/37] DEV-2471: Fix an issue with InteractiveWindow anchors that caused windows without anchors to move when the Interface window geometry changes --- interface/src/scripting/DesktopScriptingInterface.cpp | 2 ++ interface/src/ui/InteractiveWindow.cpp | 7 +++++-- interface/src/ui/InteractiveWindow.h | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/interface/src/scripting/DesktopScriptingInterface.cpp b/interface/src/scripting/DesktopScriptingInterface.cpp index 32b5eb768d..ae4af48cd6 100644 --- a/interface/src/scripting/DesktopScriptingInterface.cpp +++ b/interface/src/scripting/DesktopScriptingInterface.cpp @@ -55,12 +55,14 @@ static const QVariantMap DOCK_AREA { /**jsdoc * The possible "relative position anchors" of an InteractiveWindow. Used when defining the `relativePosition` property of an `InteractiveWindow`. * @typedef {object} InteractiveWindow.RelativePositionAnchors + * @property {InteractiveWindow.RelativePositionAnchor} NO_ANCHOR - Specifies that the position of the `InteractiveWindow` will not be relative to any part of the Interface window. * @property {InteractiveWindow.RelativePositionAnchor} TOP_LEFT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the top left of the Interface window. * @property {InteractiveWindow.RelativePositionAnchor} TOP_RIGHT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the top right of the Interface window. * @property {InteractiveWindow.RelativePositionAnchor} BOTTOM_RIGHT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the bottom right of the Interface window. * @property {InteractiveWindow.RelativePositionAnchor} BOTTOM_LEFT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the bottom left of the Interface window. */ static const QVariantMap RELATIVE_POSITION_ANCHOR { + { "NO_ANCHOR", RelativePositionAnchor::NO_ANCHOR }, { "TOP_LEFT", RelativePositionAnchor::TOP_LEFT }, { "TOP_RIGHT", RelativePositionAnchor::TOP_RIGHT }, { "BOTTOM_RIGHT", RelativePositionAnchor::BOTTOM_RIGHT }, diff --git a/interface/src/ui/InteractiveWindow.cpp b/interface/src/ui/InteractiveWindow.cpp index b7140b4009..8391923cbb 100644 --- a/interface/src/ui/InteractiveWindow.cpp +++ b/interface/src/ui/InteractiveWindow.cpp @@ -116,9 +116,10 @@ void InteractiveWindow::forwardKeyReleaseEvent(int key, int modifiers) { } void InteractiveWindow::onMainWindowGeometryChanged(QRect geometry) { + // This handler is only connected `if (_isFullScreenWindow || _relativePositionAnchor != RelativePositionAnchor::NONE)`. if (_isFullScreenWindow) { repositionAndResizeFullScreenWindow(); - } else { + } else if (_relativePositionAnchor != RelativePositionAnchor::NO_ANCHOR) { setPositionUsingRelativePositionAndAnchor(geometry); } } @@ -326,7 +327,9 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap connect(object, SIGNAL(presentationModeChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection); #endif - connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &InteractiveWindow::onMainWindowGeometryChanged, Qt::QueuedConnection); + if (_isFullScreenWindow || _relativePositionAnchor != RelativePositionAnchor::NO_ANCHOR) { + connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &InteractiveWindow::onMainWindowGeometryChanged, Qt::QueuedConnection); + } QUrl sourceURL{ sourceUrl }; // If the passed URL doesn't correspond to a known scheme, assume it's a local file path diff --git a/interface/src/ui/InteractiveWindow.h b/interface/src/ui/InteractiveWindow.h index d25c3d7ec2..fb10aac444 100644 --- a/interface/src/ui/InteractiveWindow.h +++ b/interface/src/ui/InteractiveWindow.h @@ -91,6 +91,7 @@ namespace InteractiveWindowEnums { Q_ENUM_NS(DockArea); enum RelativePositionAnchor { + NO_ANCHOR, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT, @@ -147,7 +148,7 @@ private: Q_INVOKABLE glm::vec2 getPosition() const; Q_INVOKABLE void setPosition(const glm::vec2& position); - RelativePositionAnchor _relativePositionAnchor{ RelativePositionAnchor::TOP_LEFT }; + RelativePositionAnchor _relativePositionAnchor{ RelativePositionAnchor::NO_ANCHOR }; Q_INVOKABLE RelativePositionAnchor getRelativePositionAnchor() const; Q_INVOKABLE void setRelativePositionAnchor(const RelativePositionAnchor& position); From 4c48d80da7343be6542cd5375598c632115244f1 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 18 Oct 2019 13:34:42 -0700 Subject: [PATCH 21/37] Fix warning on MacOS and Ubuntu --- interface/src/ui/InteractiveWindow.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/ui/InteractiveWindow.cpp b/interface/src/ui/InteractiveWindow.cpp index 8391923cbb..6cc26e2409 100644 --- a/interface/src/ui/InteractiveWindow.cpp +++ b/interface/src/ui/InteractiveWindow.cpp @@ -497,6 +497,9 @@ void InteractiveWindow::setPositionUsingRelativePositionAndAnchor(const QRect& m newPosition.x = mainWindowGeometry.x() + relativePosition.x; newPosition.y = mainWindowGeometry.y() + mainWindowGeometry.height() - relativePosition.y; break; + case RelativePositionAnchor::NO_ANCHOR: + // No-op. + break; } // Make sure we include the dimensions of the docked widget! From b914bb60fef645c8b4bc91c81969600cbc08e15c Mon Sep 17 00:00:00 2001 From: dooglifeSF <41022919+dooglifeSF@users.noreply.github.com> Date: Mon, 21 Oct 2019 14:15:31 -0700 Subject: [PATCH 22/37] Change strafeleft<->straferight transitions to isMoving vars and remove the sidesteps from the blendranges --- .../resources/avatar/avatar-animation.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index b1e3b0e978..731be4e07a 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -4740,11 +4740,11 @@ "children": [ ], "data": { - "endFrame": 30, + "endFrame": 35, "loopFlag": true, "startFrame": 1, "timeScale": 1, - "url": "qrc:///avatar/animations/side_step_short_left.fbx" + "url": "qrc:///avatar/animations/walk_left.fbx" }, "id": "strafeLeftShortStep_c", "type": "clip" @@ -4753,11 +4753,11 @@ "children": [ ], "data": { - "endFrame": 20, + "endFrame": 35, "loopFlag": true, "startFrame": 1, "timeScale": 1, - "url": "qrc:///avatar/animations/side_step_left.fbx" + "url": "qrc:///avatar/animations/walk_left.fbx" }, "id": "strafeLeftStep_c", "type": "clip" @@ -4838,12 +4838,12 @@ "children": [ ], "data": { - "endFrame": 30, + "endFrame": 35, "loopFlag": true, - "mirrorFlag": true, + "mirrorFlag": false, "startFrame": 1, "timeScale": 1, - "url": "qrc:///avatar/animations/side_step_short_left.fbx" + "url": "qrc:///avatar/animations/walk_right.fbx" }, "id": "strafeRightShortStep_c", "type": "clip" @@ -4852,12 +4852,12 @@ "children": [ ], "data": { - "endFrame": 20, + "endFrame": 35, "loopFlag": true, - "mirrorFlag": true, + "mirrorFlag": false, "startFrame": 1, "timeScale": 1, - "url": "qrc:///avatar/animations/side_step_left.fbx" + "url": "qrc:///avatar/animations/walk_right.fbx" }, "id": "strafeRightStep_c", "type": "clip" @@ -5617,7 +5617,7 @@ }, { "state": "STRAFELEFT", - "var": "isInputLeft" + "var": "isMovingLeft" }, { "state": "turnRight", @@ -5681,7 +5681,7 @@ }, { "state": "STRAFERIGHT", - "var": "isInputRight" + "var": "isMovingRight" }, { "state": "turnRight", From a4fcb2c39e1fcc93df6c0d3883929580704b1a10 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 21 Oct 2019 14:31:15 -0700 Subject: [PATCH 23/37] 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 24/37] 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 25/37] 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 5bf2365a5e384dde44754eadd687370880b795a4 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 21 Oct 2019 17:29:44 -0700 Subject: [PATCH 26/37] 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 f6aa4a2dd4af4842f0206b097449149deb423906 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 22 Oct 2019 11:42:19 -0700 Subject: [PATCH 27/37] 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 b8a607dcf030467b745a3ef6b1e8b8e611560ab8 Mon Sep 17 00:00:00 2001 From: dooglifeSF <41022919+dooglifeSF@users.noreply.github.com> Date: Tue, 22 Oct 2019 11:53:59 -0700 Subject: [PATCH 28/37] remove unused slow speed sidesteps --- .../resources/avatar/avatar-animation.json | 58 ------------------- 1 file changed, 58 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 731be4e07a..670c520b65 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -4736,32 +4736,6 @@ }, { "children": [ - { - "children": [ - ], - "data": { - "endFrame": 35, - "loopFlag": true, - "startFrame": 1, - "timeScale": 1, - "url": "qrc:///avatar/animations/walk_left.fbx" - }, - "id": "strafeLeftShortStep_c", - "type": "clip" - }, - { - "children": [ - ], - "data": { - "endFrame": 35, - "loopFlag": true, - "startFrame": 1, - "timeScale": 1, - "url": "qrc:///avatar/animations/walk_left.fbx" - }, - "id": "strafeLeftStep_c", - "type": "clip" - }, { "children": [ ], @@ -4819,8 +4793,6 @@ "alpha": 0, "alphaVar": "moveLateralAlpha", "characteristicSpeeds": [ - 0.1, - 0.5, 1, 2.55, 3.35, @@ -4834,34 +4806,6 @@ }, { "children": [ - { - "children": [ - ], - "data": { - "endFrame": 35, - "loopFlag": true, - "mirrorFlag": false, - "startFrame": 1, - "timeScale": 1, - "url": "qrc:///avatar/animations/walk_right.fbx" - }, - "id": "strafeRightShortStep_c", - "type": "clip" - }, - { - "children": [ - ], - "data": { - "endFrame": 35, - "loopFlag": true, - "mirrorFlag": false, - "startFrame": 1, - "timeScale": 1, - "url": "qrc:///avatar/animations/walk_right.fbx" - }, - "id": "strafeRightStep_c", - "type": "clip" - }, { "children": [ ], @@ -4923,8 +4867,6 @@ "alpha": 0, "alphaVar": "moveLateralAlpha", "characteristicSpeeds": [ - 0.1, - 0.5, 1, 2.55, 3.4, From e1fa10b4de1473b0c93d4ab198f2e911bc833117 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Tue, 22 Oct 2019 14:14:41 -0700 Subject: [PATCH 29/37] 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 f325cef4d6933b540756489afc52699f74bc8c38 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 22 Oct 2019 15:45:49 -0700 Subject: [PATCH 30/37] Implement DEV-257: Allow scripts running on the ESS to access avatar info via the AvatarHashMap --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 2 +- assignment-client/src/scripts/EntityScriptServer.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 32c944f5b8..522f0bf163 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -265,7 +265,7 @@ static const int AVATAR_MIXER_BROADCAST_FRAMES_PER_SECOND = 45; void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { quint64 start = usecTimestampNow(); - if (node->getType() == NodeType::Agent && node->getLinkedData() && node->getActiveSocket() && !node->isUpstream()) { + if ((node->getType() == NodeType::Agent || node->getType() == NodeType::EntityScriptServer) && node->getLinkedData() && node->getActiveSocket() && !node->isUpstream()) { broadcastAvatarDataToAgent(node); } else if (node->getType() == NodeType::DownstreamAvatarMixer) { broadcastAvatarDataToDownstreamMixer(node); diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 174cf73094..7c3d491470 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -86,8 +86,6 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig this, "handleOctreePacket"); packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); - auto avatarHashMap = DependencyManager::set(); - packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket"); packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket"); packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket"); @@ -255,6 +253,7 @@ void EntityScriptServer::handleEntityScriptCallMethodPacket(QSharedPointer(ScriptEngine::ENTITY_SERVER_SCRIPT); DependencyManager::set(); + DependencyManager::set(); // make sure we request our script once the agent connects to the domain auto nodeList = DependencyManager::get(); @@ -448,6 +447,7 @@ void EntityScriptServer::resetEntitiesScriptEngine() { newEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue); newEngine->registerGlobalObject("SoundCache", DependencyManager::get().data()); + newEngine->registerGlobalObject("AvatarList", DependencyManager::get().data()); // connect this script engines printedMessage signal to the global ScriptEngines these various messages auto scriptEngines = DependencyManager::get().data(); From b987c6b58a274fc97133dab6b43c22b00f1e2bcc Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 22 Oct 2019 16:25:16 -0700 Subject: [PATCH 31/37] remove unecessary comments --- libraries/fbx/src/FBXSerializer.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 6b30c59595..f8339ddd31 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -177,10 +177,6 @@ glm::mat4 getGlobalTransform(const QMultiMap& _connectionParen break; } } - if (fbxModel.hasGeometricOffset && visitedNodes.size() > 1) { - qCWarning(modelformat) << "Here is a parent node with Geometric offset ?????" << url; - } - } return globalTransform; } From df782edcd9aafb8a988bcc68774c639f5ab17739 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 23 Oct 2019 11:14:22 -0700 Subject: [PATCH 32/37] 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 33/37] 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 34/37] 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 bb0849d3a0295735159ff2b1cb9b0fdd7712bda1 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 23 Oct 2019 14:23:29 -0700 Subject: [PATCH 35/37] 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 36/37] 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 37/37] 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() {