Update Facetrackers

This commit is contained in:
Atlante45 2015-02-26 19:15:49 +01:00
parent 8eb4abc49c
commit b6968a6b15
6 changed files with 77 additions and 126 deletions

View file

@ -50,6 +50,8 @@ DdeFaceTracker::DdeFaceTracker() :
} }
DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 port) : DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 port) :
_host(host),
_port(port),
_lastReceiveTimestamp(0), _lastReceiveTimestamp(0),
_reset(false), _reset(false),
_leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes _leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes
@ -63,9 +65,7 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 port) :
_browUpRightIndex(18), _browUpRightIndex(18),
_mouthSmileLeftIndex(28), _mouthSmileLeftIndex(28),
_mouthSmileRightIndex(29), _mouthSmileRightIndex(29),
_jawOpenIndex(21), _jawOpenIndex(21)
_host(host),
_port(port)
{ {
_blendshapeCoefficients.resize(NUM_EXPRESSION); _blendshapeCoefficients.resize(NUM_EXPRESSION);
@ -80,18 +80,6 @@ DdeFaceTracker::~DdeFaceTracker() {
} }
} }
void DdeFaceTracker::init() {
}
void DdeFaceTracker::reset() {
_reset = true;
}
void DdeFaceTracker::update() {
}
void DdeFaceTracker::setEnabled(bool enabled) { void DdeFaceTracker::setEnabled(bool enabled) {
// isOpen() does not work as one might expect on QUdpSocket; don't test isOpen() before closing socket. // isOpen() does not work as one might expect on QUdpSocket; don't test isOpen() before closing socket.
_udpSocket.close(); _udpSocket.close();

View file

@ -23,12 +23,10 @@ class DdeFaceTracker : public FaceTracker, public Dependency {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
//initialization virtual void reset() { _reset = true; }
void init();
void reset(); virtual bool isActive() const;
void update(); virtual bool isTracking() const { return isActive(); }
bool isActive() const;
float getLeftBlink() const { return getBlendshapeCoefficient(_leftBlinkIndex); } float getLeftBlink() const { return getBlendshapeCoefficient(_leftBlinkIndex); }
float getRightBlink() const { return getBlendshapeCoefficient(_rightBlinkIndex); } float getRightBlink() const { return getBlendshapeCoefficient(_rightBlinkIndex); }

View file

@ -25,37 +25,11 @@ using namespace fs;
using namespace std; using namespace std;
const QString DEFAULT_FACESHIFT_HOSTNAME = "localhost";
const quint16 FACESHIFT_PORT = 33433; const quint16 FACESHIFT_PORT = 33433;
float STARTING_FACESHIFT_FRAME_TIME = 0.033f; const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f;
Faceshift::Faceshift() : Faceshift::Faceshift() :
_tcpEnabled(true),
_tcpRetryCount(0),
_lastTrackingStateReceived(0),
_averageFrameTime(STARTING_FACESHIFT_FRAME_TIME),
_headAngularVelocity(0),
_headLinearVelocity(0),
_lastHeadTranslation(0),
_filteredHeadTranslation(0),
_eyeGazeLeftPitch(0.0f),
_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),
_eyeDeflection("faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION), _eyeDeflection("faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION),
_hostname("faceshiftHostname", DEFAULT_FACESHIFT_HOSTNAME) _hostname("faceshiftHostname", DEFAULT_FACESHIFT_HOSTNAME)
{ {
@ -71,31 +45,15 @@ Faceshift::Faceshift() :
#endif #endif
} }
#ifdef HAVE_FACESHIFT
void Faceshift::init() { void Faceshift::init() {
#ifdef HAVE_FACESHIFT
setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)); setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift));
#endif
} }
bool Faceshift::isConnectedOrConnecting() const { void Faceshift::update(float deltaTime) {
return _tcpSocket.state() == QAbstractSocket::ConnectedState ||
(_tcpRetryCount == 0 && _tcpSocket.state() != QAbstractSocket::UnconnectedState);
}
bool Faceshift::isActive() const {
#ifdef HAVE_FACESHIFT
const quint64 ACTIVE_TIMEOUT_USECS = 1000000;
return (usecTimestampNow() - _lastTrackingStateReceived) < ACTIVE_TIMEOUT_USECS;
#else
return false;
#endif
}
void Faceshift::update() {
if (!isActive()) { if (!isActive()) {
return; return;
} }
PerformanceTimer perfTimer("faceshift");
// get the euler angles relative to the window // get the euler angles relative to the window
glm::vec3 eulers = glm::degrees(safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3( glm::vec3 eulers = glm::degrees(safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3(
(_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f, (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f, 0.0f))))); (_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f, (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f, 0.0f)))));
@ -116,14 +74,28 @@ void Faceshift::update() {
} }
void Faceshift::reset() { void Faceshift::reset() {
#ifdef HAVE_FACESHIFT
if (_tcpSocket.state() == QAbstractSocket::ConnectedState) { if (_tcpSocket.state() == QAbstractSocket::ConnectedState) {
string message; string message;
fsBinaryStream::encode_message(message, fsMsgCalibrateNeutral()); fsBinaryStream::encode_message(message, fsMsgCalibrateNeutral());
send(message); send(message);
} }
_longTermAverageInitialized = false; _longTermAverageInitialized = false;
}
bool Faceshift::isActive() const {
const quint64 ACTIVE_TIMEOUT_USECS = 1000000;
return (usecTimestampNow() - _lastTrackingStateReceived) < ACTIVE_TIMEOUT_USECS;
}
bool Faceshift::isTracking() const {
return isActive() && _tracking;
}
#endif #endif
bool Faceshift::isConnectedOrConnecting() const {
return _tcpSocket.state() == QAbstractSocket::ConnectedState ||
(_tcpRetryCount == 0 && _tcpSocket.state() != QAbstractSocket::UnconnectedState);
} }
void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp, void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp,
@ -148,12 +120,13 @@ void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float
} }
void Faceshift::setTCPEnabled(bool enabled) { void Faceshift::setTCPEnabled(bool enabled) {
#ifdef HAVE_FACESHIFT
if ((_tcpEnabled = enabled)) { if ((_tcpEnabled = enabled)) {
connectSocket(); connectSocket();
} else { } else {
_tcpSocket.disconnectFromHost(); _tcpSocket.disconnectFromHost();
} }
#endif
} }
void Faceshift::connectSocket() { void Faceshift::connectSocket() {
@ -202,10 +175,6 @@ void Faceshift::readFromSocket() {
receive(_tcpSocket.readAll()); receive(_tcpSocket.readAll());
} }
float Faceshift::getBlendshapeCoefficient(int index) const {
return (index >= 0 && index < (int)_blendshapeCoefficients.size()) ? _blendshapeCoefficients[index] : 0.0f;
}
void Faceshift::send(const std::string& message) { void Faceshift::send(const std::string& message) {
_tcpSocket.write(message.data(), message.size()); _tcpSocket.write(message.data(), message.size());
} }

View file

@ -24,8 +24,7 @@
#include "FaceTracker.h" #include "FaceTracker.h"
const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f; const float STARTING_FACESHIFT_FRAME_TIME = 0.033f;
const QString DEFAULT_FACESHIFT_HOSTNAME = "localhost";
/// Handles interaction with the Faceshift software, which provides head position/orientation and facial features. /// Handles interaction with the Faceshift software, which provides head position/orientation and facial features.
class Faceshift : public FaceTracker, public Dependency { class Faceshift : public FaceTracker, public Dependency {
@ -33,11 +32,17 @@ class Faceshift : public FaceTracker, public Dependency {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
void init(); #ifdef HAVE_FACESHIFT
// If we don't have faceshift, use the base class' methods
virtual void init();
virtual void update(float deltaTime);
virtual void reset();
bool isConnectedOrConnecting() const; virtual bool isActive() const;
virtual bool isTracking() const;
#endif
bool isActive() const; bool isConnectedOrConnecting() const;
const glm::vec3& getHeadAngularVelocity() const { return _headAngularVelocity; } const glm::vec3& getHeadAngularVelocity() const { return _headAngularVelocity; }
@ -68,9 +73,6 @@ public:
QString getHostname() { return _hostname.get(); } QString getHostname() { return _hostname.get(); }
void setHostname(const QString& hostname); void setHostname(const QString& hostname);
void update();
void reset();
void updateFakeCoefficients(float leftBlink, void updateFakeCoefficients(float leftBlink,
float rightBlink, float rightBlink,
@ -82,15 +84,12 @@ public:
QVector<float>& coefficients) const; QVector<float>& coefficients) const;
signals: signals:
void connectionStateChanged(); void connectionStateChanged();
public slots: public slots:
void setTCPEnabled(bool enabled); void setTCPEnabled(bool enabled);
private slots: private slots:
void connectSocket(); void connectSocket();
void noteConnected(); void noteConnected();
void noteError(QAbstractSocket::SocketError error); void noteError(QAbstractSocket::SocketError error);
@ -101,8 +100,6 @@ private:
Faceshift(); Faceshift();
virtual ~Faceshift() {} virtual ~Faceshift() {}
float getBlendshapeCoefficient(int index) const;
void send(const std::string& message); void send(const std::string& message);
void receive(const QByteArray& buffer); void receive(const QByteArray& buffer);
@ -113,48 +110,48 @@ private:
fs::fsBinaryStream _stream; fs::fsBinaryStream _stream;
#endif #endif
bool _tcpEnabled; bool _tcpEnabled = true;
int _tcpRetryCount; int _tcpRetryCount = 0;
bool _tracking; bool _tracking = false;
quint64 _lastTrackingStateReceived; quint64 _lastTrackingStateReceived = 0;
float _averageFrameTime; float _averageFrameTime = STARTING_FACESHIFT_FRAME_TIME;
glm::vec3 _headAngularVelocity; glm::vec3 _headAngularVelocity = glm::vec3(0.0f);
glm::vec3 _headLinearVelocity; glm::vec3 _headLinearVelocity = glm::vec3(0.0f);
glm::vec3 _lastHeadTranslation; glm::vec3 _lastHeadTranslation = glm::vec3(0.0f);
glm::vec3 _filteredHeadTranslation; glm::vec3 _filteredHeadTranslation = glm::vec3(0.0f);
// degrees // degrees
float _eyeGazeLeftPitch; float _eyeGazeLeftPitch = 0.0f;
float _eyeGazeLeftYaw; float _eyeGazeLeftYaw = 0.0f;
float _eyeGazeRightPitch; float _eyeGazeRightPitch = 0.0f;
float _eyeGazeRightYaw; float _eyeGazeRightYaw = 0.0f;
int _leftBlinkIndex;
int _rightBlinkIndex;
int _leftEyeOpenIndex;
int _rightEyeOpenIndex;
// Brows
int _browDownLeftIndex;
int _browDownRightIndex;
int _browUpCenterIndex;
int _browUpLeftIndex;
int _browUpRightIndex;
int _mouthSmileLeftIndex;
int _mouthSmileRightIndex;
int _jawOpenIndex;
// degrees // degrees
float _longTermAverageEyePitch; float _longTermAverageEyePitch = 0.0f;
float _longTermAverageEyeYaw; float _longTermAverageEyeYaw = 0.0f;
bool _longTermAverageInitialized; bool _longTermAverageInitialized = false;
Setting::Handle<float> _eyeDeflection; Setting::Handle<float> _eyeDeflection;
Setting::Handle<QString> _hostname; Setting::Handle<QString> _hostname;
// see http://support.faceshift.com/support/articles/35129-export-of-blendshapes
int _leftBlinkIndex = 0;
int _rightBlinkIndex = 1;
int _leftEyeOpenIndex = 8;
int _rightEyeOpenIndex = 9;
// Brows
int _browDownLeftIndex = 14;
int _browDownRightIndex = 15;
int _browUpCenterIndex = 16;
int _browUpLeftIndex = 17;
int _browUpRightIndex = 18;
int _mouthSmileLeftIndex = 28;
int _mouthSmileRightIndex = 29;
int _jawOpenIndex = 21;
}; };
#endif // hifi_Faceshift_h #endif // hifi_Faceshift_h

View file

@ -126,13 +126,12 @@ void Visage::init() {
updateEnabled(); updateEnabled();
} }
void Visage::update() { void Visage::update(float deltaTime) {
#ifdef HAVE_VISAGE #ifdef HAVE_VISAGE
_active = (_tracker->getTrackingData(_data) == TRACK_STAT_OK); _active = (_tracker->getTrackingData(_data) == TRACK_STAT_OK);
if (!_active) { if (!_active) {
return; return;
} }
PerformanceTimer perfTimer("visage");
_headRotation = glm::quat(glm::vec3(-_data->faceRotation[0], -_data->faceRotation[1], _data->faceRotation[2])); _headRotation = glm::quat(glm::vec3(-_data->faceRotation[0], -_data->faceRotation[1], _data->faceRotation[2]));
_headTranslation = (glm::vec3(_data->faceTranslation[0], _data->faceTranslation[1], _data->faceTranslation[2]) - _headTranslation = (glm::vec3(_data->faceTranslation[0], _data->faceTranslation[1], _data->faceTranslation[2]) -
_headOrigin) * TRANSLATION_SCALE; _headOrigin) * TRANSLATION_SCALE;

View file

@ -31,12 +31,12 @@ class Visage : public FaceTracker, public Dependency {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
void init(); virtual void init();
virtual void update(float deltaTime);
virtual void reset();
bool isActive() const { return _active; } virtual bool isActive() const { return _active; }
virtual bool isTracking() const { return isActive(); }
void update();
void reset();
public slots: public slots: