mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 12:37:51 +02:00
Start eye tracker streaming such that don't block Interface
Start method is called in a separate thread.
This commit is contained in:
parent
8e93ee654e
commit
8b326414ac
3 changed files with 77 additions and 33 deletions
|
@ -2050,10 +2050,7 @@ void Application::setActiveEyeTracker() {
|
||||||
bool isEyeTracking = Menu::getInstance()->isOptionChecked(MenuOption::SMIEyeTracking);
|
bool isEyeTracking = Menu::getInstance()->isOptionChecked(MenuOption::SMIEyeTracking);
|
||||||
bool isSimulating = Menu::getInstance()->isOptionChecked(MenuOption::SimulateEyeTracking);
|
bool isSimulating = Menu::getInstance()->isOptionChecked(MenuOption::SimulateEyeTracking);
|
||||||
eyeTracker->setEnabled(isEyeTracking, isSimulating);
|
eyeTracker->setEnabled(isEyeTracking, isSimulating);
|
||||||
if (isEyeTracking && !eyeTracker->isEnabled()) {
|
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::SMIEyeTracking, false);
|
|
||||||
isEyeTracking = false;
|
|
||||||
}
|
|
||||||
Menu::getInstance()->getActionForOption(MenuOption::OnePointCalibration)->setEnabled(isEyeTracking && !isSimulating);
|
Menu::getInstance()->getActionForOption(MenuOption::OnePointCalibration)->setEnabled(isEyeTracking && !isSimulating);
|
||||||
Menu::getInstance()->getActionForOption(MenuOption::ThreePointCalibration)->setEnabled(isEyeTracking && !isSimulating);
|
Menu::getInstance()->getActionForOption(MenuOption::ThreePointCalibration)->setEnabled(isEyeTracking && !isSimulating);
|
||||||
Menu::getInstance()->getActionForOption(MenuOption::FivePointCalibration)->setEnabled(isEyeTracking && !isSimulating);
|
Menu::getInstance()->getActionForOption(MenuOption::FivePointCalibration)->setEnabled(isEyeTracking && !isSimulating);
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
|
|
||||||
#include "EyeTracker.h"
|
#include "EyeTracker.h"
|
||||||
|
|
||||||
|
#include <QFuture>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QtConcurrent\QtConcurrentRun>
|
||||||
|
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
@ -125,29 +127,30 @@ void EyeTracker::init() {
|
||||||
} else {
|
} else {
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect(&_startStreamingWatcher, SIGNAL(finished()), this, SLOT(onStreamStarted()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void EyeTracker::setEnabled(bool enabled, bool simulate) {
|
#ifdef HAVE_IVIEWHMD
|
||||||
if (!_isInitialized) {
|
int EyeTracker::startStreaming(bool simulate) {
|
||||||
return;
|
return smi_startStreaming(simulate); // This call blocks execution.
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IVIEWHMD
|
#ifdef HAVE_IVIEWHMD
|
||||||
qCDebug(interfaceapp) << "Eye Tracker: Set enabled =" << enabled << ", simulate =" << simulate;
|
void EyeTracker::onStreamStarted() {
|
||||||
if (enabled && !_isStreaming) {
|
int result = _startStreamingWatcher.result();
|
||||||
// There is no smi_stopStreaming() method so keep streaming once started in case tracking is re-enabled after stopping.
|
_isStreaming = (result == SMI_RET_SUCCESS);
|
||||||
int result = smi_startStreaming(simulate);
|
|
||||||
if (result != SMI_RET_SUCCESS) {
|
if (result != SMI_RET_SUCCESS) {
|
||||||
qCWarning(interfaceapp) << "Eye Tracker: Error starting streaming:" << smiReturnValueToString(result);
|
qCWarning(interfaceapp) << "Eye Tracker: Error starting streaming:" << smiReturnValueToString(result);
|
||||||
// Display error dialog except if SMI SDK has already displayed an error message.
|
// Display error dialog unless SMI SDK has already displayed an error message.
|
||||||
if (result != SMI_ERROR_HMD_NOT_SUPPORTED) {
|
if (result != SMI_ERROR_HMD_NOT_SUPPORTED) {
|
||||||
QMessageBox::warning(nullptr, "Eye Tracker Error", smiReturnValueToString(result));
|
QMessageBox::warning(nullptr, "Eye Tracker Error", smiReturnValueToString(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_isStreaming = (result == SMI_RET_SUCCESS);
|
|
||||||
|
|
||||||
if (_isStreaming) {
|
if (_isStreaming) {
|
||||||
// Automatically load calibration if one has been saved.
|
// Automatically load calibration if one has been saved.
|
||||||
QString availableCalibrations = QString(smi_getAvailableCalibrations());
|
QString availableCalibrations = QString(smi_getAvailableCalibrations());
|
||||||
|
@ -162,10 +165,39 @@ void EyeTracker::setEnabled(bool enabled, bool simulate) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void EyeTracker::setEnabled(bool enabled, bool simulate) {
|
||||||
|
if (!_isInitialized) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_isEnabled = enabled && _isStreaming;
|
#ifdef HAVE_IVIEWHMD
|
||||||
_isSimulating = _isEnabled && simulate;
|
qCDebug(interfaceapp) << "Eye Tracker: Set enabled =" << enabled << ", simulate =" << simulate;
|
||||||
|
|
||||||
|
// There is no smi_stopStreaming() method and after an smi_quit(), streaming cannot be restarted (at least not for
|
||||||
|
// simulated data). So keep streaming once started in case tracking is re-enabled after stopping.
|
||||||
|
|
||||||
|
// Try to stop streaming if changing whether simulating or not.
|
||||||
|
if (enabled && _isStreaming && _isStreamSimulating != simulate) {
|
||||||
|
int result = smi_quit();
|
||||||
|
if (result != SMI_RET_SUCCESS) {
|
||||||
|
qCWarning(interfaceapp) << "Eye Tracker: Error stopping streaming:" << smiReturnValueToString(result);
|
||||||
|
}
|
||||||
|
_isStreaming = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled && !_isStreaming) {
|
||||||
|
// Start SMI streaming in a separate thread because it blocks.
|
||||||
|
QFuture<int> future = QtConcurrent::run(this, &EyeTracker::startStreaming, simulate);
|
||||||
|
_startStreamingWatcher.setFuture(future);
|
||||||
|
_isStreamSimulating = simulate;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isEnabled = enabled;
|
||||||
|
_isSimulating = simulate;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,11 +207,17 @@ void EyeTracker::reset() {
|
||||||
|
|
||||||
bool EyeTracker::isTracking() const {
|
bool EyeTracker::isTracking() const {
|
||||||
static const quint64 ACTIVE_TIMEOUT_USECS = 2000000; // 2 secs
|
static const quint64 ACTIVE_TIMEOUT_USECS = 2000000; // 2 secs
|
||||||
return (usecTimestampNow() - _lastProcessDataTimestamp < ACTIVE_TIMEOUT_USECS);
|
return _isEnabled && (usecTimestampNow() - _lastProcessDataTimestamp < ACTIVE_TIMEOUT_USECS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IVIEWHMD
|
#ifdef HAVE_IVIEWHMD
|
||||||
void EyeTracker::calibrate(int points) {
|
void EyeTracker::calibrate(int points) {
|
||||||
|
|
||||||
|
if (!_isStreaming) {
|
||||||
|
qCWarning(interfaceapp) << "Eye Tracker: Cannot calibrate because not streaming";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
smi_CalibrationHMDStruct* calibrationHMDStruct;
|
smi_CalibrationHMDStruct* calibrationHMDStruct;
|
||||||
smi_createCalibrationHMDStruct(&calibrationHMDStruct);
|
smi_createCalibrationHMDStruct(&calibrationHMDStruct);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define hifi_EyeTracker_h
|
#define hifi_EyeTracker_h
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
@ -44,19 +45,27 @@ public:
|
||||||
void processData(smi_CallbackDataStruct* data);
|
void processData(smi_CallbackDataStruct* data);
|
||||||
|
|
||||||
void calibrate(int points);
|
void calibrate(int points);
|
||||||
|
|
||||||
|
int startStreaming(bool simulate);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onStreamStarted();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString smiReturnValueToString(int value);
|
QString smiReturnValueToString(int value);
|
||||||
|
|
||||||
bool _isInitialized = false;
|
bool _isInitialized = false;
|
||||||
bool _isStreaming = false;
|
|
||||||
bool _isEnabled = false;
|
bool _isEnabled = false;
|
||||||
bool _isSimulating = false;
|
bool _isSimulating = false;
|
||||||
|
bool _isStreaming = false;
|
||||||
|
bool _isStreamSimulating = false;
|
||||||
|
|
||||||
quint64 _lastProcessDataTimestamp;
|
quint64 _lastProcessDataTimestamp;
|
||||||
|
|
||||||
glm::vec3 _lookAtPosition;
|
glm::vec3 _lookAtPosition;
|
||||||
|
|
||||||
|
QFutureWatcher<int> _startStreamingWatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EyeTracker_h
|
#endif // hifi_EyeTracker_h
|
||||||
|
|
Loading…
Reference in a new issue