mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 15:03:53 +02:00
Merge pull request #4698 from ctrlaltdavid/fps-facetracker
Facetracker FPS refactor
This commit is contained in:
commit
bc8f6708b6
6 changed files with 98 additions and 82 deletions
|
@ -136,9 +136,6 @@ struct Packet {
|
|||
|
||||
const float STARTING_DDE_MESSAGE_TIME = 0.033f;
|
||||
|
||||
const int FPS_TIMER_DELAY = 2000; // ms
|
||||
const int FPS_TIMER_DURATION = 2000; // ms
|
||||
|
||||
DdeFaceTracker::DdeFaceTracker() :
|
||||
DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT)
|
||||
{
|
||||
|
@ -147,6 +144,7 @@ DdeFaceTracker::DdeFaceTracker() :
|
|||
|
||||
DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, quint16 controlPort) :
|
||||
_ddeProcess(NULL),
|
||||
_ddeStopping(false),
|
||||
_host(host),
|
||||
_serverPort(serverPort),
|
||||
_controlPort(controlPort),
|
||||
|
@ -171,9 +169,7 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
|
|||
_lastLeftEyeBlink(0.0f),
|
||||
_filteredLeftEyeBlink(0.0f),
|
||||
_lastRightEyeBlink(0.0f),
|
||||
_filteredRightEyeBlink(0.0f),
|
||||
_isCalculatingFPS(false),
|
||||
_frameCount(0)
|
||||
_filteredRightEyeBlink(0.0f)
|
||||
{
|
||||
_coefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||
|
||||
|
@ -201,46 +197,50 @@ void DdeFaceTracker::setEnabled(bool enabled) {
|
|||
if (enabled && !_ddeProcess) {
|
||||
// Terminate any existing DDE process, perhaps left running after an Interface crash
|
||||
_udpSocket.writeDatagram(DDE_EXIT_COMMAND, DDE_SERVER_ADDR, _controlPort);
|
||||
_ddeStopping = false;
|
||||
|
||||
qDebug() << "[Info] DDE Face Tracker Starting";
|
||||
qCDebug(interfaceapp) << "DDE Face Tracker: Starting";
|
||||
_ddeProcess = new QProcess(qApp);
|
||||
connect(_ddeProcess, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(processFinished(int, QProcess::ExitStatus)));
|
||||
_ddeProcess->start(QCoreApplication::applicationDirPath() + DDE_PROGRAM_PATH, DDE_ARGUMENTS);
|
||||
}
|
||||
|
||||
if (!enabled && _ddeProcess) {
|
||||
_ddeStopping = true;
|
||||
_udpSocket.writeDatagram(DDE_EXIT_COMMAND, DDE_SERVER_ADDR, _controlPort);
|
||||
delete _ddeProcess;
|
||||
_ddeProcess = NULL;
|
||||
qDebug() << "[Info] DDE Face Tracker Stopped";
|
||||
qCDebug(interfaceapp) << "DDE Face Tracker: Stopping";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DdeFaceTracker::processFinished(int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
if (_ddeProcess) {
|
||||
// DDE crashed or was manually terminated
|
||||
qDebug() << "[Info] DDE Face Tracker Stopped Unexpectedly";
|
||||
if (_ddeStopping) {
|
||||
qCDebug(interfaceapp) << "DDE Face Tracker: Stopped";
|
||||
|
||||
} else {
|
||||
qCWarning(interfaceapp) << "DDE Face Tracker: Stopped unexpectedly";
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::NoFaceTracking, true);
|
||||
}
|
||||
_udpSocket.close();
|
||||
delete _ddeProcess;
|
||||
_ddeProcess = NULL;
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::NoFaceTracking, true);
|
||||
}
|
||||
}
|
||||
|
||||
void DdeFaceTracker::reset() {
|
||||
_reset = true;
|
||||
if (_udpSocket.state() == QAbstractSocket::BoundState) {
|
||||
_reset = true;
|
||||
|
||||
qDebug() << "[Info] Reset DDE Tracking";
|
||||
const char* DDE_RESET_COMMAND = "reset";
|
||||
_udpSocket.writeDatagram(DDE_RESET_COMMAND, DDE_SERVER_ADDR, _controlPort);
|
||||
qCDebug(interfaceapp) << "DDE Face Tracker: Reset";
|
||||
|
||||
// Log camera FPS after a reset
|
||||
if (!_isCalculatingFPS) {
|
||||
QTimer::singleShot(FPS_TIMER_DELAY, this, SLOT(startFPSTimer()));
|
||||
_isCalculatingFPS = true;
|
||||
const char* DDE_RESET_COMMAND = "reset";
|
||||
_udpSocket.writeDatagram(DDE_RESET_COMMAND, DDE_SERVER_ADDR, _controlPort);
|
||||
|
||||
FaceTracker::reset();
|
||||
|
||||
_reset = true;
|
||||
}
|
||||
|
||||
_reset = true;
|
||||
}
|
||||
|
||||
bool DdeFaceTracker::isActive() const {
|
||||
|
@ -250,7 +250,7 @@ bool DdeFaceTracker::isActive() const {
|
|||
|
||||
//private slots and methods
|
||||
void DdeFaceTracker::socketErrorOccurred(QAbstractSocket::SocketError socketError) {
|
||||
qCDebug(interfaceapp) << "[Error] DDE Face Tracker Socket Error: " << _udpSocket.errorString();
|
||||
qCWarning(interfaceapp) << "DDE Face Tracker: Socket error: " << _udpSocket.errorString();
|
||||
}
|
||||
|
||||
void DdeFaceTracker::socketStateChanged(QAbstractSocket::SocketState socketState) {
|
||||
|
@ -278,7 +278,7 @@ void DdeFaceTracker::socketStateChanged(QAbstractSocket::SocketState socketState
|
|||
state = "Unconnected";
|
||||
break;
|
||||
}
|
||||
qCDebug(interfaceapp) << "[Info] DDE Face Tracker Socket: " << state;
|
||||
qCDebug(interfaceapp) << "DDE Face Tracker: Socket: " << state;
|
||||
}
|
||||
|
||||
void DdeFaceTracker::readPendingDatagrams() {
|
||||
|
@ -419,23 +419,10 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
|||
}
|
||||
_lastMessageReceived = usecsNow;
|
||||
|
||||
// Count frames if timing
|
||||
if (_isCalculatingFPS) {
|
||||
_frameCount++;
|
||||
}
|
||||
|
||||
FaceTracker::countFrame();
|
||||
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "[Error] DDE Face Tracker Decode Error";
|
||||
qCWarning(interfaceapp) << "DDE Face Tracker: Decode error";
|
||||
}
|
||||
_lastReceiveTimestamp = usecTimestampNow();
|
||||
}
|
||||
|
||||
void DdeFaceTracker::startFPSTimer() {
|
||||
_frameCount = 0;
|
||||
QTimer::singleShot(FPS_TIMER_DURATION, this, SLOT(finishFPSTimer()));
|
||||
}
|
||||
|
||||
void DdeFaceTracker::finishFPSTimer() {
|
||||
qDebug() << "[Info] DDE FPS =" << (float)_frameCount / ((float)FPS_TIMER_DURATION / 1000.0f);
|
||||
_isCalculatingFPS = false;
|
||||
}
|
||||
|
|
|
@ -59,15 +59,13 @@ private slots:
|
|||
void readPendingDatagrams();
|
||||
void socketStateChanged(QAbstractSocket::SocketState socketState);
|
||||
|
||||
void startFPSTimer();
|
||||
void finishFPSTimer();
|
||||
|
||||
private:
|
||||
DdeFaceTracker();
|
||||
DdeFaceTracker(const QHostAddress& host, quint16 serverPort, quint16 controlPort);
|
||||
~DdeFaceTracker();
|
||||
virtual ~DdeFaceTracker();
|
||||
|
||||
QProcess* _ddeProcess;
|
||||
bool _ddeStopping;
|
||||
|
||||
QHostAddress _host;
|
||||
quint16 _serverPort;
|
||||
|
@ -111,9 +109,6 @@ private:
|
|||
float _filteredLeftEyeBlink;
|
||||
float _lastRightEyeBlink;
|
||||
float _filteredRightEyeBlink;
|
||||
|
||||
bool _isCalculatingFPS;
|
||||
int _frameCount;
|
||||
};
|
||||
|
||||
#endif // hifi_DdeFaceTracker_h
|
|
@ -9,9 +9,21 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
#include "FaceTracker.h"
|
||||
#include "InterfaceLogging.h"
|
||||
|
||||
const int FPS_TIMER_DELAY = 2000; // ms
|
||||
const int FPS_TIMER_DURATION = 2000; // ms
|
||||
|
||||
FaceTracker::FaceTracker() :
|
||||
_isCalculatingFPS(false),
|
||||
_frameCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline float FaceTracker::getBlendshapeCoefficient(int index) const {
|
||||
return isValidBlendshapeIndex(index) ? glm::mix(0.0f, _blendshapeCoefficients[index], getFadeCoefficient())
|
||||
|
@ -65,4 +77,27 @@ void FaceTracker::update(float deltaTime) {
|
|||
_relaxationStatus = glm::clamp(_relaxationStatus - deltaTime / RELAXATION_TIME, 0.0f, 1.0f);
|
||||
_fadeCoefficient = std::exp(-(1.0f - _relaxationStatus) * INVERSE_AT_EPSILON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FaceTracker::reset() {
|
||||
if (isActive() && !_isCalculatingFPS) {
|
||||
QTimer::singleShot(FPS_TIMER_DELAY, this, SLOT(startFPSTimer()));
|
||||
_isCalculatingFPS = true;
|
||||
}
|
||||
}
|
||||
|
||||
void FaceTracker::startFPSTimer() {
|
||||
_frameCount = 0;
|
||||
QTimer::singleShot(FPS_TIMER_DURATION, this, SLOT(finishFPSTimer()));
|
||||
}
|
||||
|
||||
void FaceTracker::countFrame() {
|
||||
if (_isCalculatingFPS) {
|
||||
_frameCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void FaceTracker::finishFPSTimer() {
|
||||
qCDebug(interfaceapp) << "Face tracker FPS =" << (float)_frameCount / ((float)FPS_TIMER_DURATION / 1000.0f);
|
||||
_isCalculatingFPS = false;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
|
||||
virtual void init() {}
|
||||
virtual void update(float deltaTime);
|
||||
virtual void reset() {}
|
||||
virtual void reset();
|
||||
|
||||
float getFadeCoefficient() const;
|
||||
|
||||
|
@ -44,6 +44,9 @@ public:
|
|||
float getBlendshapeCoefficient(int index) const;
|
||||
|
||||
protected:
|
||||
FaceTracker();
|
||||
virtual ~FaceTracker() {};
|
||||
|
||||
glm::vec3 _headTranslation = glm::vec3(0.0f);
|
||||
glm::quat _headRotation = glm::quat();
|
||||
float _estimatedEyePitch = 0.0f;
|
||||
|
@ -52,6 +55,16 @@ protected:
|
|||
|
||||
float _relaxationStatus = 0.0f; // Between 0.0f and 1.0f
|
||||
float _fadeCoefficient = 0.0f; // Between 0.0f and 1.0f
|
||||
|
||||
void countFrame();
|
||||
|
||||
private slots:
|
||||
void startFPSTimer();
|
||||
void finishFPSTimer();
|
||||
|
||||
private:
|
||||
bool _isCalculatingFPS;
|
||||
int _frameCount;
|
||||
};
|
||||
|
||||
#endif // hifi_FaceTracker_h
|
||||
|
|
|
@ -30,20 +30,16 @@ const QString DEFAULT_FACESHIFT_HOSTNAME = "localhost";
|
|||
const quint16 FACESHIFT_PORT = 33433;
|
||||
const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f;
|
||||
|
||||
const int FPS_TIMER_DELAY = 2000; // ms
|
||||
const int FPS_TIMER_DURATION = 2000; // ms
|
||||
|
||||
Faceshift::Faceshift() :
|
||||
_eyeDeflection("faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION),
|
||||
_hostname("faceshiftHostname", DEFAULT_FACESHIFT_HOSTNAME),
|
||||
_isCalculatingFPS(false),
|
||||
_frameCount(0)
|
||||
_hostname("faceshiftHostname", DEFAULT_FACESHIFT_HOSTNAME)
|
||||
{
|
||||
#ifdef HAVE_FACESHIFT
|
||||
connect(&_tcpSocket, SIGNAL(connected()), SLOT(noteConnected()));
|
||||
connect(&_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(noteError(QAbstractSocket::SocketError)));
|
||||
connect(&_tcpSocket, SIGNAL(readyRead()), SLOT(readFromSocket()));
|
||||
connect(&_tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), SIGNAL(connectionStateChanged()));
|
||||
connect(&_tcpSocket, SIGNAL(disconnected()), SLOT(noteDisconnected()));
|
||||
|
||||
connect(&_udpSocket, SIGNAL(readyRead()), SLOT(readPendingDatagrams()));
|
||||
|
||||
|
@ -83,15 +79,13 @@ void Faceshift::update(float deltaTime) {
|
|||
|
||||
void Faceshift::reset() {
|
||||
if (_tcpSocket.state() == QAbstractSocket::ConnectedState) {
|
||||
qCDebug(interfaceapp, "Faceshift: Reset");
|
||||
|
||||
FaceTracker::reset();
|
||||
|
||||
string message;
|
||||
fsBinaryStream::encode_message(message, fsMsgCalibrateNeutral());
|
||||
send(message);
|
||||
|
||||
// Log camera FPS after a reset
|
||||
if (!_isCalculatingFPS) {
|
||||
QTimer::singleShot(FPS_TIMER_DELAY, this, SLOT(startFPSTimer()));
|
||||
_isCalculatingFPS = true;
|
||||
}
|
||||
}
|
||||
_longTermAverageInitialized = false;
|
||||
}
|
||||
|
@ -138,6 +132,7 @@ void Faceshift::setTCPEnabled(bool enabled) {
|
|||
if ((_tcpEnabled = enabled)) {
|
||||
connectSocket();
|
||||
} else {
|
||||
qCDebug(interfaceapp, "Faceshift: Disconnecting...");
|
||||
_tcpSocket.disconnectFromHost();
|
||||
}
|
||||
#endif
|
||||
|
@ -156,7 +151,7 @@ void Faceshift::connectSocket() {
|
|||
|
||||
void Faceshift::noteConnected() {
|
||||
#ifdef HAVE_FACESHIFT
|
||||
qCDebug(interfaceapp, "Faceshift: Connected.");
|
||||
qCDebug(interfaceapp, "Faceshift: Connected");
|
||||
// request the list of blendshape names
|
||||
string message;
|
||||
fsBinaryStream::encode_message(message, fsMsgSendBlendshapeNames());
|
||||
|
@ -164,10 +159,16 @@ void Faceshift::noteConnected() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Faceshift::noteDisconnected() {
|
||||
#ifdef HAVE_FACESHIFT
|
||||
qCDebug(interfaceapp, "Faceshift: Disconnected");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Faceshift::noteError(QAbstractSocket::SocketError error) {
|
||||
if (!_tcpRetryCount) {
|
||||
// Only spam log with fail to connect the first time, so that we can keep waiting for server
|
||||
qCDebug(interfaceapp) << "Faceshift: " << _tcpSocket.errorString();
|
||||
qCWarning(interfaceapp) << "Faceshift: " << _tcpSocket.errorString();
|
||||
}
|
||||
// retry connection after a 2 second delay
|
||||
if (_tcpEnabled) {
|
||||
|
@ -294,10 +295,8 @@ void Faceshift::receive(const QByteArray& buffer) {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
// Count frames if timing
|
||||
if (_isCalculatingFPS) {
|
||||
_frameCount++;
|
||||
}
|
||||
|
||||
FaceTracker::countFrame();
|
||||
}
|
||||
|
||||
void Faceshift::setEyeDeflection(float faceshiftEyeDeflection) {
|
||||
|
@ -308,12 +307,3 @@ void Faceshift::setHostname(const QString& hostname) {
|
|||
_hostname.set(hostname);
|
||||
}
|
||||
|
||||
void Faceshift::startFPSTimer() {
|
||||
_frameCount = 0;
|
||||
QTimer::singleShot(FPS_TIMER_DURATION, this, SLOT(finishFPSTimer()));
|
||||
}
|
||||
|
||||
void Faceshift::finishFPSTimer() {
|
||||
qCDebug(interfaceapp) << "Faceshift: FPS =" << (float)_frameCount / ((float)FPS_TIMER_DURATION / 1000.0f);
|
||||
_isCalculatingFPS = false;
|
||||
}
|
||||
|
|
|
@ -95,8 +95,7 @@ private slots:
|
|||
void noteError(QAbstractSocket::SocketError error);
|
||||
void readPendingDatagrams();
|
||||
void readFromSocket();
|
||||
void startFPSTimer();
|
||||
void finishFPSTimer();
|
||||
void noteDisconnected();
|
||||
|
||||
private:
|
||||
Faceshift();
|
||||
|
@ -154,9 +153,6 @@ private:
|
|||
int _mouthSmileRightIndex = 29;
|
||||
|
||||
int _jawOpenIndex = 21;
|
||||
|
||||
bool _isCalculatingFPS;
|
||||
int _frameCount;
|
||||
};
|
||||
|
||||
#endif // hifi_Faceshift_h
|
||||
|
|
Loading…
Reference in a new issue