Date: Fri, 18 Oct 2019 09:17:03 +1300
Subject: [PATCH 10/33] JSDoc fixes noticed in passing
---
interface/src/avatar/MyAvatar.h | 2 +-
interface/src/raypick/LaserPointerScriptingInterface.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 0f139ddbff..c93645331f 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -275,7 +275,7 @@ class MyAvatar : public Avatar {
* @property {number} analogPlusSprintSpeed - The sprint (run) speed of your avatar for the "AnalogPlus" control scheme.
* @property {MyAvatar.SitStandModelType} userRecenterModel - Controls avatar leaning and recentering behavior.
* @property {number} isInSittingState - true
if the user wearing the HMD is determined to be sitting
- * (avatar leaning is disabled, recenntering is enabled), false
if the user wearing the HMD is
+ * (avatar leaning is disabled, recentering is enabled), false
if the user wearing the HMD is
* determined to be standing (avatar leaning is enabled, and avatar recenters if it leans too far).
* If userRecenterModel == 2
(i.e., auto) the property value automatically updates as the user sits
* or stands, unless isSitStandStateLocked == true
. Setting the property value overrides the current
diff --git a/interface/src/raypick/LaserPointerScriptingInterface.h b/interface/src/raypick/LaserPointerScriptingInterface.h
index 6c5ce0dbaf..5745e29e69 100644
--- a/interface/src/raypick/LaserPointerScriptingInterface.h
+++ b/interface/src/raypick/LaserPointerScriptingInterface.h
@@ -25,10 +25,10 @@ class LaserPointerScriptingInterface : public QObject, public Dependency {
* represent objects for repeatedly calculating ray intersections with avatars, entities, and overlays. Ray pointers can also
* be configured to generate events on entities and overlays intersected.
*
- * Deprecated: This API is deprecated. Use {@link Pointers} instead.
- *
* @namespace LaserPointers
*
+ * @deprecated This API is deprecated and will be removed. Use {@link Pointers} instead.
+ *
* @hifi-interface
* @hifi-client-entity
* @hifi-avatar
From 92f1b59cc8e555e0594cad64eb5151a3378f888e Mon Sep 17 00:00:00 2001
From: "Anthony J. Thibault"
Date: Fri, 18 Oct 2019 16:30:32 -0700
Subject: [PATCH 11/33] Full legacy API and FST support
---
.../src/avatars/ScriptableAvatar.cpp | 12 -----
.../src/avatars/ScriptableAvatar.h | 7 ---
libraries/avatars/src/HeadData.cpp | 3 ++
libraries/avatars/src/HeadData.h | 6 +--
.../controllers/src/controllers/Actions.cpp | 2 +-
.../controllers/src/controllers/Actions.h | 2 +-
.../src/controllers/StandardController.cpp | 2 +-
.../src/controllers/StandardControls.h | 2 +-
libraries/fbx/src/FSTReader.cpp | 50 +++++++++++++++++--
libraries/render-utils/src/Model.cpp | 2 +
libraries/shared/src/BlendshapeConstants.h | 6 +--
11 files changed, 60 insertions(+), 34 deletions(-)
diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp
index 044ab86942..54eb499be1 100644
--- a/assignment-client/src/avatars/ScriptableAvatar.cpp
+++ b/assignment-client/src/avatars/ScriptableAvatar.cpp
@@ -279,18 +279,6 @@ void ScriptableAvatar::setJointMappingsFromNetworkReply() {
networkReply->deleteLater();
}
-void ScriptableAvatar::setHasProceduralBlinkFaceMovement(bool hasProceduralBlinkFaceMovement) {
- _headData->setHasProceduralBlinkFaceMovement(hasProceduralBlinkFaceMovement);
-}
-
-void ScriptableAvatar::setHasProceduralEyeFaceMovement(bool hasProceduralEyeFaceMovement) {
- _headData->setHasProceduralEyeFaceMovement(hasProceduralEyeFaceMovement);
-}
-
-void ScriptableAvatar::setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement) {
- _headData->setHasAudioEnabledFaceMovement(hasAudioEnabledFaceMovement);
-}
-
AvatarEntityMap ScriptableAvatar::getAvatarEntityData() const {
// DANGER: Now that we store the AvatarEntityData in packed format this call is potentially Very Expensive!
// Avoid calling this method if possible.
diff --git a/assignment-client/src/avatars/ScriptableAvatar.h b/assignment-client/src/avatars/ScriptableAvatar.h
index fc796b418f..f2f5a1e6f4 100644
--- a/assignment-client/src/avatars/ScriptableAvatar.h
+++ b/assignment-client/src/avatars/ScriptableAvatar.h
@@ -153,13 +153,6 @@ public:
virtual QByteArray toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking = false) override;
- void setHasProceduralBlinkFaceMovement(bool hasProceduralBlinkFaceMovement);
- bool getHasProceduralBlinkFaceMovement() const override { return _headData->getHasProceduralBlinkFaceMovement(); }
- void setHasProceduralEyeFaceMovement(bool hasProceduralEyeFaceMovement);
- bool getHasProceduralEyeFaceMovement() const override { return _headData->getHasProceduralEyeFaceMovement(); }
- void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement);
- bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); }
-
/**jsdoc
* Gets details of all avatar entities.
* Warning: Potentially an expensive call. Do not use if possible.
diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp
index f37b88c135..ff73677bb8 100644
--- a/libraries/avatars/src/HeadData.cpp
+++ b/libraries/avatars/src/HeadData.cpp
@@ -27,6 +27,9 @@ HeadData::HeadData(AvatarData* owningAvatar) :
_basePitch(0.0f),
_baseRoll(0.0f),
_lookAtPosition(0.0f, 0.0f, 0.0f),
+ _blendshapeCoefficients((int)Blendshapes::BlendshapeCount, 0.0f),
+ _transientBlendshapeCoefficients((int)Blendshapes::BlendshapeCount, 0.0f),
+ _summedBlendshapeCoefficients((int)Blendshapes::BlendshapeCount, 0.0f),
_owningAvatar(owningAvatar)
{
_userProceduralAnimationFlags.assign((size_t)ProceduralAnimaitonTypeCount, true);
diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h
index 9652792512..218ffceaa1 100644
--- a/libraries/avatars/src/HeadData.h
+++ b/libraries/avatars/src/HeadData.h
@@ -121,9 +121,9 @@ protected:
float _averageLoudness { 0.0f };
float _browAudioLift { 0.0f };
- QVector _blendshapeCoefficients { (int)Blendshapes::BlendshapeCount, 0.0f };
- QVector _transientBlendshapeCoefficients { (int)Blendshapes::BlendshapeCount, 0.0f };
- QVector _summedBlendshapeCoefficients { (int)Blendshapes::BlendshapeCount, 0.0f };
+ QVector _blendshapeCoefficients;
+ QVector _transientBlendshapeCoefficients;
+ QVector _summedBlendshapeCoefficients;
QMap _blendshapeLookupMap;
AvatarData* _owningAvatar;
diff --git a/libraries/controllers/src/controllers/Actions.cpp b/libraries/controllers/src/controllers/Actions.cpp
index 198c342b1d..6dd9a47395 100644
--- a/libraries/controllers/src/controllers/Actions.cpp
+++ b/libraries/controllers/src/controllers/Actions.cpp
@@ -350,7 +350,7 @@ namespace controller {
makePosePair(Action::LEFT_EYE, "LeftEye"),
makePosePair(Action::RIGHT_EYE, "RightEye"),
- // AJT: blendshapes
+ // blendshapes
makeAxisPair(Action::EYEBLINK_L, "EyeBlink_L"),
makeAxisPair(Action::EYEBLINK_R, "EyeBlink_R"),
makeAxisPair(Action::EYESQUINT_L, "EyeSquint_L"),
diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h
index 1a5c73a1d8..86821b4633 100644
--- a/libraries/controllers/src/controllers/Actions.h
+++ b/libraries/controllers/src/controllers/Actions.h
@@ -184,7 +184,7 @@ enum class Action {
LEFT_EYE,
RIGHT_EYE,
- // AJT: blendshapes
+ // blendshapes
EYEBLINK_L,
EYEBLINK_R,
EYESQUINT_L,
diff --git a/libraries/controllers/src/controllers/StandardController.cpp b/libraries/controllers/src/controllers/StandardController.cpp
index 14697b26d2..168604ee45 100644
--- a/libraries/controllers/src/controllers/StandardController.cpp
+++ b/libraries/controllers/src/controllers/StandardController.cpp
@@ -356,7 +356,7 @@ Input::NamedVector StandardController::getAvailableInputs() const {
makePair(LEFT_EYE, "LeftEye"),
makePair(RIGHT_EYE, "RightEye"),
- // AJT: blendshapes
+ // blendshapes
makePair(EYEBLINK_L, "EyeBlink_L"),
makePair(EYEBLINK_R, "EyeBlink_R"),
makePair(EYESQUINT_L, "EyeSquint_L"),
diff --git a/libraries/controllers/src/controllers/StandardControls.h b/libraries/controllers/src/controllers/StandardControls.h
index 55bcf0e36a..f99072af7c 100644
--- a/libraries/controllers/src/controllers/StandardControls.h
+++ b/libraries/controllers/src/controllers/StandardControls.h
@@ -91,7 +91,7 @@ namespace controller {
LEFT_GRIP,
RIGHT_GRIP,
- // AJT: blendshapes
+ // blendshapes
EYEBLINK_L,
EYEBLINK_R,
EYESQUINT_L,
diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp
index 41b660f722..2835151bfe 100644
--- a/libraries/fbx/src/FSTReader.cpp
+++ b/libraries/fbx/src/FSTReader.cpp
@@ -21,7 +21,7 @@
QVariantHash FSTReader::parseMapping(QIODevice* device) {
QVariantHash properties;
-
+
QByteArray line;
while (!(line = device->readLine()).isEmpty()) {
if ((line = line.trimmed()).startsWith('#')) {
@@ -34,12 +34,10 @@ QVariantHash FSTReader::parseMapping(QIODevice* device) {
QByteArray name = sections.at(0).trimmed();
if (sections.size() == 2) {
properties.insertMulti(name, sections.at(1).trimmed());
-
} else if (sections.size() == 3) {
QVariantHash heading = properties.value(name).toHash();
heading.insertMulti(sections.at(1).trimmed(), sections.at(2).trimmed());
properties.insert(name, heading);
-
} else if (sections.size() >= 4) {
QVariantHash heading = properties.value(name).toHash();
QVariantList contents;
@@ -50,14 +48,56 @@ QVariantHash FSTReader::parseMapping(QIODevice* device) {
properties.insert(name, heading);
}
}
-
+
return properties;
}
+static void removeBlendshape(QVariantHash& bs, const QString& key) {
+ if (bs.contains(key)) {
+ bs.remove(key);
+ }
+}
+
+static void splitBlendshapes(QVariantHash& bs, const QString& key, const QString& leftKey, const QString& rightKey) {
+ if (bs.contains(key) && !(bs.contains(leftKey) || bs.contains(rightKey))) {
+ // key has been split into leftKey and rightKey blendshapes
+ QVariantList origShapes = bs.values(key);
+ QVariantList halfShapes;
+ for (int i = 0; i < origShapes.size(); i++) {
+ QVariantList origShape = origShapes[i].toList();
+ QVariantList halfShape;
+ halfShape.append(origShape[0]);
+ halfShape.append(QVariant(0.5f * origShape[1].toFloat()));
+ bs.insertMulti(leftKey, halfShape);
+ bs.insertMulti(rightKey, halfShape);
+ }
+ }
+}
+
+// convert legacy blendshapes to arkit blendshapes
+static void fixUpLegacyBlendshapes(QVariantHash& properties) {
+ QVariantHash bs = properties.value("bs").toHash();
+
+ // These blendshapes have no ARKit equivalent, so we remove them.
+ removeBlendshape(bs, "JawChew");
+ removeBlendshape(bs, "ChinLowerRaise");
+ removeBlendshape(bs, "ChinUpperRaise");
+
+ // These blendshapes are split in ARKit, we replace them with their left and right sides with a weight of 1/2.
+ splitBlendshapes(bs, "LipsUpperUp", "MouthUpperUp_L", "MouthUpperUp_R");
+ splitBlendshapes(bs, "LipsLowerDown", "MouthLowerDown_L", "MouthLowerDown_R");
+ splitBlendshapes(bs, "Sneer", "NoseSneer_L", "NoseSneer_R");
+
+ // re-insert new mutated bs hash into mapping properties.
+ properties.insert("bs", bs);
+}
+
QVariantHash FSTReader::readMapping(const QByteArray& data) {
QBuffer buffer(const_cast(&data));
buffer.open(QIODevice::ReadOnly);
- return FSTReader::parseMapping(&buffer);
+ QVariantHash mapping = FSTReader::parseMapping(&buffer);
+ fixUpLegacyBlendshapes(mapping);
+ return mapping;
}
void FSTReader::writeVariant(QBuffer& buffer, QVariantHash::const_iterator& it) {
diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp
index 74cf1ffa39..a7e098e1b7 100644
--- a/libraries/render-utils/src/Model.cpp
+++ b/libraries/render-utils/src/Model.cpp
@@ -39,6 +39,8 @@
#include "RenderUtilsLogging.h"
#include
+#include
+
using namespace std;
int nakedModelPointerTypeId = qRegisterMetaType();
diff --git a/libraries/shared/src/BlendshapeConstants.h b/libraries/shared/src/BlendshapeConstants.h
index 63e99f465f..0f934b2056 100644
--- a/libraries/shared/src/BlendshapeConstants.h
+++ b/libraries/shared/src/BlendshapeConstants.h
@@ -109,10 +109,10 @@ enum class LegacyBlendshpaes : int {
// Legacy shapes
// * JawChew (not in ARKit)
-// * MouthUpperUp (split in ARKit)
-// * MouthLowerDown (split in ARKit)
+// * LipsUpperUp (split in ARKit)
+// * LipsLowerDown (split in ARKit)
// * Sneer (split in ARKit)
// * ChinLowerRaise (not in ARKit)
-// * ChinUpperRase (not in ARKit)
+// * ChinUpperRaise (not in ARKit)
#endif // hifi_BlendshapeConstants_h
From 03f88f696d1c1d8d31ec5649157b9f887f944850 Mon Sep 17 00:00:00 2001
From: "Anthony J. Thibault"
Date: Mon, 21 Oct 2019 19:37:57 -0700
Subject: [PATCH 12/33] Renamed LipsTogether to MouthClose and bug fixes.
---
interface/resources/controllers/standard.json | 2 +-
interface/resources/controllers/standard_nomovement.json | 2 +-
interface/src/avatar/MyHead.cpp | 2 +-
libraries/avatars/src/AvatarData.cpp | 4 ++++
libraries/avatars/src/HeadData.cpp | 4 ++++
libraries/avatars/src/HeadData.h | 1 +
libraries/controllers/src/controllers/Actions.cpp | 2 +-
libraries/controllers/src/controllers/Actions.h | 2 +-
libraries/controllers/src/controllers/StandardController.cpp | 2 +-
libraries/controllers/src/controllers/StandardControls.h | 2 +-
libraries/shared/src/BlendshapeConstants.cpp | 2 +-
libraries/shared/src/BlendshapeConstants.h | 4 ++--
12 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/interface/resources/controllers/standard.json b/interface/resources/controllers/standard.json
index 8c84039b86..b6cb4e3e27 100644
--- a/interface/resources/controllers/standard.json
+++ b/interface/resources/controllers/standard.json
@@ -208,7 +208,7 @@
{ "from": "Standard.Puff", "to": "Actions.Puff" },
{ "from": "Standard.CheekSquint_L", "to": "Actions.CheekSquint_L" },
{ "from": "Standard.CheekSquint_R", "to": "Actions.CheekSquint_R" },
- { "from": "Standard.LipsTogether", "to": "Actions.LipsTogether" },
+ { "from": "Standard.MouthClose", "to": "Actions.MouthClose" },
{ "from": "Standard.MouthUpperUp_L", "to": "Actions.MouthUpperUp_L" },
{ "from": "Standard.MouthUpperUp_R", "to": "Actions.MouthUpperUp_R" },
{ "from": "Standard.MouthLowerDown_L", "to": "Actions.MouthLowerDown_L" },
diff --git a/interface/resources/controllers/standard_nomovement.json b/interface/resources/controllers/standard_nomovement.json
index e311a5fa62..04c0d2f329 100644
--- a/interface/resources/controllers/standard_nomovement.json
+++ b/interface/resources/controllers/standard_nomovement.json
@@ -103,7 +103,7 @@
{ "from": "Standard.Puff", "to": "Actions.Puff" },
{ "from": "Standard.CheekSquint_L", "to": "Actions.CheekSquint_L" },
{ "from": "Standard.CheekSquint_R", "to": "Actions.CheekSquint_R" },
- { "from": "Standard.LipsTogether", "to": "Actions.LipsTogether" },
+ { "from": "Standard.MouthClose", "to": "Actions.MouthClose" },
{ "from": "Standard.MouthUpperUp_L", "to": "Actions.MouthUpperUp_L" },
{ "from": "Standard.MouthUpperUp_R", "to": "Actions.MouthUpperUp_R" },
{ "from": "Standard.MouthLowerDown_L", "to": "Actions.MouthLowerDown_L" },
diff --git a/interface/src/avatar/MyHead.cpp b/interface/src/avatar/MyHead.cpp
index f92f8b7218..a0e70a3049 100644
--- a/interface/src/avatar/MyHead.cpp
+++ b/interface/src/avatar/MyHead.cpp
@@ -64,7 +64,7 @@ static controller::Action blendshapeActions[] = {
controller::Action::PUFF,
controller::Action::CHEEKSQUINT_L,
controller::Action::CHEEKSQUINT_R,
- controller::Action::LIPSTOGETHER,
+ controller::Action::MOUTHCLOSE,
controller::Action::MOUTHUPPERUP_L,
controller::Action::MOUTHUPPERUP_R,
controller::Action::MOUTHLOWERDOWN_L,
diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp
index c5dcfba1c0..87d6c57d59 100755
--- a/libraries/avatars/src/AvatarData.cpp
+++ b/libraries/avatars/src/AvatarData.cpp
@@ -1217,6 +1217,10 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
_keyState = newKeyState;
_handState = newHandState;
+ if (!newHasScriptedBlendshapes && getHasScriptedBlendshapes()) {
+ // if scripted blendshapes have just been turned off, slam blendshapes back to zero.
+ _headData->clearBlendshapeCoefficients();
+ }
_headData->setHasScriptedBlendshapes(newHasScriptedBlendshapes);
_headData->setProceduralAnimationFlag(HeadData::SaccadeProceduralEyeJointAnimation, newHasProceduralEyeMovement);
_headData->setProceduralAnimationFlag(HeadData::AudioProceduralBlendshapeAnimation, newHasAudioEnabledFaceMovement);
diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp
index ff73677bb8..93fb0190bb 100644
--- a/libraries/avatars/src/HeadData.cpp
+++ b/libraries/avatars/src/HeadData.cpp
@@ -83,6 +83,10 @@ int HeadData::getNumSummedBlendshapeCoefficients() const {
return maxSize;
}
+void HeadData::clearBlendshapeCoefficients() {
+ _blendshapeCoefficients.fill(0.0f, (int)_blendshapeCoefficients.size());
+}
+
const QVector& HeadData::getSummedBlendshapeCoefficients() {
int maxSize = std::max(_blendshapeCoefficients.size(), _transientBlendshapeCoefficients.size());
if (_summedBlendshapeCoefficients.size() != maxSize) {
diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h
index 218ffceaa1..083374b32d 100644
--- a/libraries/avatars/src/HeadData.h
+++ b/libraries/avatars/src/HeadData.h
@@ -62,6 +62,7 @@ public:
const QVector& getSummedBlendshapeCoefficients();
int getNumSummedBlendshapeCoefficients() const;
void setBlendshapeCoefficients(const QVector& blendshapeCoefficients) { _blendshapeCoefficients = blendshapeCoefficients; }
+ void clearBlendshapeCoefficients();
const glm::vec3& getLookAtPosition() const { return _lookAtPosition; }
void setLookAtPosition(const glm::vec3& lookAtPosition) {
diff --git a/libraries/controllers/src/controllers/Actions.cpp b/libraries/controllers/src/controllers/Actions.cpp
index 6dd9a47395..36f454b5d0 100644
--- a/libraries/controllers/src/controllers/Actions.cpp
+++ b/libraries/controllers/src/controllers/Actions.cpp
@@ -393,7 +393,7 @@ namespace controller {
makeAxisPair(Action::PUFF, "Puff"),
makeAxisPair(Action::CHEEKSQUINT_L, "CheekSquint_L"),
makeAxisPair(Action::CHEEKSQUINT_R, "CheekSquint_R"),
- makeAxisPair(Action::LIPSTOGETHER, "LipsTogether"),
+ makeAxisPair(Action::MOUTHCLOSE, "MouthClose"),
makeAxisPair(Action::MOUTHUPPERUP_L, "MouthUpperUp_L"),
makeAxisPair(Action::MOUTHUPPERUP_R, "MouthUpperUp_R"),
makeAxisPair(Action::MOUTHLOWERDOWN_L, "MouthLowerDown_L"),
diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h
index 86821b4633..5c96923dc3 100644
--- a/libraries/controllers/src/controllers/Actions.h
+++ b/libraries/controllers/src/controllers/Actions.h
@@ -227,7 +227,7 @@ enum class Action {
PUFF,
CHEEKSQUINT_L,
CHEEKSQUINT_R,
- LIPSTOGETHER,
+ MOUTHCLOSE,
MOUTHUPPERUP_L,
MOUTHUPPERUP_R,
MOUTHLOWERDOWN_L,
diff --git a/libraries/controllers/src/controllers/StandardController.cpp b/libraries/controllers/src/controllers/StandardController.cpp
index 168604ee45..936f1c391f 100644
--- a/libraries/controllers/src/controllers/StandardController.cpp
+++ b/libraries/controllers/src/controllers/StandardController.cpp
@@ -399,7 +399,7 @@ Input::NamedVector StandardController::getAvailableInputs() const {
makePair(PUFF, "Puff"),
makePair(CHEEKSQUINT_L, "CheekSquint_L"),
makePair(CHEEKSQUINT_R, "CheekSquint_R"),
- makePair(LIPSTOGETHER, "LipsTogether"),
+ makePair(MOUTHCLOSE, "MouthClose"),
makePair(MOUTHUPPERUP_L, "MouthUpperUp_L"),
makePair(MOUTHUPPERUP_R, "MouthUpperUp_R"),
makePair(MOUTHLOWERDOWN_L, "MouthLowerDown_L"),
diff --git a/libraries/controllers/src/controllers/StandardControls.h b/libraries/controllers/src/controllers/StandardControls.h
index f99072af7c..965c095187 100644
--- a/libraries/controllers/src/controllers/StandardControls.h
+++ b/libraries/controllers/src/controllers/StandardControls.h
@@ -134,7 +134,7 @@ namespace controller {
PUFF,
CHEEKSQUINT_L,
CHEEKSQUINT_R,
- LIPSTOGETHER,
+ MOUTHCLOSE,
MOUTHUPPERUP_L,
MOUTHUPPERUP_R,
MOUTHLOWERDOWN_L,
diff --git a/libraries/shared/src/BlendshapeConstants.cpp b/libraries/shared/src/BlendshapeConstants.cpp
index 7564c31944..91b68ed8a9 100644
--- a/libraries/shared/src/BlendshapeConstants.cpp
+++ b/libraries/shared/src/BlendshapeConstants.cpp
@@ -54,7 +54,7 @@ const char* FACESHIFT_BLENDSHAPES[] = {
"Puff",
"CheekSquint_L",
"CheekSquint_R",
- "LipsTogether",
+ "MouthClose",
"MouthUpperUp_L",
"MouthUpperUp_R",
"MouthLowerDown_L",
diff --git a/libraries/shared/src/BlendshapeConstants.h b/libraries/shared/src/BlendshapeConstants.h
index 0f934b2056..8db29856c3 100644
--- a/libraries/shared/src/BlendshapeConstants.h
+++ b/libraries/shared/src/BlendshapeConstants.h
@@ -58,7 +58,7 @@ enum class Blendshapes : int {
Puff,
CheekSquint_L,
CheekSquint_R,
- LipsTogether,
+ MouthClose,
MouthUpperUp_L,
MouthUpperUp_R,
MouthLowerDown_L,
@@ -94,7 +94,7 @@ enum class LegacyBlendshpaes : int {
};
// NEW in ARKit
-// * LipsTogether
+// * MouthClose
// * MouthUpperUp_L
// * MouthUpperUp_R
// * MouthLowerDown_L
From 61b9f08fec914aa6a8233a398a545dfaa87e1da0 Mon Sep 17 00:00:00 2001
From: "Anthony J. Thibault"
Date: Tue, 22 Oct 2019 22:19:03 -0700
Subject: [PATCH 13/33] Blendshapes for OtherAvatars should update even if no
joints have changes.
---
interface/src/avatar/OtherAvatar.cpp | 5 ++++-
.../avatars-renderer/src/avatars-renderer/SkeletonModel.cpp | 3 ++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp
index 5673c2443f..50f6369dbe 100755
--- a/interface/src/avatar/OtherAvatar.cpp
+++ b/interface/src/avatar/OtherAvatar.cpp
@@ -267,6 +267,7 @@ void OtherAvatar::simulate(float deltaTime, bool inView) {
_skeletonModel->getRig().computeExternalPoses(rootTransform);
_jointDataSimulationRate.increment();
+ head->simulate(deltaTime);
_skeletonModel->simulate(deltaTime, true);
locationChanged(); // joints changed, so if there are any children, update them.
@@ -277,9 +278,11 @@ void OtherAvatar::simulate(float deltaTime, bool inView) {
headPosition = getWorldPosition();
}
head->setPosition(headPosition);
+ } else {
+ head->simulate(deltaTime);
+ _skeletonModel->simulate(deltaTime, false);
}
head->setScale(getModelScale());
- head->simulate(deltaTime);
relayJointDataToChildren();
} else {
// a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated.
diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp
index b52a68f066..fc16851942 100644
--- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp
+++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp
@@ -165,8 +165,9 @@ void SkeletonModel::updateAttitude(const glm::quat& orientation) {
// but just before head has been simulated.
void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
updateAttitude(_owningAvatar->getWorldOrientation());
+ setBlendshapeCoefficients(_owningAvatar->getHead()->getSummedBlendshapeCoefficients());
+
if (fullUpdate) {
- setBlendshapeCoefficients(_owningAvatar->getHead()->getSummedBlendshapeCoefficients());
Parent::simulate(deltaTime, fullUpdate);
From 777f9699192d9e542f06dd61f9e324a1d502b076 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Thu, 24 Oct 2019 09:00:29 +1300
Subject: [PATCH 14/33] Typo
---
libraries/script-engine/src/RecordingScriptingInterface.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libraries/script-engine/src/RecordingScriptingInterface.h b/libraries/script-engine/src/RecordingScriptingInterface.h
index 19db6dc50d..fd9c2d64e6 100644
--- a/libraries/script-engine/src/RecordingScriptingInterface.h
+++ b/libraries/script-engine/src/RecordingScriptingInterface.h
@@ -265,7 +265,7 @@ public slots:
* Gets the default directory that recordings are saved in.
* @function Recording.getDefaultRecordingSaveDirectory
* @returns {string} The default recording save directory.
- * @exampl Report the default save directory.
+ * @example Report the default save directory.
* print("Default save directory: " + Recording.getDefaultRecordingSaveDirectory());
*/
QString getDefaultRecordingSaveDirectory();
From 116510225ad6f9590b7d7deaeefe77012be5bf66 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Thu, 24 Oct 2019 09:10:26 +1300
Subject: [PATCH 15/33] Typo
---
libraries/ui/src/ui/ToolbarScriptingInterface.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libraries/ui/src/ui/ToolbarScriptingInterface.h b/libraries/ui/src/ui/ToolbarScriptingInterface.h
index a4746e4566..746ba2894e 100644
--- a/libraries/ui/src/ui/ToolbarScriptingInterface.h
+++ b/libraries/ui/src/ui/ToolbarScriptingInterface.h
@@ -19,7 +19,7 @@
class QQuickItem;
-// No JSDoc for ToolbarButtonProxy because oolbarProxy#addButton() doesn't work.
+// No JSDoc for ToolbarButtonProxy because ToolbarProxy#addButton() doesn't work.
class ToolbarButtonProxy : public QmlWrapper {
Q_OBJECT
From 423074463dada43a8b70d851f53cf5423193a8bb Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Thu, 24 Oct 2019 09:17:13 +1300
Subject: [PATCH 16/33] Typo
---
interface/src/audio/AudioScope.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/interface/src/audio/AudioScope.h b/interface/src/audio/AudioScope.h
index fcc9b21efe..26b228e900 100644
--- a/interface/src/audio/AudioScope.h
+++ b/interface/src/audio/AudioScope.h
@@ -240,7 +240,7 @@ signals:
void pauseChanged();
/**jsdoc
- * Triggered when scoep is triggered.
+ * Triggered when scope is triggered.
* @function AudioScope.triggered
* @returns {Signal}
*/
From 2591aed686acebf7c599199468a890f04a3bb1fd Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Thu, 24 Oct 2019 09:20:24 +1300
Subject: [PATCH 17/33] Exclude AudioScope API from JSDoc output
---
tools/jsdoc/plugins/hifi.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index 07549530ce..56d2278b50 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -26,7 +26,7 @@ exports.handlers = {
'../../assignment-client/src/octree',
'../../interface/src',
'../../interface/src/assets',
- '../../interface/src/audio',
+ //'../../interface/src/audio', Exlude AudioScope API from output.
'../../interface/src/avatar',
'../../interface/src/commerce',
'../../interface/src/devices',
From f28d317914448c90f0c2a1697de8832b5dc29975 Mon Sep 17 00:00:00 2001
From: "Anthony J. Thibault"
Date: Wed, 23 Oct 2019 16:43:10 -0700
Subject: [PATCH 18/33] Clean up reamining issues
---
interface/src/avatar/MySkeletonModel.cpp | 14 +++++---------
.../src/avatars-renderer/SkeletonModel.cpp | 11 -----------
libraries/avatars/src/AvatarData.cpp | 3 ++-
libraries/avatars/src/HeadData.cpp | 9 +--------
4 files changed, 8 insertions(+), 29 deletions(-)
diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp
index 0d7bd3f3b3..6fe199aaba 100755
--- a/interface/src/avatar/MySkeletonModel.cpp
+++ b/interface/src/avatar/MySkeletonModel.cpp
@@ -112,23 +112,19 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
const HFMModel& hfmModel = getHFMModel();
+ MyAvatar* myAvatar = static_cast(_owningAvatar);
+ assert(myAvatar);
+
Head* head = _owningAvatar->getHead();
- // AJT: blendshapes TODO: RE-enable this and avoid duplication with
- // SkeletonModel::updateRig()
- /*
- bool eyePosesValid = !head->getHasProceduralEyeMovement();
+ bool eyePosesValid = (myAvatar->getControllerPoseInSensorFrame(controller::Action::LEFT_EYE).isValid() ||
+ myAvatar->getControllerPoseInSensorFrame(controller::Action::RIGHT_EYE).isValid());
glm::vec3 lookAt;
if (eyePosesValid) {
lookAt = head->getLookAtPosition(); // don't apply no-crosseyes code when eyes are being tracked
} else {
lookAt = avoidCrossedEyes(head->getLookAtPosition());
}
- */
- glm::vec3 lookAt = avoidCrossedEyes(head->getLookAtPosition());
-
- MyAvatar* myAvatar = static_cast(_owningAvatar);
- assert(myAvatar);
Rig::ControllerParameters params;
diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp
index fc16851942..ccc87c28f3 100644
--- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp
+++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp
@@ -110,17 +110,6 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
assert(!_owningAvatar->isMyAvatar());
Head* head = _owningAvatar->getHead();
-
- // AJT: blendshapes TODO: RE-enable this. but move into rig?
- /*
- bool eyePosesValid = !head->getHasProceduralEyeMovement();
- glm::vec3 lookAt;
- if (eyePosesValid) {
- lookAt = head->getLookAtPosition(); // don't apply no-crosseyes code etc when eyes are being tracked
- } else {
- lookAt = avoidCrossedEyes(head->getCorrectedLookAtPosition());
- }
- */
glm::vec3 lookAt = avoidCrossedEyes(head->getCorrectedLookAtPosition());
// no need to call Model::updateRig() because otherAvatars get their joint state
diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp
index 87d6c57d59..818902968f 100755
--- a/libraries/avatars/src/AvatarData.cpp
+++ b/libraries/avatars/src/AvatarData.cpp
@@ -2637,6 +2637,7 @@ enum class JsonAvatarFrameVersion : int {
JointRotationsInAbsoluteFrame,
JointDefaultPoseBits,
JointUnscaledTranslations,
+ ARKitBlendshapes
};
QJsonValue toJsonValue(const JointData& joint) {
@@ -2681,7 +2682,7 @@ void AvatarData::avatarEntityDataToJson(QJsonObject& root) const {
QJsonObject AvatarData::toJson() const {
QJsonObject root;
- root[JSON_AVATAR_VERSION] = (int)JsonAvatarFrameVersion::JointUnscaledTranslations;
+ root[JSON_AVATAR_VERSION] = (int)JsonAvatarFrameVersion::ARKitBlendshapes;
if (!getSkeletonModelURL().isEmpty()) {
root[JSON_AVATAR_BODY_MODEL] = getSkeletonModelURL().toString();
diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp
index 93fb0190bb..5e8d5c457f 100644
--- a/libraries/avatars/src/HeadData.cpp
+++ b/libraries/avatars/src/HeadData.cpp
@@ -186,14 +186,7 @@ QJsonObject HeadData::toJson() const {
void HeadData::fromJson(const QJsonObject& json) {
if (json.contains(JSON_AVATAR_HEAD_BLENDSHAPE_COEFFICIENTS)) {
auto jsonValue = json[JSON_AVATAR_HEAD_BLENDSHAPE_COEFFICIENTS];
- if (jsonValue.isArray()) {
- QVector blendshapeCoefficients;
- QJsonArray blendshapeCoefficientsJson = jsonValue.toArray();
- for (const auto& blendshapeCoefficient : blendshapeCoefficientsJson) {
- blendshapeCoefficients.push_back((float)blendshapeCoefficient.toDouble());
- }
- setBlendshapeCoefficients(blendshapeCoefficients);
- } else if (jsonValue.isObject()) {
+ if (jsonValue.isObject()) {
QJsonObject blendshapeCoefficientsJson = jsonValue.toObject();
for (const QString& name : blendshapeCoefficientsJson.keys()) {
float value = (float)blendshapeCoefficientsJson[name].toDouble();
From dc7b611e8e8aded9b618868d1dcfef444dbe25eb Mon Sep 17 00:00:00 2001
From: "Anthony J. Thibault"
Date: Thu, 24 Oct 2019 09:53:11 -0700
Subject: [PATCH 19/33] documentation and warning fixes
---
interface/src/avatar/MyAvatar.cpp | 2 --
interface/src/avatar/MyAvatar.h | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index f1829db8f6..52083af8f2 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -6535,7 +6535,6 @@ void MyAvatar::updateEyesLookAtPosition(float deltaTime) {
updateLookAtTargetAvatar();
- bool isLookingAtSomeone = false;
glm::vec3 lookAtSpot;
const MyHead* myHead = getMyHead();
@@ -6596,7 +6595,6 @@ void MyAvatar::updateEyesLookAtPosition(float deltaTime) {
avatar && avatar->getLookAtSnappingEnabled() && getLookAtSnappingEnabled();
if (haveLookAtCandidate && mutualLookAtSnappingEnabled) {
// If I am looking at someone else, look directly at one of their eyes
- isLookingAtSomeone = true;
auto lookingAtHead = avatar->getHead();
const float MAXIMUM_FACE_ANGLE = 65.0f * RADIANS_PER_DEGREE;
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 953b7ef1dc..9197b005be 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -307,7 +307,7 @@ class MyAvatar : public Avatar {
* @borrows Avatar.clearAvatarEntity as clearAvatarEntity
* @borrows Avatar.hasScriptedBlendshapes as hasScriptedBlendshapes
* @borrows Avatar.hasProceduralBlinkFaceMovement as hasProceduralBlinkFaceMovement
- * @borrows Avatar.hasEyeFaceMovement as hasEyeFaceMovement
+ * @borrows Avatar.hasProceduralEyeFaceMovement as hasProceduralEyeFaceMovement
* @borrows Avatar.hasAudioEnabledFaceMovement as hasAudioEnabledFaceMovement
* @borrows Avatar.setSkeletonModelURL as setSkeletonModelURL
* @borrows Avatar.getAttachmentData as getAttachmentData
From 9325ea588a1b0fda23bea233eaa64ad924c2c5d1 Mon Sep 17 00:00:00 2001
From: "Anthony J. Thibault"
Date: Sat, 26 Oct 2019 09:20:51 -0700
Subject: [PATCH 20/33] Re-added removed jsdoc comments for removed AvatarInput
jsapi.
With a comment that these properties/functions have been removed.
---
interface/src/ui/AvatarInputs.h | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/interface/src/ui/AvatarInputs.h b/interface/src/ui/AvatarInputs.h
index 40ee0ea7d4..3b0e57d037 100644
--- a/interface/src/ui/AvatarInputs.h
+++ b/interface/src/ui/AvatarInputs.h
@@ -32,6 +32,14 @@ class AvatarInputs : public QObject {
* @hifi-client-entity
* @hifi-avatar
*
+ * @property {boolean} cameraEnabled - true
if webcam face tracking is enabled, false
if it is
+ * disabled.
+ * Read-only.
+ * Deprecated: This property is deprecated and has been removed.
+ * @property {boolean} cameraMuted - true
if webcam face tracking is muted (temporarily disabled),
+ * false
it if isn't.
+ * Read-only.
+ * Deprecated: This property is deprecated and has been removed.
* @property {boolean} ignoreRadiusEnabled - true
if the privacy shield is enabled, false
if it
* is disabled.
* Read-only.
@@ -87,6 +95,20 @@ public slots:
signals:
+ /**jsdoc
+ * Triggered when webcam face tracking is enabled or disabled.
+ * @deprecated This signal is deprecated and has been removed.
+ * @function AvatarInputs.cameraEnabledChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when webcam face tracking is muted (temporarily disabled) or unmuted.
+ * @deprecated This signal is deprecated and has been removed.
+ * @function AvatarInputs.cameraMutedChanged
+ * @returns {Signal}
+ */
+
/**jsdoc
* Triggered when the display mode changes between desktop and HMD.
* @function AvatarInputs.isHMDChanged
@@ -157,6 +179,12 @@ protected:
*/
Q_INVOKABLE void resetSensors();
+ /**jsdoc
+ * Toggles the muting (temporary disablement) of webcam face tracking on/off.
+ * Deprecated: This function is deprecated and has been removed.
+ * @function AvatarInputs.toggleCameraMute
+ */
+
private:
void onAvatarEnteredIgnoreRadius();
void onAvatarLeftIgnoreRadius();
From 70c3bb2748827cffb7bd0f60402a752af31e2c1c Mon Sep 17 00:00:00 2001
From: Oren Hurvitz
Date: Tue, 10 Sep 2019 15:38:20 +0300
Subject: [PATCH 21/33] Emit an event when failing to load an avatar.
Previously, MyAvatar only emitted an event (onLoadComplete) if the load succeeded.
Now it also emits an event (onLoadFailed) if the load failed.
---
interface/src/avatar/MyAvatar.cpp | 5 ++++-
interface/src/avatar/MyAvatar.h | 9 ++++++++-
libraries/animation/src/Rig.cpp | 6 +++++-
libraries/animation/src/Rig.h | 1 +
4 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index 6e0bfab69b..4392505fb3 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -349,7 +349,8 @@ MyAvatar::MyAvatar(QThread* thread) :
}
});
- connect(&(_skeletonModel->getRig()), SIGNAL(onLoadComplete()), this, SIGNAL(onLoadComplete()));
+ connect(&(_skeletonModel->getRig()), &Rig::onLoadComplete, this, &MyAvatar::onLoadComplete);
+ connect(&(_skeletonModel->getRig()), &Rig::onLoadFailed, this, &MyAvatar::onLoadFailed);
_characterController.setDensity(_density);
}
@@ -2626,6 +2627,8 @@ void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelN
if (urlString.isEmpty() || (fullAvatarURL != getSkeletonModelURL())) {
setSkeletonModelURL(fullAvatarURL);
UserActivityLogger::getInstance().changedModel("skeleton", urlString);
+ } else {
+ emit onLoadComplete();
}
}
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 081fd00d5b..4c7f0c4a75 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -2435,10 +2435,17 @@ signals:
/**jsdoc
* Triggered when the avatar's model finishes loading.
* @function MyAvatar.onLoadComplete
- * @returns {Signal}
+ * @returns {Signal}
*/
void onLoadComplete();
+ /**jsdoc
+ * Triggered when the avatar's model has failed to load.
+ * @function MyAvatar.onLoadFailed
+ * @returns {Signal}
+ */
+ void onLoadFailed();
+
/**jsdoc
* Triggered when your avatar changes from being active to being away.
* @function MyAvatar.wentAway
diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp
index fac4e04ce9..fc1885ea2b 100644
--- a/libraries/animation/src/Rig.cpp
+++ b/libraries/animation/src/Rig.cpp
@@ -2353,6 +2353,7 @@ void Rig::initAnimGraph(const QUrl& url) {
// abort load if the previous skeleton was deleted.
auto sharedSkeletonPtr = weakSkeletonPtr.lock();
if (!sharedSkeletonPtr) {
+ emit onLoadFailed();
return;
}
@@ -2386,8 +2387,9 @@ void Rig::initAnimGraph(const QUrl& url) {
}
emit onLoadComplete();
});
- connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) {
+ connect(_animLoader.get(), &AnimNodeLoader::error, [this, url](int error, QString str) {
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
+ emit onLoadFailed();
});
connect(_networkLoader.get(), &AnimNodeLoader::success, [this, weakSkeletonPtr, networkUrl](AnimNode::Pointer nodeIn) {
@@ -2415,6 +2417,8 @@ void Rig::initAnimGraph(const QUrl& url) {
connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) {
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
});
+ } else {
+ emit onLoadComplete();
}
}
diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h
index 8570ae4441..b2b9ecd5b4 100644
--- a/libraries/animation/src/Rig.h
+++ b/libraries/animation/src/Rig.h
@@ -260,6 +260,7 @@ public:
signals:
void onLoadComplete();
+ void onLoadFailed();
protected:
bool isIndexValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
From 884cbd7de93370a0d9ed0ec053b87bc1c8475cf9 Mon Sep 17 00:00:00 2001
From: amerhifi
Date: Tue, 29 Oct 2019 09:26:48 -0700
Subject: [PATCH 22/33] working on moving display plugin lookup to audiodevices
---
interface/src/scripting/AudioDevices.cpp | 29 +++++++++-
libraries/audio-client/src/AudioClient.cpp | 57 ++++++++-----------
libraries/audio-client/src/AudioClient.h | 5 +-
.../plugins/src/plugins/PluginManager.cpp | 8 +--
4 files changed, 58 insertions(+), 41 deletions(-)
diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp
index 76c871fa5c..8737cd1296 100644
--- a/interface/src/scripting/AudioDevices.cpp
+++ b/interface/src/scripting/AudioDevices.cpp
@@ -15,6 +15,7 @@
#include
#include
+#include
#include
#include "Application.h"
@@ -68,6 +69,21 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) {
return deviceName;
}
+
+static QString getHmdAudioDeviceName(QAudio::Mode mode) {
+ foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getAllDisplayPlugins()) {
+ if (displayPlugin && displayPlugin->isHmd()) {
+ if (mode == QAudio::AudioInput) {
+ return displayPlugin->getPreferredAudioInDevice();
+ } else {
+ return displayPlugin->getPreferredAudioOutDevice();
+ }
+ break;
+ }
+ }
+ return QString();
+}
+
Qt::ItemFlags AudioDeviceList::_flags { Qt::ItemIsSelectable | Qt::ItemIsEnabled };
AudioDeviceList::AudioDeviceList(QAudio::Mode mode) : _mode(mode) {
@@ -263,6 +279,18 @@ void AudioDeviceList::onDevicesChanged(const QList& devices
bool hmdIsSelected = false;
bool desktopIsSelected = false;
+ //getting hmd mode
+ if (devices.size() > 0) {
+ auto mode = devices.first().getMode();
+ QString name = getHmdAudioDeviceName(mode);
+ if (!name.isEmpty()) {
+ auto client = DependencyManager::get().data();
+ QMetaObject::invokeMethod(client, "setHmdAudioName",
+ Q_ARG(QAudio::Mode, mode),
+ Q_ARG(const QString&, name));
+ }
+ }
+
if (!_backupSelectedDesktopDeviceName.isEmpty() && !_backupSelectedHMDDeviceName.isEmpty()) {
foreach(const HifiAudioDeviceInfo& deviceInfo, devices) {
for (bool isHMD : {false, true}) {
@@ -275,7 +303,6 @@ void AudioDeviceList::onDevicesChanged(const QList& devices
_selectedDesktopDevice = deviceInfo;
backupSelectedDeviceName.clear();
}
-
}
}
}
diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp
index fe4fab8415..e966274a9b 100644
--- a/libraries/audio-client/src/AudioClient.cpp
+++ b/libraries/audio-client/src/AudioClient.cpp
@@ -48,7 +48,6 @@
#include
#include
#include
-#include
#include "AudioClientLogging.h"
#include "AudioLogging.h"
@@ -83,38 +82,31 @@ Mutex _recordMutex;
QString defaultAudioDeviceName(QAudio::Mode mode);
-static QString getHmdAudioDeviceName(QAudio::Mode mode) {
- foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getAllDisplayPlugins()) {
- if (displayPlugin && displayPlugin->isHmd()) {
- if (mode == QAudio::AudioInput) {
- return displayPlugin->getPreferredAudioInDevice();
- } else {
- return displayPlugin->getPreferredAudioOutDevice();
- }
- break;
- }
+void AudioClient::setHmdAudioName(QAudio::Mode mode, const QString& name) {
+ if (mode == QAudio::AudioInput) {
+ _hmdInputName = name;
+ } else {
+ _hmdOutputName = name;
}
- return QString();
}
// thread-safe
-QList getAvailableDevices(QAudio::Mode mode) {
+QList getAvailableDevices(QAudio::Mode mode, const QString& hmdName) {
//get hmd device name prior to locking device mutex. in case of shutdown, this thread will be locked and audio client
//cannot properly shut down.
- QString hmdDeviceName = getHmdAudioDeviceName(mode);
QString defDeviceName = defaultAudioDeviceName(mode);
// NOTE: availableDevices() clobbers the Qt internal device list
Lock lock(_deviceMutex);
auto devices = QAudioDeviceInfo::availableDevices(mode);
-
+
HifiAudioDeviceInfo defaultDesktopDevice;
QList newDevices;
for (auto& device : devices) {
newDevices.push_back(HifiAudioDeviceInfo(device, false, mode));
if (device.deviceName() == defDeviceName.trimmed()) {
defaultDesktopDevice = HifiAudioDeviceInfo(device, true, mode, HifiAudioDeviceInfo::desktop);
- }
+ }
}
if (defaultDesktopDevice.getDevice().isNull()) {
@@ -123,11 +115,10 @@ QList getAvailableDevices(QAudio::Mode mode) {
defaultDesktopDevice = HifiAudioDeviceInfo(devices.first(), true, mode, HifiAudioDeviceInfo::desktop);
}
newDevices.push_front(defaultDesktopDevice);
-
- if (!hmdDeviceName.isNull() && !hmdDeviceName.isEmpty()) {
+ if (!hmdName.isNull()) {
HifiAudioDeviceInfo hmdDevice;
foreach(auto device, newDevices) {
- if (device.getDevice().deviceName() == hmdDeviceName) {
+ if (device.getDevice().deviceName() == hmdName) {
hmdDevice = HifiAudioDeviceInfo(device.getDevice(), true, mode, HifiAudioDeviceInfo::hmd);
break;
}
@@ -149,9 +140,9 @@ void AudioClient::checkDevices() {
return;
}
- auto inputDevices = getAvailableDevices(QAudio::AudioInput);
- auto outputDevices = getAvailableDevices(QAudio::AudioOutput);
-
+ auto inputDevices = getAvailableDevices(QAudio::AudioInput, _hmdInputName);
+ auto outputDevices = getAvailableDevices(QAudio::AudioOutput, _hmdOutputName);
+
checkDefaultChanges(inputDevices);
checkDefaultChanges(outputDevices);
@@ -335,8 +326,8 @@ AudioClient::AudioClient() {
connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat);
// initialize wasapi; if getAvailableDevices is called from the CheckDevicesThread before this, it will crash
- getAvailableDevices(QAudio::AudioInput);
- getAvailableDevices(QAudio::AudioOutput);
+ getAvailableDevices(QAudio::AudioInput, _hmdInputName);
+ getAvailableDevices(QAudio::AudioOutput, _hmdOutputName);
// start a thread to detect any device changes
_checkDevicesTimer = new QTimer(this);
@@ -436,9 +427,9 @@ void AudioClient::setAudioPaused(bool pause) {
}
}
-HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName, bool isHmd=false) {
+HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName, const QString& hmdName, bool isHmd=false) {
HifiAudioDeviceInfo result;
- foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode)) {
+ foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode,hmdName)) {
if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) {
if ((!isHmd && audioDevice.getDeviceType() != HifiAudioDeviceInfo::hmd) || (isHmd && audioDevice.getDeviceType() != HifiAudioDeviceInfo::desktop)) {
result = audioDevice;
@@ -493,7 +484,7 @@ QString AudioClient::getWinDeviceName(wchar_t* guid) {
#endif
-HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
+HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode, const QString& hmdName) {
QString deviceName = defaultAudioDeviceName(mode);
#if defined (Q_OS_ANDROID)
if (mode == QAudio::AudioInput) {
@@ -509,7 +500,7 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
}
}
#endif
- return getNamedAudioDeviceForMode(mode, deviceName);
+ return getNamedAudioDeviceForMode(mode, deviceName, hmdName);
}
QString defaultAudioDeviceName(QAudio::Mode mode) {
@@ -615,7 +606,8 @@ QString defaultAudioDeviceName(QAudio::Mode mode) {
}
bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName) {
- return (getNamedAudioDeviceForMode(mode, deviceName).deviceName() == deviceName);
+ QString hmdName = mode == QAudio::AudioInput ? _hmdInputName : _hmdOutputName;
+ return (getNamedAudioDeviceForMode(mode, deviceName, hmdName).deviceName() == deviceName);
}
@@ -778,11 +770,11 @@ void AudioClient::start() {
_desiredOutputFormat = _desiredInputFormat;
_desiredOutputFormat.setChannelCount(OUTPUT_CHANNEL_COUNT);
- HifiAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput);
+ HifiAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput, _hmdInputName);
qCDebug(audioclient) << "The default audio input device is" << inputDeviceInfo.deviceName();
bool inputFormatSupported = switchInputToAudioDevice(inputDeviceInfo);
- HifiAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput);
+ HifiAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput, _hmdOutputName);
qCDebug(audioclient) << "The default audio output device is" << outputDeviceInfo.deviceName();
bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo);
@@ -1021,7 +1013,8 @@ bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo
}
bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QString& deviceName, bool isHmd) {
- return switchAudioDevice(mode, getNamedAudioDeviceForMode(mode, deviceName, isHmd));
+ QString hmdName = mode == QAudio::AudioInput ? _hmdInputName : _hmdOutputName;
+ return switchAudioDevice(mode, getNamedAudioDeviceForMode(mode, deviceName, hmdName, isHmd));
}
void AudioClient::configureReverb() {
diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h
index ce63c43cff..9628de99e8 100644
--- a/libraries/audio-client/src/AudioClient.h
+++ b/libraries/audio-client/src/AudioClient.h
@@ -313,7 +313,7 @@ private:
// background tasks
void checkDevices();
void checkPeakValues();
-
+ void setHmdAudioName(QAudio::Mode mode, const QString& name);
void outputFormatChanged();
void handleAudioInput(QByteArray& audioBuffer);
void prepareLocalAudioInjectors(std::unique_ptr localAudioLock = nullptr);
@@ -481,6 +481,9 @@ private:
QList _inputDevices;
QList _outputDevices;
+ QString _hmdInputName { QString() };
+ QString _hmdOutputName{ QString() };
+
AudioFileWav _audioFileWav;
bool _hasReceivedFirstPacket { false };
diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp
index 660159d9bd..784de6bdea 100644
--- a/libraries/plugins/src/plugins/PluginManager.cpp
+++ b/libraries/plugins/src/plugins/PluginManager.cpp
@@ -224,13 +224,7 @@ const OculusPlatformPluginPointer PluginManager::getOculusPlatformPlugin() {
}
DisplayPluginList PluginManager::getAllDisplayPlugins() {
- if (thread() != QThread::currentThread()) {
- DisplayPluginList list;
- QMetaObject::invokeMethod(this, "getAllDisplayPlugins", Qt::BlockingQueuedConnection, Q_RETURN_ARG(DisplayPluginList, list));
- return list;
- } else {
- return _displayPlugins;
- }
+ return _displayPlugins;
}
const DisplayPluginList& PluginManager::getDisplayPlugins() {
From 9370ce9b763bbacd94449e267d2b38fe4ef259d0 Mon Sep 17 00:00:00 2001
From: amerhifi
Date: Tue, 29 Oct 2019 10:24:30 -0700
Subject: [PATCH 23/33] removed items
---
libraries/audio-client/CMakeLists.txt | 1 -
libraries/audio-client/src/AudioClient.h | 3 ++-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libraries/audio-client/CMakeLists.txt b/libraries/audio-client/CMakeLists.txt
index e1d90334ff..6b88292dd4 100644
--- a/libraries/audio-client/CMakeLists.txt
+++ b/libraries/audio-client/CMakeLists.txt
@@ -6,7 +6,6 @@ setup_hifi_library(Network Multimedia ${PLATFORM_QT_COMPONENTS})
link_hifi_libraries(audio plugins)
include_hifi_library_headers(shared)
include_hifi_library_headers(networking)
-include_hifi_library_headers(gpu)
if (ANDROID)
else ()
diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h
index 9628de99e8..fadc599228 100644
--- a/libraries/audio-client/src/AudioClient.h
+++ b/libraries/audio-client/src/AudioClient.h
@@ -243,6 +243,8 @@ public slots:
// calling with a null QAudioDevice will use the system default
bool switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo = HifiAudioDeviceInfo());
bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName, bool isHmd);
+ void setHmdAudioName(QAudio::Mode mode, const QString& name);
+
// Qt opensles plugin is not able to detect when the headset is plugged in
void setHeadsetPluggedIn(bool pluggedIn);
@@ -313,7 +315,6 @@ private:
// background tasks
void checkDevices();
void checkPeakValues();
- void setHmdAudioName(QAudio::Mode mode, const QString& name);
void outputFormatChanged();
void handleAudioInput(QByteArray& audioBuffer);
void prepareLocalAudioInjectors(std::unique_ptr localAudioLock = nullptr);
From 77f5b985a1a7c0c7e9431de2c397a416307d9308 Mon Sep 17 00:00:00 2001
From: amerhifi
Date: Tue, 29 Oct 2019 11:19:59 -0700
Subject: [PATCH 24/33] added read/write lock to hmd name
---
libraries/audio-client/src/AudioClient.cpp | 43 +++++++++++++++++-----
libraries/audio-client/src/AudioClient.h | 2 +-
2 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp
index e966274a9b..c81823d14b 100644
--- a/libraries/audio-client/src/AudioClient.cpp
+++ b/libraries/audio-client/src/AudioClient.cpp
@@ -83,6 +83,7 @@ Mutex _recordMutex;
QString defaultAudioDeviceName(QAudio::Mode mode);
void AudioClient::setHmdAudioName(QAudio::Mode mode, const QString& name) {
+ QWriteLocker lock(&_hmdNameLock);
if (mode == QAudio::AudioInput) {
_hmdInputName = name;
} else {
@@ -140,8 +141,17 @@ void AudioClient::checkDevices() {
return;
}
- auto inputDevices = getAvailableDevices(QAudio::AudioInput, _hmdInputName);
- auto outputDevices = getAvailableDevices(QAudio::AudioOutput, _hmdOutputName);
+ QString hmdInputName;
+ QString hmdOutputName;
+
+ {
+ QReadLocker readLock(&_hmdNameLock);
+ hmdInputName = _hmdInputName;
+ hmdOutputName = _hmdOutputName;
+ }
+
+ auto inputDevices = getAvailableDevices(QAudio::AudioInput, hmdInputName);
+ auto outputDevices = getAvailableDevices(QAudio::AudioOutput, hmdOutputName);
checkDefaultChanges(inputDevices);
checkDefaultChanges(outputDevices);
@@ -325,10 +335,12 @@ AudioClient::AudioClient() {
connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat);
- // initialize wasapi; if getAvailableDevices is called from the CheckDevicesThread before this, it will crash
- getAvailableDevices(QAudio::AudioInput, _hmdInputName);
- getAvailableDevices(QAudio::AudioOutput, _hmdOutputName);
-
+ {
+ QReadLocker readLock(&_hmdNameLock);
+ // initialize wasapi; if getAvailableDevices is called from the CheckDevicesThread before this, it will crash
+ getAvailableDevices(QAudio::AudioInput, _hmdInputName);
+ getAvailableDevices(QAudio::AudioOutput, _hmdOutputName);
+ }
// start a thread to detect any device changes
_checkDevicesTimer = new QTimer(this);
const unsigned long DEVICE_CHECK_INTERVAL_MSECS = 2 * 1000;
@@ -606,6 +618,7 @@ QString defaultAudioDeviceName(QAudio::Mode mode) {
}
bool AudioClient::getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName) {
+ QReadLocker readLock(&_hmdNameLock);
QString hmdName = mode == QAudio::AudioInput ? _hmdInputName : _hmdOutputName;
return (getNamedAudioDeviceForMode(mode, deviceName, hmdName).deviceName() == deviceName);
}
@@ -769,12 +782,20 @@ void AudioClient::start() {
_desiredOutputFormat = _desiredInputFormat;
_desiredOutputFormat.setChannelCount(OUTPUT_CHANNEL_COUNT);
+
+ QString inputName;
+ QString outputName;
+ {
+ QReadLocker readLock(&_hmdNameLock);
+ inputName = _hmdInputName;
+ outputName = _hmdOutputName;
+ }
- HifiAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput, _hmdInputName);
+ HifiAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput, inputName);
qCDebug(audioclient) << "The default audio input device is" << inputDeviceInfo.deviceName();
bool inputFormatSupported = switchInputToAudioDevice(inputDeviceInfo);
- HifiAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput, _hmdOutputName);
+ HifiAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput, outputName);
qCDebug(audioclient) << "The default audio output device is" << outputDeviceInfo.deviceName();
bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo);
@@ -1013,7 +1034,11 @@ bool AudioClient::switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo
}
bool AudioClient::switchAudioDevice(QAudio::Mode mode, const QString& deviceName, bool isHmd) {
- QString hmdName = mode == QAudio::AudioInput ? _hmdInputName : _hmdOutputName;
+ QString hmdName;
+ {
+ QReadLocker readLock(&_hmdNameLock);
+ hmdName = mode == QAudio::AudioInput ? _hmdInputName : _hmdOutputName;
+ }
return switchAudioDevice(mode, getNamedAudioDeviceForMode(mode, deviceName, hmdName, isHmd));
}
diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h
index fadc599228..4e6abd3509 100644
--- a/libraries/audio-client/src/AudioClient.h
+++ b/libraries/audio-client/src/AudioClient.h
@@ -508,7 +508,7 @@ private:
#endif
AudioSolo _solo;
-
+ QReadWriteLock _hmdNameLock;
Mutex _checkDevicesMutex;
QTimer* _checkDevicesTimer { nullptr };
Mutex _checkPeakValuesMutex;
From 7d5dcbfc77e3cf047504d48f428994689745e9ce Mon Sep 17 00:00:00 2001
From: amerhifi
Date: Tue, 29 Oct 2019 11:58:04 -0700
Subject: [PATCH 25/33] space cleanup
---
interface/src/scripting/AudioDevices.cpp | 1 -
libraries/audio-client/src/AudioClient.cpp | 2 +-
libraries/audio-client/src/AudioClient.h | 3 ++-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp
index 8737cd1296..8a4e0925e3 100644
--- a/interface/src/scripting/AudioDevices.cpp
+++ b/interface/src/scripting/AudioDevices.cpp
@@ -69,7 +69,6 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) {
return deviceName;
}
-
static QString getHmdAudioDeviceName(QAudio::Mode mode) {
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getAllDisplayPlugins()) {
if (displayPlugin && displayPlugin->isHmd()) {
diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp
index c81823d14b..4b7d642a71 100644
--- a/libraries/audio-client/src/AudioClient.cpp
+++ b/libraries/audio-client/src/AudioClient.cpp
@@ -116,6 +116,7 @@ QList getAvailableDevices(QAudio::Mode mode, const QString&
defaultDesktopDevice = HifiAudioDeviceInfo(devices.first(), true, mode, HifiAudioDeviceInfo::desktop);
}
newDevices.push_front(defaultDesktopDevice);
+
if (!hmdName.isNull()) {
HifiAudioDeviceInfo hmdDevice;
foreach(auto device, newDevices) {
@@ -143,7 +144,6 @@ void AudioClient::checkDevices() {
QString hmdInputName;
QString hmdOutputName;
-
{
QReadLocker readLock(&_hmdNameLock);
hmdInputName = _hmdInputName;
diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h
index 4e6abd3509..dafa81081c 100644
--- a/libraries/audio-client/src/AudioClient.h
+++ b/libraries/audio-client/src/AudioClient.h
@@ -244,7 +244,6 @@ public slots:
bool switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo = HifiAudioDeviceInfo());
bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName, bool isHmd);
void setHmdAudioName(QAudio::Mode mode, const QString& name);
-
// Qt opensles plugin is not able to detect when the headset is plugged in
void setHeadsetPluggedIn(bool pluggedIn);
@@ -315,6 +314,7 @@ private:
// background tasks
void checkDevices();
void checkPeakValues();
+
void outputFormatChanged();
void handleAudioInput(QByteArray& audioBuffer);
void prepareLocalAudioInjectors(std::unique_ptr localAudioLock = nullptr);
@@ -508,6 +508,7 @@ private:
#endif
AudioSolo _solo;
+
QReadWriteLock _hmdNameLock;
Mutex _checkDevicesMutex;
QTimer* _checkDevicesTimer { nullptr };
From ddfbb55e19fedae98d1aeba7d4d9a83299f8b025 Mon Sep 17 00:00:00 2001
From: amerhifi
Date: Tue, 29 Oct 2019 15:36:43 -0700
Subject: [PATCH 26/33] fixed old ui filtering of audio devices
---
interface/resources/qml/hifi/audio/Audio.qml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml
index fccba12a8a..eef339b854 100644
--- a/interface/resources/qml/hifi/audio/Audio.qml
+++ b/interface/resources/qml/hifi/audio/Audio.qml
@@ -375,14 +375,14 @@ Rectangle {
x: margins.paddings
interactive: false;
height: contentHeight;
- spacing: 4;
+
clip: true;
model: AudioScriptingInterface.devices.input;
delegate: Item {
width: rightMostInputLevelPos - margins.paddings*2
- height: margins.sizeCheckBox > checkBoxInput.implicitHeight ?
- margins.sizeCheckBox : checkBoxInput.implicitHeight
-
+ height: ((type != "hmd" && bar.currentIndex === 0) || (type != "desktop" && bar.currentIndex === 1)) ?
+ (margins.sizeCheckBox > checkBoxInput.implicitHeight ? margins.sizeCheckBox + 4 : checkBoxInput.implicitHeight + 4) : 0
+ visible: (type != "hmd" && bar.currentIndex === 0) || (type != "desktop" && bar.currentIndex === 1)
AudioControls.CheckBox {
id: checkBoxInput
anchors.left: parent.left
@@ -470,13 +470,13 @@ Rectangle {
height: contentHeight;
anchors.top: outputDeviceHeader.bottom;
anchors.topMargin: 10;
- spacing: 4;
clip: true;
model: AudioScriptingInterface.devices.output;
delegate: Item {
width: rightMostInputLevelPos
- height: margins.sizeCheckBox > checkBoxOutput.implicitHeight ?
- margins.sizeCheckBox : checkBoxOutput.implicitHeight
+ height: ((type != "hmd" && bar.currentIndex === 0) || (type != "desktop" && bar.currentIndex === 1)) ?
+ (margins.sizeCheckBox > checkBoxOutput.implicitHeight ? margins.sizeCheckBox + 4 : checkBoxOutput.implicitHeight + 4) : 0
+ visible: (type != "hmd" && bar.currentIndex === 0) || (type != "desktop" && bar.currentIndex === 1)
AudioControls.CheckBox {
id: checkBoxOutput
From 7953e3889f4f04b458a09d0a899730f158b605a3 Mon Sep 17 00:00:00 2001
From: Oren Hurvitz
Date: Tue, 10 Sep 2019 11:48:05 +0300
Subject: [PATCH 27/33] Wait for the avatar skeleton to finish loading before
adding the avatar entities
---
interface/src/AvatarBookmarks.cpp | 42 ++++++++++++++++++++-----------
1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp
index d9ac522dc8..2ebe769bec 100644
--- a/interface/src/AvatarBookmarks.cpp
+++ b/interface/src/AvatarBookmarks.cpp
@@ -212,22 +212,36 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) {
auto myAvatar = DependencyManager::get()->getMyAvatar();
auto treeRenderer = DependencyManager::get();
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
- myAvatar->clearWornAvatarEntities();
+
+ // Once the skeleton URL has been loaded, add the Avatar Entities.
+ // We have to wait, because otherwise the avatar entities will try to get attached to the joints
+ // of the *current* avatar at first. But the current avatar might have a different joints scheme
+ // from the new avatar, and that would cause the entities to be attached to the wrong joints.
+
+ std::shared_ptr connection1 = std::make_shared();
+ *connection1 = connect(myAvatar.get(), &MyAvatar::onLoadComplete, [this, bookmark, bookmarkName, myAvatar, connection1]() {
+ qCDebug(interfaceapp) << "Finish loading avatar bookmark" << bookmarkName;
+ QObject::disconnect(*connection1);
+ myAvatar->clearWornAvatarEntities();
+ const float& qScale = bookmark.value(ENTRY_AVATAR_SCALE, 1.0f).toFloat();
+ myAvatar->setAvatarScale(qScale);
+ QList attachments = bookmark.value(ENTRY_AVATAR_ATTACHMENTS, QList()).toList();
+ myAvatar->setAttachmentsVariant(attachments);
+ QVariantList avatarEntities = bookmark.value(ENTRY_AVATAR_ENTITIES, QVariantList()).toList();
+ addAvatarEntities(avatarEntities);
+ emit bookmarkLoaded(bookmarkName);
+ });
+
+ std::shared_ptr connection2 = std::make_shared();
+ *connection2 = connect(myAvatar.get(), &MyAvatar::onLoadFailed, [this, bookmarkName, connection2]() {
+ qCDebug(interfaceapp) << "Failed to load avatar bookmark" << bookmarkName;
+ QObject::disconnect(*connection2);
+ });
+
+ qCDebug(interfaceapp) << "Start loading avatar bookmark" << bookmarkName;
+
const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString();
myAvatar->useFullAvatarURL(avatarUrl);
- qCDebug(interfaceapp) << "Avatar On";
- const QList& attachments = bookmark.value(ENTRY_AVATAR_ATTACHMENTS, QList()).toList();
-
- qCDebug(interfaceapp) << "Attach " << attachments;
- myAvatar->setAttachmentsVariant(attachments);
-
- const float& qScale = bookmark.value(ENTRY_AVATAR_SCALE, 1.0f).toFloat();
- myAvatar->setAvatarScale(qScale);
-
- const QVariantList& avatarEntities = bookmark.value(ENTRY_AVATAR_ENTITIES, QVariantList()).toList();
- addAvatarEntities(avatarEntities);
-
- emit bookmarkLoaded(bookmarkName);
}
}
}
From 1a42ad0736cb6d596a88db41091c8f51f3e434ee Mon Sep 17 00:00:00 2001
From: dante ruiz
Date: Wed, 30 Oct 2019 09:27:37 -0700
Subject: [PATCH 28/33] update launcher text
---
.../qml/HFBase/CreateAccountBase.qml | 22 ++++---------------
launchers/qt/resources/qml/HFBase/Error.qml | 2 +-
.../qt/resources/qml/HFBase/LoginBase.qml | 2 +-
3 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/launchers/qt/resources/qml/HFBase/CreateAccountBase.qml b/launchers/qt/resources/qml/HFBase/CreateAccountBase.qml
index c419878413..f788eeaa4d 100644
--- a/launchers/qt/resources/qml/HFBase/CreateAccountBase.qml
+++ b/launchers/qt/resources/qml/HFBase/CreateAccountBase.qml
@@ -8,7 +8,7 @@ import HQLauncher 1.0
Item {
id: root
anchors.centerIn: parent
- property string titleText: "Sign in and pick a password"
+ property string titleText: "Create Your Username and Password"
property string usernamePlaceholder: "Username"
property string passwordPlaceholder: "Set a password (must be at least 6 characters)"
property int marginLeft: root.width * 0.15
@@ -28,6 +28,7 @@ Item {
HFTextHeader {
id: title
width: 481
+ wrapMode: Text.WordWrap
lineHeight: 35
lineHeightMode: Text.FixedHeight
text: LauncherState.lastSignupErrorMessage.length == 0 ? root.titleText : "Uh oh"
@@ -39,21 +40,6 @@ Item {
}
}
- HFTextRegular {
- id: instruction
- width: 425
-
- text: "Use the email address you applied for access with"
- visible: LauncherState.lastSignupErrorMessage.length == 0
-
- anchors {
- left: root.left
- leftMargin: root.marginLeft
- top: title.bottom
- topMargin: 18
- }
- }
-
HFTextError {
id: error
@@ -88,10 +74,10 @@ Item {
enabled: root.enabled
- placeholderText: "Email Address"
+ placeholderText: "Verify Your Email"
seperatorColor: Qt.rgba(1, 1, 1, 0.3)
anchors {
- top: instruction.bottom
+ top: error.visible ? error.bottom : title.bottom
left: root.left
leftMargin: root.marginLeft
topMargin: 18
diff --git a/launchers/qt/resources/qml/HFBase/Error.qml b/launchers/qt/resources/qml/HFBase/Error.qml
index 98eb1d17ac..5f93931ced 100644
--- a/launchers/qt/resources/qml/HFBase/Error.qml
+++ b/launchers/qt/resources/qml/HFBase/Error.qml
@@ -45,7 +45,7 @@ Item {
HFTextRegular {
id: description
- text: "We seem to have a problem.\n Please restart Launcher."
+ text: "We seem to have a problem.\n Please restart."
anchors {
top: header.bottom
diff --git a/launchers/qt/resources/qml/HFBase/LoginBase.qml b/launchers/qt/resources/qml/HFBase/LoginBase.qml
index 1df9950dd4..1f526edf19 100644
--- a/launchers/qt/resources/qml/HFBase/LoginBase.qml
+++ b/launchers/qt/resources/qml/HFBase/LoginBase.qml
@@ -77,7 +77,7 @@ Item {
width: 430
text: LauncherState.lastUsedUsername
- placeholderText: "Username"
+ placeholderText: "Username or Email address"
seperatorColor: Qt.rgba(1, 1, 1, 0.3)
anchors {
From d48097ce2c81a52d87e25fd2b566f11f78cf1d02 Mon Sep 17 00:00:00 2001
From: dante ruiz
Date: Wed, 30 Oct 2019 10:41:17 -0700
Subject: [PATCH 29/33] Make requested changes
---
launchers/qt/resources/qml/HFBase/Error.qml | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/launchers/qt/resources/qml/HFBase/Error.qml b/launchers/qt/resources/qml/HFBase/Error.qml
index 5f93931ced..8e45c6accb 100644
--- a/launchers/qt/resources/qml/HFBase/Error.qml
+++ b/launchers/qt/resources/qml/HFBase/Error.qml
@@ -45,7 +45,7 @@ Item {
HFTextRegular {
id: description
- text: "We seem to have a problem.\n Please restart."
+ text: "We seem to have a problem."
anchors {
top: header.bottom
@@ -54,6 +54,16 @@ Item {
}
}
+ HFTextRegular {
+ text: "Please restart."
+
+ anchors {
+ top: description.bottom
+ topMargin: 1
+ horizontalCenter: header.horizontalCenter
+ }
+ }
+
HFButton {
id: button
From 39e10926606ef1768c9679f92f4423d4918b1f1f Mon Sep 17 00:00:00 2001
From: amer cerkic
Date: Wed, 30 Oct 2019 11:34:41 -0700
Subject: [PATCH 30/33] working on hmd fix
---
interface/src/scripting/AudioDevices.cpp | 28 +++++++++++-------------
interface/src/scripting/AudioDevices.h | 2 +-
2 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp
index 8a4e0925e3..306d822ed4 100644
--- a/interface/src/scripting/AudioDevices.cpp
+++ b/interface/src/scripting/AudioDevices.cpp
@@ -271,24 +271,22 @@ std::shared_ptr getSimilarDevice(const QString& deviceNa
return devices[minDistanceIndex];
}
-void AudioDeviceList::onDevicesChanged(const QList& devices) {
+
+void AudioDeviceList::onDevicesChanged(QAudio::Mode mode, const QList& devices) {
beginResetModel();
QList> newDevices;
bool hmdIsSelected = false;
bool desktopIsSelected = false;
- //getting hmd mode
- if (devices.size() > 0) {
- auto mode = devices.first().getMode();
- QString name = getHmdAudioDeviceName(mode);
- if (!name.isEmpty()) {
- auto client = DependencyManager::get().data();
- QMetaObject::invokeMethod(client, "setHmdAudioName",
- Q_ARG(QAudio::Mode, mode),
- Q_ARG(const QString&, name));
- }
+ QString name = getHmdAudioDeviceName(mode);
+ if (!name.isEmpty()) {
+ auto client = DependencyManager::get().data();
+ QMetaObject::invokeMethod(client, "setHmdAudioName",
+ Q_ARG(QAudio::Mode, mode),
+ Q_ARG(const QString&, name));
}
+
if (!_backupSelectedDesktopDeviceName.isEmpty() && !_backupSelectedHMDDeviceName.isEmpty()) {
foreach(const HifiAudioDeviceInfo& deviceInfo, devices) {
@@ -452,8 +450,8 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
const QList& devicesOutput = client->getAudioDevices(QAudio::AudioOutput);
//setup devices
- _inputs.onDevicesChanged(devicesInput);
- _outputs.onDevicesChanged(devicesOutput);
+ _inputs.onDevicesChanged(QAudio::AudioInput, devicesInput);
+ _outputs.onDevicesChanged(QAudio::AudioOutput,devicesOutput);
}
AudioDevices::~AudioDevices() {}
@@ -552,14 +550,14 @@ void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList& devices);
+ void onDevicesChanged(QAudio::Mode mode, const QList& devices);
protected:
friend class AudioDevices;
From 4b4b722875cd64aaa786d637aa5cb592586b0600 Mon Sep 17 00:00:00 2001
From: amer cerkic
Date: Wed, 30 Oct 2019 16:27:19 -0700
Subject: [PATCH 31/33] fixed issues related to context switching and selection
with hmd
---
interface/src/scripting/AudioDevices.cpp | 36 ++++++++++++----------
libraries/audio-client/src/AudioClient.cpp | 18 +----------
2 files changed, 21 insertions(+), 33 deletions(-)
diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp
index 306d822ed4..d66cb84dfe 100644
--- a/interface/src/scripting/AudioDevices.cpp
+++ b/interface/src/scripting/AudioDevices.cpp
@@ -69,18 +69,25 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) {
return deviceName;
}
-static QString getHmdAudioDeviceName(QAudio::Mode mode) {
+static void checkHmdDefaultsChange(QAudio::Mode mode) {
+ QString name;
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getAllDisplayPlugins()) {
if (displayPlugin && displayPlugin->isHmd()) {
if (mode == QAudio::AudioInput) {
- return displayPlugin->getPreferredAudioInDevice();
+ name = displayPlugin->getPreferredAudioInDevice();
} else {
- return displayPlugin->getPreferredAudioOutDevice();
+ name = displayPlugin->getPreferredAudioOutDevice();
}
break;
}
}
- return QString();
+
+ if (!name.isEmpty()) {
+ auto client = DependencyManager::get().data();
+ QMetaObject::invokeMethod(client, "setHmdAudioName",
+ Q_ARG(QAudio::Mode, mode),
+ Q_ARG(const QString&, name));
+ }
}
Qt::ItemFlags AudioDeviceList::_flags { Qt::ItemIsSelectable | Qt::ItemIsEnabled };
@@ -278,16 +285,8 @@ void AudioDeviceList::onDevicesChanged(QAudio::Mode mode, const QList> newDevices;
bool hmdIsSelected = false;
bool desktopIsSelected = false;
-
- QString name = getHmdAudioDeviceName(mode);
- if (!name.isEmpty()) {
- auto client = DependencyManager::get().data();
- QMetaObject::invokeMethod(client, "setHmdAudioName",
- Q_ARG(QAudio::Mode, mode),
- Q_ARG(const QString&, name));
- }
-
+ checkHmdDefaultsChange(mode);
if (!_backupSelectedDesktopDeviceName.isEmpty() && !_backupSelectedHMDDeviceName.isEmpty()) {
foreach(const HifiAudioDeviceInfo& deviceInfo, devices) {
for (bool isHMD : {false, true}) {
@@ -441,6 +440,9 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
connect(client, &AudioClient::deviceChanged, this, &AudioDevices::onDeviceChanged, Qt::QueuedConnection);
connect(client, &AudioClient::devicesChanged, this, &AudioDevices::onDevicesChanged, Qt::QueuedConnection);
connect(client, &AudioClient::peakValueListChanged, &_inputs, &AudioInputDeviceList::onPeakValueListChanged, Qt::QueuedConnection);
+
+ checkHmdDefaultsChange(QAudio::AudioInput);
+ checkHmdDefaultsChange(QAudio::AudioOutput);
_inputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioInput), contextIsHMD);
_outputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioOutput), contextIsHMD);
@@ -449,9 +451,11 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
const QList& devicesInput = client->getAudioDevices(QAudio::AudioInput);
const QList& devicesOutput = client->getAudioDevices(QAudio::AudioOutput);
- //setup devices
- _inputs.onDevicesChanged(QAudio::AudioInput, devicesInput);
- _outputs.onDevicesChanged(QAudio::AudioOutput,devicesOutput);
+ if (devicesInput.size() > 0 && devicesOutput.size() > 0) {
+ //setup devices
+ _inputs.onDevicesChanged(QAudio::AudioInput, devicesInput);
+ _outputs.onDevicesChanged(QAudio::AudioOutput, devicesOutput);
+ }
}
AudioDevices::~AudioDevices() {}
diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp
index 4b7d642a71..d8741e4aa7 100644
--- a/libraries/audio-client/src/AudioClient.cpp
+++ b/libraries/audio-client/src/AudioClient.cpp
@@ -791,23 +791,7 @@ void AudioClient::start() {
outputName = _hmdOutputName;
}
- HifiAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput, inputName);
- qCDebug(audioclient) << "The default audio input device is" << inputDeviceInfo.deviceName();
- bool inputFormatSupported = switchInputToAudioDevice(inputDeviceInfo);
-
- HifiAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput, outputName);
- qCDebug(audioclient) << "The default audio output device is" << outputDeviceInfo.deviceName();
- bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo);
-
- if (!inputFormatSupported) {
- qCDebug(audioclient) << "Unable to set up audio input because of a problem with input format.";
- qCDebug(audioclient) << "The closest format available is" << inputDeviceInfo.getDevice().nearestFormat(_desiredInputFormat);
- }
-
- if (!outputFormatSupported) {
- qCDebug(audioclient) << "Unable to set up audio output because of a problem with output format.";
- qCDebug(audioclient) << "The closest format available is" << outputDeviceInfo.getDevice().nearestFormat(_desiredOutputFormat);
- }
+
#if defined(Q_OS_ANDROID)
connect(&_checkInputTimer, &QTimer::timeout, this, &AudioClient::checkInputTimeout);
_checkInputTimer.start(CHECK_INPUT_READS_MSECS);
From 52e0f54d0c76456b7296bf10a321ba7c65817df2 Mon Sep 17 00:00:00 2001
From: amerhifi
Date: Thu, 31 Oct 2019 07:21:16 -0700
Subject: [PATCH 32/33] addressing comments
---
interface/src/scripting/AudioDevices.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp
index d66cb84dfe..688b4df8cd 100644
--- a/interface/src/scripting/AudioDevices.cpp
+++ b/interface/src/scripting/AudioDevices.cpp
@@ -554,14 +554,14 @@ void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList
Date: Thu, 31 Oct 2019 11:29:46 -0700
Subject: [PATCH 33/33] Attempt to fix DEV-2615 and DEV-2618 with more menu
scripting interface guards
---
.../src/scripting/MenuScriptingInterface.cpp | 119 +++++++++++++++---
1 file changed, 100 insertions(+), 19 deletions(-)
diff --git a/interface/src/scripting/MenuScriptingInterface.cpp b/interface/src/scripting/MenuScriptingInterface.cpp
index 1020c12733..9e7f6fdc2b 100644
--- a/interface/src/scripting/MenuScriptingInterface.cpp
+++ b/interface/src/scripting/MenuScriptingInterface.cpp
@@ -32,106 +32,187 @@ void MenuScriptingInterface::menuItemTriggered() {
}
void MenuScriptingInterface::addMenu(const QString& menu, const QString& grouping) {
- QMetaObject::invokeMethod(Menu::getInstance(), "addMenu", Q_ARG(const QString&, menu), Q_ARG(const QString&, grouping));
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
+ QMetaObject::invokeMethod(menuInstance, "addMenu", Q_ARG(const QString&, menu), Q_ARG(const QString&, grouping));
}
void MenuScriptingInterface::removeMenu(const QString& menu) {
- QMetaObject::invokeMethod(Menu::getInstance(), "removeMenu", Q_ARG(const QString&, menu));
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
+ QMetaObject::invokeMethod(menuInstance, "removeMenu", Q_ARG(const QString&, menu));
}
bool MenuScriptingInterface::menuExists(const QString& menu) {
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return false;
+ }
+
if (QThread::currentThread() == qApp->thread()) {
- Menu* menuInstance = Menu::getInstance();
return menuInstance && menuInstance->menuExists(menu);
}
+
bool result { false };
- BLOCKING_INVOKE_METHOD(Menu::getInstance(), "menuExists",
+
+ BLOCKING_INVOKE_METHOD(menuInstance, "menuExists",
Q_RETURN_ARG(bool, result),
Q_ARG(const QString&, menu));
+
return result;
}
void MenuScriptingInterface::addSeparator(const QString& menuName, const QString& separatorName) {
- QMetaObject::invokeMethod(Menu::getInstance(), "addSeparator",
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
+ QMetaObject::invokeMethod(menuInstance, "addSeparator",
Q_ARG(const QString&, menuName),
Q_ARG(const QString&, separatorName));
}
void MenuScriptingInterface::removeSeparator(const QString& menuName, const QString& separatorName) {
- QMetaObject::invokeMethod(Menu::getInstance(), "removeSeparator",
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
+ QMetaObject::invokeMethod(menuInstance, "removeSeparator",
Q_ARG(const QString&, menuName),
Q_ARG(const QString&, separatorName));
}
void MenuScriptingInterface::addMenuItem(const MenuItemProperties& properties) {
- QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
+ QMetaObject::invokeMethod(menuInstance, "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
void MenuScriptingInterface::addMenuItem(const QString& menu, const QString& menuitem, const QString& shortcutKey) {
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
MenuItemProperties properties(menu, menuitem, shortcutKey);
- QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
+ QMetaObject::invokeMethod(menuInstance, "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
void MenuScriptingInterface::addMenuItem(const QString& menu, const QString& menuitem) {
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
MenuItemProperties properties(menu, menuitem);
- QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
+ QMetaObject::invokeMethod(menuInstance, "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString& menuitem) {
- QMetaObject::invokeMethod(Menu::getInstance(), "removeMenuItem",
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+ QMetaObject::invokeMethod(menuInstance, "removeMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem));
};
bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString& menuitem) {
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return false;
+ }
+
if (QThread::currentThread() == qApp->thread()) {
- Menu* menuInstance = Menu::getInstance();
return menuInstance && menuInstance->menuItemExists(menu, menuitem);
}
+
bool result { false };
- BLOCKING_INVOKE_METHOD(Menu::getInstance(), "menuItemExists",
+
+ BLOCKING_INVOKE_METHOD(menuInstance, "menuItemExists",
Q_RETURN_ARG(bool, result),
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem));
+
return result;
}
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return false;
+ }
+
if (QThread::currentThread() == qApp->thread()) {
- Menu* menuInstance = Menu::getInstance();
return menuInstance && menuInstance->isOptionChecked(menuOption);
}
+
bool result { false };
- BLOCKING_INVOKE_METHOD(Menu::getInstance(), "isOptionChecked",
+
+ BLOCKING_INVOKE_METHOD(menuInstance, "isOptionChecked",
Q_RETURN_ARG(bool, result),
Q_ARG(const QString&, menuOption));
return result;
}
void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool isChecked) {
- QMetaObject::invokeMethod(Menu::getInstance(), "setIsOptionChecked",
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
+ QMetaObject::invokeMethod(menuInstance, "setIsOptionChecked",
Q_ARG(const QString&, menuOption),
Q_ARG(bool, isChecked));
}
bool MenuScriptingInterface::isMenuEnabled(const QString& menuOption) {
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return false;
+ }
+
if (QThread::currentThread() == qApp->thread()) {
- Menu* menuInstance = Menu::getInstance();
return menuInstance && menuInstance->isMenuEnabled(menuOption);
}
+
bool result { false };
- BLOCKING_INVOKE_METHOD(Menu::getInstance(), "isMenuEnabled",
+
+ BLOCKING_INVOKE_METHOD(menuInstance, "isMenuEnabled",
Q_RETURN_ARG(bool, result),
Q_ARG(const QString&, menuOption));
+
return result;
}
void MenuScriptingInterface::setMenuEnabled(const QString& menuOption, bool isChecked) {
- QMetaObject::invokeMethod(Menu::getInstance(), "setMenuEnabled",
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
+ QMetaObject::invokeMethod(menuInstance, "setMenuEnabled",
Q_ARG(const QString&, menuOption),
Q_ARG(bool, isChecked));
}
void MenuScriptingInterface::triggerOption(const QString& menuOption) {
- QMetaObject::invokeMethod(Menu::getInstance(), "triggerOption", Q_ARG(const QString&, menuOption));
+ Menu* menuInstance = Menu::getInstance();
+ if (!menuInstance) {
+ return;
+ }
+
+ QMetaObject::invokeMethod(menuInstance, "triggerOption", Q_ARG(const QString&, menuOption));
}