From fc9fb11e4f6039f5c70bf0e00de2f4c82984929f Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Tue, 22 Jul 2014 11:56:19 -0700 Subject: [PATCH] Added FacialAnimationData class --- examples/bot.js | 2 +- interface/src/devices/Faceshift.cpp | 50 ++++++-------- interface/src/devices/Faceshift.h | 43 +++++------- .../animation/src/FacialAnimationData.cpp | 30 +++++++++ libraries/animation/src/FacialAnimationData.h | 65 +++++++++++++++++++ 5 files changed, 130 insertions(+), 60 deletions(-) create mode 100644 libraries/animation/src/FacialAnimationData.cpp create mode 100644 libraries/animation/src/FacialAnimationData.h diff --git a/examples/bot.js b/examples/bot.js index e42d234abf..edef280e21 100644 --- a/examples/bot.js +++ b/examples/bot.js @@ -92,7 +92,7 @@ function playRandomSound() { botNumber = getRandomInt(1, 100); if (botNumber <= 20) { - newFaceFilePrefix = "bot" + botNumber; + newFaceFilePrefix = "amber"; newBodyFilePrefix = "defaultAvatar_body" } else { if (botNumber <= 40) { diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp index a7d50814e2..4105b17652 100644 --- a/interface/src/devices/Faceshift.cpp +++ b/interface/src/devices/Faceshift.cpp @@ -32,18 +32,6 @@ Faceshift::Faceshift() : _eyeGazeLeftYaw(0.0f), _eyeGazeRightPitch(0.0f), _eyeGazeRightYaw(0.0f), - _leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes - _rightBlinkIndex(1), - _leftEyeOpenIndex(8), - _rightEyeOpenIndex(9), - _browDownLeftIndex(14), - _browDownRightIndex(15), - _browUpCenterIndex(16), - _browUpLeftIndex(17), - _browUpRightIndex(18), - _mouthSmileLeftIndex(28), - _mouthSmileRightIndex(29), - _jawOpenIndex(21), _longTermAverageEyePitch(0.0f), _longTermAverageEyeYaw(0.0f), _longTermAverageInitialized(false) @@ -107,14 +95,14 @@ void Faceshift::reset() { void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp, float jawOpen, QVector& coefficients) const { - coefficients.resize(max((int)coefficients.size(), _jawOpenIndex + 1)); + coefficients.resize(max((int)coefficients.size(), _facialAnimationData._jawOpenIndex + 1)); qFill(coefficients.begin(), coefficients.end(), 0.0f); - coefficients[_leftBlinkIndex] = leftBlink; - coefficients[_rightBlinkIndex] = rightBlink; - coefficients[_browUpCenterIndex] = browUp; - coefficients[_browUpLeftIndex] = browUp; - coefficients[_browUpRightIndex] = browUp; - coefficients[_jawOpenIndex] = jawOpen; + coefficients[_facialAnimationData._leftBlinkIndex] = leftBlink; + coefficients[_facialAnimationData._rightBlinkIndex] = rightBlink; + coefficients[_facialAnimationData._browUpCenterIndex] = browUp; + coefficients[_facialAnimationData._browUpLeftIndex] = browUp; + coefficients[_facialAnimationData._browUpRightIndex] = browUp; + coefficients[_facialAnimationData._jawOpenIndex] = jawOpen; } void Faceshift::setTCPEnabled(bool enabled) { @@ -217,40 +205,40 @@ void Faceshift::receive(const QByteArray& buffer) { const vector& names = static_cast(msg.get())->blendshape_names(); for (size_t i = 0; i < names.size(); i++) { if (names[i] == "EyeBlink_L") { - _leftBlinkIndex = i; + _facialAnimationData._leftBlinkIndex = i; } else if (names[i] == "EyeBlink_R") { - _rightBlinkIndex = i; + _facialAnimationData._rightBlinkIndex = i; } else if (names[i] == "EyeOpen_L") { - _leftEyeOpenIndex = i; + _facialAnimationData._leftEyeOpenIndex = i; } else if (names[i] == "EyeOpen_R") { - _rightEyeOpenIndex = i; + _facialAnimationData._rightEyeOpenIndex = i; } else if (names[i] == "BrowsD_L") { - _browDownLeftIndex = i; + _facialAnimationData._browDownLeftIndex = i; } else if (names[i] == "BrowsD_R") { - _browDownRightIndex = i; + _facialAnimationData._browDownRightIndex = i; } else if (names[i] == "BrowsU_C") { - _browUpCenterIndex = i; + _facialAnimationData._browUpCenterIndex = i; } else if (names[i] == "BrowsU_L") { - _browUpLeftIndex = i; + _facialAnimationData._browUpLeftIndex = i; } else if (names[i] == "BrowsU_R") { - _browUpRightIndex = i; + _facialAnimationData._browUpRightIndex = i; } else if (names[i] == "JawOpen") { - _jawOpenIndex = i; + _facialAnimationData._jawOpenIndex = i; } else if (names[i] == "MouthSmile_L") { - _mouthSmileLeftIndex = i; + _facialAnimationData._mouthSmileLeftIndex = i; } else if (names[i] == "MouthSmile_R") { - _mouthSmileRightIndex = i; + _facialAnimationData._mouthSmileRightIndex = i; } } break; diff --git a/interface/src/devices/Faceshift.h b/interface/src/devices/Faceshift.h index 2fc1aaddb1..87fd1076ee 100644 --- a/interface/src/devices/Faceshift.h +++ b/interface/src/devices/Faceshift.h @@ -18,6 +18,7 @@ #include #include "FaceTracker.h" +#include "FacialAnimationData.h" /// Handles interaction with the Faceshift software, which provides head position/orientation and facial features. class Faceshift : public FaceTracker { @@ -42,20 +43,20 @@ public: float getEyeGazeRightPitch() const { return _eyeGazeRightPitch; } float getEyeGazeRightYaw() const { return _eyeGazeRightYaw; } - float getLeftBlink() const { return getBlendshapeCoefficient(_leftBlinkIndex); } - float getRightBlink() const { return getBlendshapeCoefficient(_rightBlinkIndex); } - float getLeftEyeOpen() const { return getBlendshapeCoefficient(_leftEyeOpenIndex); } - float getRightEyeOpen() const { return getBlendshapeCoefficient(_rightEyeOpenIndex); } + float getLeftBlink() const { return getBlendshapeCoefficient(_facialAnimationData._leftBlinkIndex); } + float getRightBlink() const { return getBlendshapeCoefficient(_facialAnimationData._rightBlinkIndex); } + float getLeftEyeOpen() const { return getBlendshapeCoefficient(_facialAnimationData._leftEyeOpenIndex); } + float getRightEyeOpen() const { return getBlendshapeCoefficient(_facialAnimationData._rightEyeOpenIndex); } - float getBrowDownLeft() const { return getBlendshapeCoefficient(_browDownLeftIndex); } - float getBrowDownRight() const { return getBlendshapeCoefficient(_browDownRightIndex); } - float getBrowUpCenter() const { return getBlendshapeCoefficient(_browUpCenterIndex); } - float getBrowUpLeft() const { return getBlendshapeCoefficient(_browUpLeftIndex); } - float getBrowUpRight() const { return getBlendshapeCoefficient(_browUpRightIndex); } + float getBrowDownLeft() const { return getBlendshapeCoefficient(_facialAnimationData._browDownLeftIndex); } + float getBrowDownRight() const { return getBlendshapeCoefficient(_facialAnimationData._browDownRightIndex); } + float getBrowUpCenter() const { return getBlendshapeCoefficient(_facialAnimationData._browUpCenterIndex); } + float getBrowUpLeft() const { return getBlendshapeCoefficient(_facialAnimationData._browUpLeftIndex); } + float getBrowUpRight() const { return getBlendshapeCoefficient(_facialAnimationData._browUpRightIndex); } - float getMouthSize() const { return getBlendshapeCoefficient(_jawOpenIndex); } - float getMouthSmileLeft() const { return getBlendshapeCoefficient(_mouthSmileLeftIndex); } - float getMouthSmileRight() const { return getBlendshapeCoefficient(_mouthSmileRightIndex); } + float getMouthSize() const { return getBlendshapeCoefficient(_facialAnimationData._jawOpenIndex); } + float getMouthSmileLeft() const { return getBlendshapeCoefficient(_facialAnimationData._mouthSmileLeftIndex); } + float getMouthSmileRight() const { return getBlendshapeCoefficient(_facialAnimationData._mouthSmileRightIndex); } void update(); void reset(); @@ -102,23 +103,9 @@ private: float _eyeGazeRightPitch; float _eyeGazeRightYaw; - int _leftBlinkIndex; - int _rightBlinkIndex; - int _leftEyeOpenIndex; - int _rightEyeOpenIndex; + // stores blendshape indexes + FacialAnimationData _facialAnimationData; - // Brows - int _browDownLeftIndex; - int _browDownRightIndex; - int _browUpCenterIndex; - int _browUpLeftIndex; - int _browUpRightIndex; - - int _mouthSmileLeftIndex; - int _mouthSmileRightIndex; - - int _jawOpenIndex; - // degrees float _longTermAverageEyePitch; float _longTermAverageEyeYaw; diff --git a/libraries/animation/src/FacialAnimationData.cpp b/libraries/animation/src/FacialAnimationData.cpp new file mode 100644 index 0000000000..0f45675083 --- /dev/null +++ b/libraries/animation/src/FacialAnimationData.cpp @@ -0,0 +1,30 @@ +// +// FacialAnimationData.cpp +// interface/src/devices +// +// Created by Ben Arnold on 7/21/2014. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "FacialAnimationData.h" + +FacialAnimationData::FacialAnimationData() :_leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes +_rightBlinkIndex(1), +_leftEyeOpenIndex(8), +_rightEyeOpenIndex(9), +_browDownLeftIndex(14), +_browDownRightIndex(15), +_browUpCenterIndex(16), +_browUpLeftIndex(17), +_browUpRightIndex(18), +_mouthSmileLeftIndex(28), +_mouthSmileRightIndex(29), +_jawOpenIndex(21) { +} + +float FacialAnimationData::getBlendshapeCoefficient(int index) const { + return (index >= 0 && index < (int)_blendshapeCoefficients.size()) ? _blendshapeCoefficients[index] : 0.0f; +} \ No newline at end of file diff --git a/libraries/animation/src/FacialAnimationData.h b/libraries/animation/src/FacialAnimationData.h new file mode 100644 index 0000000000..c8d740c1c9 --- /dev/null +++ b/libraries/animation/src/FacialAnimationData.h @@ -0,0 +1,65 @@ +// +// FacialAnimationData.h +// interface/src/devices +// +// Created by Ben Arnold on 7/21/2014. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_FacialAnimationData_h +#define hifi_FacialAnimationData_h + +#include +#include + +/// Stores facial animation data for use by faceshift or scripts +class FacialAnimationData : public QObject { + Q_OBJECT + +public: + friend class Faceshift; + + FacialAnimationData(); + + float getLeftBlink() const { return getBlendshapeCoefficient(_leftBlinkIndex); } + float getRightBlink() const { return getBlendshapeCoefficient(_rightBlinkIndex); } + float getLeftEyeOpen() const { return getBlendshapeCoefficient(_leftEyeOpenIndex); } + float getRightEyeOpen() const { return getBlendshapeCoefficient(_rightEyeOpenIndex); } + + float getBrowDownLeft() const { return getBlendshapeCoefficient(_browDownLeftIndex); } + float getBrowDownRight() const { return getBlendshapeCoefficient(_browDownRightIndex); } + float getBrowUpCenter() const { return getBlendshapeCoefficient(_browUpCenterIndex); } + float getBrowUpLeft() const { return getBlendshapeCoefficient(_browUpLeftIndex); } + float getBrowUpRight() const { return getBlendshapeCoefficient(_browUpRightIndex); } + + float getMouthSize() const { return getBlendshapeCoefficient(_jawOpenIndex); } + float getMouthSmileLeft() const { return getBlendshapeCoefficient(_mouthSmileLeftIndex); } + float getMouthSmileRight() const { return getBlendshapeCoefficient(_mouthSmileRightIndex); } + +private: + float getBlendshapeCoefficient(int index) const; + + int _leftBlinkIndex; + int _rightBlinkIndex; + int _leftEyeOpenIndex; + int _rightEyeOpenIndex; + + int _browDownLeftIndex; + int _browDownRightIndex; + int _browUpCenterIndex; + int _browUpLeftIndex; + int _browUpRightIndex; + + int _mouthSmileLeftIndex; + int _mouthSmileRightIndex; + + int _jawOpenIndex; + + //Only used by agents, since FaceTracker has its own _blendshapeCoefficients; + QVector _blendshapeCoefficients; +}; + +#endif // hifi_FacialAnimationData_h \ No newline at end of file