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