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