From d053379831d2b9a31f9e80131ed95886a83b1d4d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 29 Apr 2015 21:23:47 -0700 Subject: [PATCH 01/10] Add "Mute Face Tracking" menu item --- interface/src/Application.cpp | 42 ++++++++++++++++++------ interface/src/Application.h | 2 ++ interface/src/Menu.cpp | 6 ++++ interface/src/Menu.h | 1 + interface/src/avatar/Head.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/devices/DdeFaceTracker.cpp | 11 +++++-- interface/src/devices/FaceTracker.cpp | 13 +++++++- interface/src/devices/FaceTracker.h | 11 ++++++- interface/src/devices/Faceshift.cpp | 15 ++++++--- interface/src/devices/Faceshift.h | 3 +- tests/ui/src/main.cpp | 1 + 12 files changed, 87 insertions(+), 22 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d0d01f4534..80231d6342 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -585,6 +585,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // The offscreen UI needs to intercept the mouse and keyboard // events coming from the onscreen window _glWidget->installEventFilter(DependencyManager::get().data()); + + // initialize our face trackers after loading the menu settings + auto faceshiftTracker = DependencyManager::get(); + faceshiftTracker->init(); + connect(faceshiftTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled); + auto ddeTracker = DependencyManager::get(); + ddeTracker->init(); + connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled); } @@ -911,6 +919,12 @@ void Application::audioMuteToggled() { muteAction->setChecked(DependencyManager::get()->isMuted()); } +void Application::faceTrackerMuteToggled() { + QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking); + Q_CHECK_PTR(muteAction); + muteAction->setChecked(getActiveFaceTracker()->isMuted()); +} + void Application::aboutApp() { InfoView::forcedShow(INFO_HELP_PATH); } @@ -1889,17 +1903,29 @@ FaceTracker* Application::getActiveFaceTracker() { } void Application::setActiveFaceTracker() { + bool isMuted = Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking); #ifdef HAVE_FACESHIFT - DependencyManager::get()->setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)); + auto faceshiftTracker = DependencyManager::get(); + faceshiftTracker->setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)); + faceshiftTracker->setIsMuted(isMuted); #endif #ifdef HAVE_DDE bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::UseCamera); Menu::getInstance()->getActionForOption(MenuOption::UseAudioForMouth)->setVisible(isUsingDDE); Menu::getInstance()->getActionForOption(MenuOption::VelocityFilter)->setVisible(isUsingDDE); - DependencyManager::get()->setEnabled(isUsingDDE); + auto ddeTracker = DependencyManager::get(); + ddeTracker->setEnabled(isUsingDDE); + ddeTracker->setIsMuted(isMuted); #endif } +void Application::toggleFaceTrackerMute() { + FaceTracker* faceTracker = getActiveFaceTracker(); + if (faceTracker) { + faceTracker->toggleMute(); + } +} + bool Application::exportEntities(const QString& filename, const QVector& entityIDs) { QVector entities; @@ -2068,10 +2094,6 @@ void Application::init() { SixenseManager::getInstance().toggleSixense(true); #endif - // initialize our face trackers after loading the menu settings - DependencyManager::get()->init(); - DependencyManager::get()->init(); - Leapmotion::init(); RealSense::init(); @@ -2209,7 +2231,7 @@ void Application::updateMyAvatarLookAtPosition() { isLookingAtSomeone = true; // If I am looking at someone else, look directly at one of their eyes - if (tracker) { + if (tracker && !tracker->isMuted()) { // If a face tracker is active, look at the eye for the side my gaze is biased toward if (tracker->getEstimatedEyeYaw() > _myAvatar->getHead()->getFinalYaw()) { // Look at their right eye @@ -2235,7 +2257,7 @@ void Application::updateMyAvatarLookAtPosition() { // // Deflect the eyes a bit to match the detected Gaze from 3D camera if active // - if (tracker) { + if (tracker && !tracker->isMuted()) { float eyePitch = tracker->getEstimatedEyePitch(); float eyeYaw = tracker->getEstimatedEyeYaw(); const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; @@ -2290,7 +2312,7 @@ void Application::updateCamera(float deltaTime) { if (!OculusManager::isConnected() && !TV3DManager::isConnected() && Menu::getInstance()->isOptionChecked(MenuOption::OffAxisProjection)) { FaceTracker* tracker = getActiveFaceTracker(); - if (tracker) { + if (tracker && !tracker->isMuted()) { const float EYE_OFFSET_SCALE = 0.025f; glm::vec3 position = tracker->getHeadTranslation() * EYE_OFFSET_SCALE; float xSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? 1.0f : -1.0f; @@ -2353,7 +2375,7 @@ void Application::update(float deltaTime) { PerformanceTimer perfTimer("devices"); DeviceTracker::updateAll(); FaceTracker* tracker = getActiveFaceTracker(); - if (tracker) { + if (tracker && !tracker->isMuted()) { tracker->update(deltaTime); } SixenseManager::getInstance().update(deltaTime); diff --git a/interface/src/Application.h b/interface/src/Application.h index 9f87d05711..91bded9267 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -391,6 +391,7 @@ public slots: void resetSensors(); void setActiveFaceTracker(); + void toggleFaceTrackerMute(); void aboutApp(); void showEditEntitiesHelp(); @@ -432,6 +433,7 @@ private slots: void runTests(); void audioMuteToggled(); + void faceTrackerMuteToggled(); void setCursorVisible(bool visible); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 90a9d3b22c..789a1ebb27 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -394,6 +394,12 @@ Menu::Menu() { QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::VelocityFilter, 0, true); ddeFiltering->setVisible(false); #endif +#if defined(HAVE_FACESHIFT) || defined(HAVE_DDE) + faceTrackingMenu->addSeparator(); + addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::MuteFaceTracking, + 0, false, + qApp, SLOT(toggleFaceTrackerMute())); +#endif auto avatarManager = DependencyManager::get(); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AvatarReceiveStats, 0, false, diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 7d105687ab..a622668742 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -211,6 +211,7 @@ namespace MenuOption { const QString Mirror = "Mirror"; const QString MuteAudio = "Mute Microphone"; const QString MuteEnvironment = "Mute Environment"; + const QString MuteFaceTracking = "Mute Face Tracking"; const QString NoFaceTracking = "None"; const QString OctreeStats = "Entity Statistics"; const QString OffAxisProjection = "Off-Axis Projection"; diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 41c2e9b54c..16cd906133 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -90,7 +90,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { // Only use face trackers when not playing back a recording. if (!myAvatar->isPlaying()) { FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker(); - _isFaceTrackerConnected = faceTracker != NULL; + _isFaceTrackerConnected = faceTracker != NULL && !faceTracker->isMuted(); if (_isFaceTrackerConnected) { _blendshapeCoefficients = faceTracker->getBlendshapeCoefficients(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 557d630ebf..73c2e6a6e8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -243,7 +243,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { estimatedPosition /= OCULUS_LEAN_SCALE; } else { FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker(); - if (tracker) { + if (tracker && !tracker->isMuted()) { estimatedPosition = tracker->getHeadTranslation(); _trackedHeadPosition = estimatedPosition; estimatedRotation = glm::degrees(safeEulerAngles(tracker->getHeadRotation())); diff --git a/interface/src/devices/DdeFaceTracker.cpp b/interface/src/devices/DdeFaceTracker.cpp index b6525ffb52..72c53e5826 100644 --- a/interface/src/devices/DdeFaceTracker.cpp +++ b/interface/src/devices/DdeFaceTracker.cpp @@ -316,7 +316,13 @@ float DdeFaceTracker::getBlendshapeCoefficient(int index) const { } void DdeFaceTracker::decodePacket(const QByteArray& buffer) { - if(buffer.size() > MIN_PACKET_SIZE) { + _lastReceiveTimestamp = usecTimestampNow(); + + if (_isMuted) { + return; + } + + if (buffer.size() > MIN_PACKET_SIZE) { bool isFiltering = Menu::getInstance()->isOptionChecked(MenuOption::VelocityFilter); Packet packet; @@ -328,7 +334,7 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { memcpy(&translation, packet.translation, sizeof(packet.translation)); glm::quat rotation; memcpy(&rotation, &packet.rotation, sizeof(packet.rotation)); - if (_reset || (_lastReceiveTimestamp == 0)) { + if (_reset || (_lastMessageReceived == 0)) { memcpy(&_referenceTranslation, &translation, sizeof(glm::vec3)); memcpy(&_referenceRotation, &rotation, sizeof(glm::quat)); _reset = false; @@ -503,5 +509,4 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { } else { qCWarning(interfaceapp) << "DDE Face Tracker: Decode error"; } - _lastReceiveTimestamp = usecTimestampNow(); } diff --git a/interface/src/devices/FaceTracker.cpp b/interface/src/devices/FaceTracker.cpp index 0d40249c26..a6351c2d64 100644 --- a/interface/src/devices/FaceTracker.cpp +++ b/interface/src/devices/FaceTracker.cpp @@ -15,16 +15,22 @@ #include "FaceTracker.h" #include "InterfaceLogging.h" +#include "Menu.h" const int FPS_TIMER_DELAY = 2000; // ms const int FPS_TIMER_DURATION = 2000; // ms FaceTracker::FaceTracker() : _isCalculatingFPS(false), - _frameCount(0) + _frameCount(0), + _isMuted(false) { } +void FaceTracker::init() { + _isMuted = Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking); +} + inline float FaceTracker::getBlendshapeCoefficient(int index) const { return isValidBlendshapeIndex(index) ? glm::mix(0.0f, _blendshapeCoefficients[index], getFadeCoefficient()) : 0.0f; @@ -101,3 +107,8 @@ void FaceTracker::finishFPSTimer() { qCDebug(interfaceapp) << "Face tracker FPS =" << (float)_frameCount / ((float)FPS_TIMER_DURATION / 1000.0f); _isCalculatingFPS = false; } + +void FaceTracker::toggleMute() { + _isMuted = !_isMuted; + emit muteToggled(); +} diff --git a/interface/src/devices/FaceTracker.h b/interface/src/devices/FaceTracker.h index a0a434ee9e..2ffd9f01bf 100644 --- a/interface/src/devices/FaceTracker.h +++ b/interface/src/devices/FaceTracker.h @@ -26,7 +26,7 @@ public: virtual bool isActive() const { return false; } virtual bool isTracking() const { return false; } - virtual void init() {} + virtual void init(); virtual void update(float deltaTime); virtual void reset(); @@ -42,6 +42,13 @@ public: bool isValidBlendshapeIndex(int index) const { return index >= 0 && index < getNumBlendshapes(); } const QVector& getBlendshapeCoefficients() const; float getBlendshapeCoefficient(int index) const; + + bool isMuted() const { return _isMuted; } + void setIsMuted(bool isMuted) { _isMuted = isMuted; } + void toggleMute(); + +signals: + void muteToggled(); protected: FaceTracker(); @@ -56,6 +63,8 @@ protected: float _relaxationStatus = 0.0f; // Between 0.0f and 1.0f float _fadeCoefficient = 0.0f; // Between 0.0f and 1.0f + bool _isMuted; + void countFrame(); private slots: diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp index 8a0e5a324c..3c3386a076 100644 --- a/interface/src/devices/Faceshift.cpp +++ b/interface/src/devices/Faceshift.cpp @@ -50,6 +50,7 @@ Faceshift::Faceshift() : #ifdef HAVE_FACESHIFT void Faceshift::init() { setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)); + FaceTracker::init(); } void Faceshift::update(float deltaTime) { @@ -92,7 +93,7 @@ void Faceshift::reset() { bool Faceshift::isActive() const { const quint64 ACTIVE_TIMEOUT_USECS = 1000000; - return (usecTimestampNow() - _lastTrackingStateReceived) < ACTIVE_TIMEOUT_USECS; + return (usecTimestampNow() - _lastReceiveTimestamp) < ACTIVE_TIMEOUT_USECS; } bool Faceshift::isTracking() const { @@ -196,6 +197,12 @@ void Faceshift::send(const std::string& message) { void Faceshift::receive(const QByteArray& buffer) { #ifdef HAVE_FACESHIFT + _lastReceiveTimestamp = usecTimestampNow(); + + if (_isMuted) { + return; + } + _stream.received(buffer.size(), buffer.constData()); fsMsgPtr msg; for (fsMsgPtr msg; (msg = _stream.get_message()); ) { @@ -240,11 +247,11 @@ void Faceshift::receive(const QByteArray& buffer) { const float FRAME_AVERAGING_FACTOR = 0.99f; quint64 usecsNow = usecTimestampNow(); - if (_lastTrackingStateReceived != 0) { + if (_lastMessageReceived != 0) { _averageFrameTime = FRAME_AVERAGING_FACTOR * _averageFrameTime + - (1.0f - FRAME_AVERAGING_FACTOR) * (float)(usecsNow - _lastTrackingStateReceived) / 1000000.0f; + (1.0f - FRAME_AVERAGING_FACTOR) * (float)(usecsNow - _lastMessageReceived) / 1000000.0f; } - _lastTrackingStateReceived = usecsNow; + _lastMessageReceived = usecsNow; } break; } diff --git a/interface/src/devices/Faceshift.h b/interface/src/devices/Faceshift.h index 3d38af5654..d2d9821382 100644 --- a/interface/src/devices/Faceshift.h +++ b/interface/src/devices/Faceshift.h @@ -114,7 +114,8 @@ private: bool _tcpEnabled = true; int _tcpRetryCount = 0; bool _tracking = false; - quint64 _lastTrackingStateReceived = 0; + quint64 _lastReceiveTimestamp = 0; + quint64 _lastMessageReceived = 0; float _averageFrameTime = STARTING_FACESHIFT_FRAME_TIME; glm::vec3 _headAngularVelocity = glm::vec3(0.0f); diff --git a/tests/ui/src/main.cpp b/tests/ui/src/main.cpp index a5bc50b288..b9bd195ded 100644 --- a/tests/ui/src/main.cpp +++ b/tests/ui/src/main.cpp @@ -161,6 +161,7 @@ public: Mirror, MuteAudio, MuteEnvironment, + MuteFaceTracking, NoFaceTracking, NoShadows, OctreeStats, From bc051595041a9369fd8de7932b87ce5e4f109b4b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 30 Apr 2015 16:55:10 -0700 Subject: [PATCH 02/10] Add face tracking toggle button beside microphone toggle button --- interface/src/Application.cpp | 9 ++- interface/src/audio/AudioToolBox.cpp | 4 +- interface/src/audio/AudioToolBox.h | 2 +- interface/src/devices/CameraToolBox.cpp | 85 +++++++++++++++++++++++++ interface/src/devices/CameraToolBox.h | 36 +++++++++++ interface/src/ui/ApplicationOverlay.cpp | 74 ++++++++++++++------- interface/src/ui/ApplicationOverlay.h | 1 + 7 files changed, 185 insertions(+), 26 deletions(-) create mode 100644 interface/src/devices/CameraToolBox.cpp create mode 100644 interface/src/devices/CameraToolBox.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 80231d6342..7619b72099 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -103,6 +103,7 @@ #include "audio/AudioIOStatsRenderer.h" #include "audio/AudioScope.h" +#include "devices/CameraToolBox.h" #include "devices/DdeFaceTracker.h" #include "devices/Faceshift.h" #include "devices/Leapmotion.h" @@ -266,6 +267,7 @@ bool setupEssentials(int& argc, char** argv) { auto ddeFaceTracker = DependencyManager::set(); auto modelBlender = DependencyManager::set(); auto audioToolBox = DependencyManager::set(); + auto cameraToolBox = DependencyManager::set(); auto avatarManager = DependencyManager::set(); auto lodManager = DependencyManager::set(); auto jsConsole = DependencyManager::set(); @@ -1504,7 +1506,12 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { // stop propagation return; } - + + if (DependencyManager::get()->mousePressEvent(getMouseX(), getMouseY())) { + // stop propagation + return; + } + if (_rearMirrorTools->mousePressEvent(getMouseX(), getMouseY())) { // stop propagation return; diff --git a/interface/src/audio/AudioToolBox.cpp b/interface/src/audio/AudioToolBox.cpp index 330e7bc194..e37c154429 100644 --- a/interface/src/audio/AudioToolBox.cpp +++ b/interface/src/audio/AudioToolBox.cpp @@ -35,7 +35,7 @@ bool AudioToolBox::mousePressEvent(int x, int y) { return false; } -void AudioToolBox::render(int x, int y, bool boxed) { +void AudioToolBox::render(int x, int y, int padding, bool boxed) { glEnable(GL_TEXTURE_2D); auto glCanvas = Application::getInstance()->getGLWidget(); @@ -79,7 +79,7 @@ void AudioToolBox::render(int x, int y, bool boxed) { float iconColor = 1.0f; - _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); + _iconBounds = QRect(x + padding, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); if (!audioIO->isMuted()) { glBindTexture(GL_TEXTURE_2D, _micTextureId); iconColor = 1.0f; diff --git a/interface/src/audio/AudioToolBox.h b/interface/src/audio/AudioToolBox.h index 526de89b9c..7fbbab8fad 100644 --- a/interface/src/audio/AudioToolBox.h +++ b/interface/src/audio/AudioToolBox.h @@ -18,7 +18,7 @@ class AudioToolBox : public Dependency { SINGLETON_DEPENDENCY public: - void render(int x, int y, bool boxed); + void render(int x, int y, int padding, bool boxed); bool mousePressEvent(int x, int y); protected: diff --git a/interface/src/devices/CameraToolBox.cpp b/interface/src/devices/CameraToolBox.cpp new file mode 100644 index 0000000000..ff20b0b55e --- /dev/null +++ b/interface/src/devices/CameraToolBox.cpp @@ -0,0 +1,85 @@ +// +// CameraToolBox.cpp +// interface/src/devices +// +// Created by David Rowe on 30 Apr 2015. +// Copyright 2015 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 "InterfaceConfig.h" + +#include +#include + +#include "Application.h" +#include "CameraToolBox.h" +#include "FaceTracker.h" + + +CameraToolBox::CameraToolBox() : + _iconPulseTimeReference(usecTimestampNow()) +{ +} + +bool CameraToolBox::mousePressEvent(int x, int y) { + if (_iconBounds.contains(x, y)) { + FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker(); + if (faceTracker) { + faceTracker->toggleMute(); + } + return true; + } + return false; +} + +void CameraToolBox::render(int x, int y, bool boxed) { + glEnable(GL_TEXTURE_2D); + + auto glCanvas = Application::getInstance()->getGLWidget(); + if (_enabledTextureId == 0) { + _enabledTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/mic.svg")); + } + if (_mutedTextureId == 0) { + _mutedTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/mic-mute.svg")); + } + + const int MUTE_ICON_SIZE = 24; + _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); + float iconColor = 1.0f; + if (!Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking)) { + glBindTexture(GL_TEXTURE_2D, _enabledTextureId); + } else { + glBindTexture(GL_TEXTURE_2D, _mutedTextureId); + + // Make muted icon pulsate + static const float PULSE_MIN = 0.4f; + static const float PULSE_MAX = 1.0f; + static const float PULSE_FREQUENCY = 1.0f; // in Hz + qint64 now = usecTimestampNow(); + if (now - _iconPulseTimeReference > (qint64)USECS_PER_SECOND) { + // Prevents t from getting too big, which would diminish glm::cos precision + _iconPulseTimeReference = now - ((now - _iconPulseTimeReference) % USECS_PER_SECOND); + } + float t = (float)(now - _iconPulseTimeReference) / (float)USECS_PER_SECOND; + float pulseFactor = (glm::cos(t * PULSE_FREQUENCY * 2.0f * PI) + 1.0f) / 2.0f; + iconColor = PULSE_MIN + (PULSE_MAX - PULSE_MIN) * pulseFactor; + } + + glm::vec4 quadColor(iconColor, iconColor, iconColor, 1.0f); + + glm::vec2 topLeft(_iconBounds.left(), _iconBounds.top()); + glm::vec2 bottomRight(_iconBounds.right(), _iconBounds.bottom()); + glm::vec2 texCoordTopLeft(1,1); + glm::vec2 texCoordBottomRight(0,0); + + if (_boxQuadID == GeometryCache::UNKNOWN_ID) { + _boxQuadID = DependencyManager::get()->allocateID(); + } + + DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor, _boxQuadID); + + glDisable(GL_TEXTURE_2D); +} \ No newline at end of file diff --git a/interface/src/devices/CameraToolBox.h b/interface/src/devices/CameraToolBox.h new file mode 100644 index 0000000000..3c8fad5468 --- /dev/null +++ b/interface/src/devices/CameraToolBox.h @@ -0,0 +1,36 @@ +// +// CameraToolBox.h +// interface/src/devices +// +// Created by David Rowe on 30 Apr 2015. +// Copyright 2015 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_CameraToolBox_h +#define hifi_CameraToolBox_h + +#include +#include + +class CameraToolBox : public Dependency { + SINGLETON_DEPENDENCY + +public: + void render(int x, int y, bool boxed); + bool mousePressEvent(int x, int y); + +protected: + CameraToolBox(); + +private: + GLuint _enabledTextureId = 0; + GLuint _mutedTextureId = 0; + int _boxQuadID = GeometryCache::UNKNOWN_ID; + QRect _iconBounds; + qint64 _iconPulseTimeReference = 0; +}; + +#endif // hifi_CameraToolBox_h \ No newline at end of file diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 8704a61261..c044bb0674 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -25,6 +25,7 @@ #include "audio/AudioToolBox.h" #include "Application.h" #include "ApplicationOverlay.h" +#include "devices/CameraToolBox.h" #include "devices/OculusManager.h" #include "Util.h" @@ -211,6 +212,7 @@ void ApplicationOverlay::renderOverlay() { glMatrixMode(GL_MODELVIEW); renderAudioMeter(); + renderCameraToggle(); renderStatsAndLogs(); @@ -808,18 +810,46 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool } glPopMatrix(); } +const int AUDIO_METER_GAP = 5; +const int MUTE_ICON_PADDING = 10; + +void ApplicationOverlay::renderCameraToggle() { + if (Menu::getInstance()->isOptionChecked(MenuOption::NoFaceTracking)) { + return; + } + + int audioMeterY; + bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !OculusManager::isConnected(); + bool boxed = smallMirrorVisible && + !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror); + if (boxed) { + audioMeterY = MIRROR_VIEW_HEIGHT + AUDIO_METER_GAP + MUTE_ICON_PADDING; + } else { + audioMeterY = AUDIO_METER_GAP + MUTE_ICON_PADDING; + } + + DependencyManager::get()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, boxed); +} + void ApplicationOverlay::renderAudioMeter() { auto glCanvas = Application::getInstance()->getGLWidget(); auto audio = DependencyManager::get(); // Audio VU Meter and Mute Icon const int MUTE_ICON_SIZE = 24; - const int MUTE_ICON_PADDING = 10; - const int AUDIO_METER_WIDTH = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - MUTE_ICON_PADDING; - const int AUDIO_METER_SCALE_WIDTH = AUDIO_METER_WIDTH - 2 ; const int AUDIO_METER_HEIGHT = 8; - const int AUDIO_METER_GAP = 5; - const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_GAP; + const int INTER_ICON_GAP = 2; + + int cameraSpace = 0; + int audioMeterWidth = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - MUTE_ICON_PADDING; + int audioMeterScaleWidth = audioMeterWidth - 2; + int audioMeterX = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_GAP; + if (!Menu::getInstance()->isOptionChecked(MenuOption::NoFaceTracking)) { + cameraSpace = MUTE_ICON_SIZE + INTER_ICON_GAP; + audioMeterWidth -= cameraSpace; + audioMeterScaleWidth -= cameraSpace; + audioMeterX += cameraSpace; + } int audioMeterY; bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !OculusManager::isConnected(); @@ -834,13 +864,13 @@ void ApplicationOverlay::renderAudioMeter() { const glm::vec4 AUDIO_METER_BLUE = { 0.0, 0.0, 1.0, 1.0 }; const glm::vec4 AUDIO_METER_GREEN = { 0.0, 1.0, 0.0, 1.0 }; const glm::vec4 AUDIO_METER_RED = { 1.0, 0.0, 0.0, 1.0 }; - const float AUDIO_GREEN_START = 0.25 * AUDIO_METER_SCALE_WIDTH; - const float AUDIO_RED_START = 0.80 * AUDIO_METER_SCALE_WIDTH; const float CLIPPING_INDICATOR_TIME = 1.0f; const float AUDIO_METER_AVERAGING = 0.5; const float LOG2 = log(2.0f); const float METER_LOUDNESS_SCALE = 2.8f / 5.0f; const float LOG2_LOUDNESS_FLOOR = 11.0f; + float audioGreenStart = 0.25f * audioMeterScaleWidth; + float audioRedStart = 0.8f * audioMeterScaleWidth; float audioLevel = 0.0f; float loudness = audio->getLastInputLoudness() + 1.0f; @@ -848,12 +878,12 @@ void ApplicationOverlay::renderAudioMeter() { float log2loudness = log(_trailingAudioLoudness) / LOG2; if (log2loudness <= LOG2_LOUDNESS_FLOOR) { - audioLevel = (log2loudness / LOG2_LOUDNESS_FLOOR) * METER_LOUDNESS_SCALE * AUDIO_METER_SCALE_WIDTH; + audioLevel = (log2loudness / LOG2_LOUDNESS_FLOOR) * METER_LOUDNESS_SCALE * audioMeterScaleWidth; } else { - audioLevel = (log2loudness - (LOG2_LOUDNESS_FLOOR - 1.0f)) * METER_LOUDNESS_SCALE * AUDIO_METER_SCALE_WIDTH; + audioLevel = (log2loudness - (LOG2_LOUDNESS_FLOOR - 1.0f)) * METER_LOUDNESS_SCALE * audioMeterScaleWidth; } - if (audioLevel > AUDIO_METER_SCALE_WIDTH) { - audioLevel = AUDIO_METER_SCALE_WIDTH; + if (audioLevel > audioMeterScaleWidth) { + audioLevel = audioMeterScaleWidth; } bool isClipping = ((audio->getTimeSinceLastClip() > 0.0f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)); @@ -863,7 +893,7 @@ void ApplicationOverlay::renderAudioMeter() { renderCollisionOverlay(glCanvas->width(), glCanvas->height(), magnitude, 1.0f); } - DependencyManager::get()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, boxed); + DependencyManager::get()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, cameraSpace, boxed); DependencyManager::get()->render(glCanvas->width(), glCanvas->height()); DependencyManager::get()->render(WHITE_TEXT, glCanvas->width(), glCanvas->height()); @@ -871,10 +901,10 @@ void ApplicationOverlay::renderAudioMeter() { audioMeterY += AUDIO_METER_HEIGHT; // Draw audio meter background Quad - DependencyManager::get()->renderQuad(AUDIO_METER_X, audioMeterY, AUDIO_METER_WIDTH, AUDIO_METER_HEIGHT, + DependencyManager::get()->renderQuad(audioMeterX, audioMeterY, audioMeterWidth, AUDIO_METER_HEIGHT, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); - if (audioLevel > AUDIO_RED_START) { + if (audioLevel > audioRedStart) { glm::vec4 quadColor; if (!isClipping) { quadColor = AUDIO_METER_RED; @@ -882,16 +912,16 @@ void ApplicationOverlay::renderAudioMeter() { quadColor = glm::vec4(1, 1, 1, 1); } // Draw Red Quad - DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_RED_START, + DependencyManager::get()->renderQuad(audioMeterX + audioRedStart, audioMeterY, - audioLevel - AUDIO_RED_START, + audioLevel - audioRedStart, AUDIO_METER_HEIGHT, quadColor, _audioRedQuad); - audioLevel = AUDIO_RED_START; + audioLevel = audioRedStart; } - if (audioLevel > AUDIO_GREEN_START) { + if (audioLevel > audioGreenStart) { glm::vec4 quadColor; if (!isClipping) { quadColor = AUDIO_METER_GREEN; @@ -899,13 +929,13 @@ void ApplicationOverlay::renderAudioMeter() { quadColor = glm::vec4(1, 1, 1, 1); } // Draw Green Quad - DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_GREEN_START, + DependencyManager::get()->renderQuad(audioMeterX + audioGreenStart, audioMeterY, - audioLevel - AUDIO_GREEN_START, + audioLevel - audioGreenStart, AUDIO_METER_HEIGHT, quadColor, _audioGreenQuad); - audioLevel = AUDIO_GREEN_START; + audioLevel = audioGreenStart; } if (audioLevel >= 0) { @@ -916,7 +946,7 @@ void ApplicationOverlay::renderAudioMeter() { quadColor = glm::vec4(1, 1, 1, 1); } // Draw Blue (low level) quad - DependencyManager::get()->renderQuad(AUDIO_METER_X, + DependencyManager::get()->renderQuad(audioMeterX, audioMeterY, audioLevel, AUDIO_METER_HEIGHT, quadColor, _audioBlueQuad); diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index e6c7526c5d..54c8613f94 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -101,6 +101,7 @@ private: void renderPointersOculus(const glm::vec3& eyePos); void renderAudioMeter(); + void renderCameraToggle(); void renderStatsAndLogs(); void renderDomainConnectionStatusBorder(); From 528f73897c58e7cffa31aecc98ad088cba51877d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 30 Apr 2015 22:14:01 -0700 Subject: [PATCH 03/10] Make double click face tracking toggle button reset tracking --- interface/src/Application.cpp | 21 ++++++++++++ interface/src/Application.h | 1 + interface/src/GLCanvas.cpp | 1 + interface/src/devices/CameraToolBox.cpp | 44 ++++++++++++++++++++++--- interface/src/devices/CameraToolBox.h | 11 ++++++- 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7619b72099..8e3c60907b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1016,6 +1016,9 @@ bool Application::event(QEvent* event) { case QEvent::MouseButtonPress: mousePressEvent((QMouseEvent*)event); return true; + case QEvent::MouseButtonDblClick: + mouseDoublePressEvent((QMouseEvent*)event); + return true; case QEvent::MouseButtonRelease: mouseReleaseEvent((QMouseEvent*)event); return true; @@ -1529,6 +1532,24 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { } } +void Application::mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID) { + // if one of our scripts have asked to capture this event, then stop processing it + if (_controllerScriptingInterface.isMouseCaptured()) { + return; + } + + if (activeWindow() == _window) { + if (event->button() == Qt::LeftButton) { + if (mouseOnScreen()) { + if (DependencyManager::get()->mouseDoublePressEvent(getMouseX(), getMouseY())) { + // stop propagation + return; + } + } + } + } +} + void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { if (!_aboutToQuit) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 91bded9267..2921741971 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -167,6 +167,7 @@ public: void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0); void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0); + void mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0); void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0); void touchBeginEvent(QTouchEvent* event); diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 9a9512a0b0..e169c96fe1 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -131,6 +131,7 @@ bool GLCanvas::event(QEvent* event) { case QEvent::MouseMove: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: case QEvent::KeyPress: case QEvent::KeyRelease: case QEvent::FocusIn: diff --git a/interface/src/devices/CameraToolBox.cpp b/interface/src/devices/CameraToolBox.cpp index ff20b0b55e..0f4b1ff5b1 100644 --- a/interface/src/devices/CameraToolBox.cpp +++ b/interface/src/devices/CameraToolBox.cpp @@ -20,21 +20,57 @@ CameraToolBox::CameraToolBox() : - _iconPulseTimeReference(usecTimestampNow()) + _iconPulseTimeReference(usecTimestampNow()), + _doubleClickTimer(NULL) { } +CameraToolBox::~CameraToolBox() { + if (_doubleClickTimer) { + _doubleClickTimer->stop(); + delete _doubleClickTimer; + } +} + bool CameraToolBox::mousePressEvent(int x, int y) { if (_iconBounds.contains(x, y)) { - FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker(); - if (faceTracker) { - faceTracker->toggleMute(); + if (!_doubleClickTimer) { + // Toggle mute after waiting to check that it's not a double-click. + const int DOUBLE_CLICK_WAIT = 200; // ms + _doubleClickTimer = new QTimer(this); + connect(_doubleClickTimer, SIGNAL(timeout()), this, SLOT(toggleMute())); + _doubleClickTimer->setSingleShot(true); + _doubleClickTimer->setInterval(DOUBLE_CLICK_WAIT); + _doubleClickTimer->start(); } return true; } return false; } +bool CameraToolBox::mouseDoublePressEvent(int x, int y) { + if (_iconBounds.contains(x, y)) { + if (_doubleClickTimer) { + _doubleClickTimer->stop(); + delete _doubleClickTimer; + _doubleClickTimer = NULL; + } + Application::getInstance()->resetSensors(); + return true; + } + return false; +} + +void CameraToolBox::toggleMute() { + delete _doubleClickTimer; + _doubleClickTimer = NULL; + + FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker(); + if (faceTracker) { + faceTracker->toggleMute(); + } +} + void CameraToolBox::render(int x, int y, bool boxed) { glEnable(GL_TEXTURE_2D); diff --git a/interface/src/devices/CameraToolBox.h b/interface/src/devices/CameraToolBox.h index 3c8fad5468..5f9241c81d 100644 --- a/interface/src/devices/CameraToolBox.h +++ b/interface/src/devices/CameraToolBox.h @@ -12,18 +12,26 @@ #ifndef hifi_CameraToolBox_h #define hifi_CameraToolBox_h +#include + #include #include -class CameraToolBox : public Dependency { +class CameraToolBox : public QObject, public Dependency { + Q_OBJECT SINGLETON_DEPENDENCY public: void render(int x, int y, bool boxed); bool mousePressEvent(int x, int y); + bool mouseDoublePressEvent(int x, int y); protected: CameraToolBox(); + ~CameraToolBox(); + +private slots: + void toggleMute(); private: GLuint _enabledTextureId = 0; @@ -31,6 +39,7 @@ private: int _boxQuadID = GeometryCache::UNKNOWN_ID; QRect _iconBounds; qint64 _iconPulseTimeReference = 0; + QTimer* _doubleClickTimer; }; #endif // hifi_CameraToolBox_h \ No newline at end of file From 7bc995be5e0229caa8a44975b9912e596bd80058 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 30 Apr 2015 23:11:04 -0700 Subject: [PATCH 04/10] Add camera muting icons --- interface/resources/images/face-mute.svg | 14 ++++++++++++++ interface/resources/images/face.svg | 13 +++++++++++++ interface/src/devices/CameraToolBox.cpp | 4 ++-- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 interface/resources/images/face-mute.svg create mode 100644 interface/resources/images/face.svg diff --git a/interface/resources/images/face-mute.svg b/interface/resources/images/face-mute.svg new file mode 100644 index 0000000000..fcf275fb62 --- /dev/null +++ b/interface/resources/images/face-mute.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/interface/resources/images/face.svg b/interface/resources/images/face.svg new file mode 100644 index 0000000000..aac3fb8285 --- /dev/null +++ b/interface/resources/images/face.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/interface/src/devices/CameraToolBox.cpp b/interface/src/devices/CameraToolBox.cpp index 0f4b1ff5b1..69afefff86 100644 --- a/interface/src/devices/CameraToolBox.cpp +++ b/interface/src/devices/CameraToolBox.cpp @@ -76,10 +76,10 @@ void CameraToolBox::render(int x, int y, bool boxed) { auto glCanvas = Application::getInstance()->getGLWidget(); if (_enabledTextureId == 0) { - _enabledTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/mic.svg")); + _enabledTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/face.svg")); } if (_mutedTextureId == 0) { - _mutedTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/mic-mute.svg")); + _mutedTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/face-mute.svg")); } const int MUTE_ICON_SIZE = 24; From e689b6a86939c3d461754f7e399ca5a9f363030b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 1 May 2015 12:07:00 -0700 Subject: [PATCH 05/10] Remove leading Unicode control chars --- interface/resources/images/face-mute.svg | 2 +- interface/resources/images/face.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/images/face-mute.svg b/interface/resources/images/face-mute.svg index fcf275fb62..0a93c366e0 100644 --- a/interface/resources/images/face-mute.svg +++ b/interface/resources/images/face-mute.svg @@ -1,4 +1,4 @@ - + diff --git a/interface/resources/images/face.svg b/interface/resources/images/face.svg index aac3fb8285..09d05af6fc 100644 --- a/interface/resources/images/face.svg +++ b/interface/resources/images/face.svg @@ -1,4 +1,4 @@ - + From 7afd990e2e4ac8c9c29862da4bcf2cea98ac8112 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 4 May 2015 22:27:41 -0700 Subject: [PATCH 06/10] Fix Mixamo avatar clipping in HMD view --- interface/src/avatar/MyAvatar.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 557d630ebf..ec89eb0953 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1178,14 +1178,8 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode ren } else { float clipDistance = _skeletonModel.getHeadClipDistance(); if (OculusManager::isConnected()) { - // If avatar is horizontally in front of camera, increase clip distance by the amount it is in front. - glm::vec3 cameraToAvatar = _position - cameraPos; - cameraToAvatar.y = 0.0f; - glm::vec3 cameraLookAt = camera->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f); - float headOffset = glm::dot(cameraLookAt, cameraToAvatar); - if (headOffset > 0) { - clipDistance += headOffset; - } + clipDistance = glm::length(getEyePosition() + + camera->getOrientation() * glm::vec3(0.0f, 0.0f, -clipDistance) - cameraPos); } renderFrustum->setNearClip(clipDistance); } From 1c21874f000ca4d6af1933b181c0588702050c6b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 5 May 2015 16:51:31 -0700 Subject: [PATCH 07/10] Make face tracker mute action start / stop face tracker --- interface/src/Application.cpp | 25 ++++++++++++++++++++---- interface/src/Application.h | 1 + interface/src/devices/CameraToolBox.cpp | 2 +- interface/src/devices/DdeFaceTracker.cpp | 17 +++++++++------- interface/src/devices/DdeFaceTracker.h | 4 +--- interface/src/devices/FaceTracker.cpp | 8 +------- interface/src/devices/FaceTracker.h | 15 ++++++++------ interface/src/devices/Faceshift.cpp | 12 ++++++------ interface/src/devices/Faceshift.h | 2 +- 9 files changed, 51 insertions(+), 35 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1f1d8713e7..4d1fa79abc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -934,7 +934,9 @@ void Application::audioMuteToggled() { void Application::faceTrackerMuteToggled() { QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking); Q_CHECK_PTR(muteAction); - muteAction->setChecked(getActiveFaceTracker()->isMuted()); + bool isMuted = getSelectedFaceTracker()->isMuted(); + muteAction->setChecked(isMuted); + getSelectedFaceTracker()->setEnabled(!isMuted); } void Application::aboutApp() { @@ -1887,25 +1889,40 @@ FaceTracker* Application::getActiveFaceTracker() { (faceshift->isActive() ? static_cast(faceshift.data()) : NULL)); } +FaceTracker* Application::getSelectedFaceTracker() { + FaceTracker* faceTracker = NULL; +#ifdef HAVE_FACESHIFT + if (Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)) { + faceTracker = DependencyManager::get().data(); + } +#endif +#ifdef HAVE_DDE + if (Menu::getInstance()->isOptionChecked(MenuOption::UseCamera)) { + faceTracker = DependencyManager::get().data(); + } +#endif + return faceTracker; +} + void Application::setActiveFaceTracker() { bool isMuted = Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking); #ifdef HAVE_FACESHIFT auto faceshiftTracker = DependencyManager::get(); - faceshiftTracker->setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)); faceshiftTracker->setIsMuted(isMuted); + faceshiftTracker->setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift) && !isMuted); #endif #ifdef HAVE_DDE bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::UseCamera); Menu::getInstance()->getActionForOption(MenuOption::UseAudioForMouth)->setVisible(isUsingDDE); Menu::getInstance()->getActionForOption(MenuOption::VelocityFilter)->setVisible(isUsingDDE); auto ddeTracker = DependencyManager::get(); - ddeTracker->setEnabled(isUsingDDE); ddeTracker->setIsMuted(isMuted); + ddeTracker->setEnabled(isUsingDDE && !isMuted); #endif } void Application::toggleFaceTrackerMute() { - FaceTracker* faceTracker = getActiveFaceTracker(); + FaceTracker* faceTracker = getSelectedFaceTracker(); if (faceTracker) { faceTracker->toggleMute(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index ec32d1a590..58e49159a2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -219,6 +219,7 @@ public: bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; } FaceTracker* getActiveFaceTracker(); + FaceTracker* getSelectedFaceTracker(); QSystemTrayIcon* getTrayIcon() { return _trayIcon; } ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; } diff --git a/interface/src/devices/CameraToolBox.cpp b/interface/src/devices/CameraToolBox.cpp index 69afefff86..26aff4bf9a 100644 --- a/interface/src/devices/CameraToolBox.cpp +++ b/interface/src/devices/CameraToolBox.cpp @@ -65,7 +65,7 @@ void CameraToolBox::toggleMute() { delete _doubleClickTimer; _doubleClickTimer = NULL; - FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker(); + FaceTracker* faceTracker = Application::getInstance()->getSelectedFaceTracker(); if (faceTracker) { faceTracker->toggleMute(); } diff --git a/interface/src/devices/DdeFaceTracker.cpp b/interface/src/devices/DdeFaceTracker.cpp index 5d1d184880..59d2b42a51 100644 --- a/interface/src/devices/DdeFaceTracker.cpp +++ b/interface/src/devices/DdeFaceTracker.cpp @@ -178,9 +178,7 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui _filteredBrowUp(0.0f), _lastEyeBlinks(), _filteredEyeBlinks(), - _lastEyeCoefficients(), - _isCalculatingFPS(false), - _frameCount(0) + _lastEyeCoefficients() { _coefficients.resize(NUM_FACESHIFT_BLENDSHAPES); @@ -203,7 +201,16 @@ DdeFaceTracker::~DdeFaceTracker() { #pragma warning(default:4351) #endif +void DdeFaceTracker::init() { + FaceTracker::init(); + setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::UseCamera) && !_isMuted); +} + void DdeFaceTracker::setEnabled(bool enabled) { + if (!_isInitialized) { + // Don't enable until have explicitly initialized + return; + } #ifdef HAVE_DDE // isOpen() does not work as one might expect on QUdpSocket; don't test isOpen() before closing socket. _udpSocket.close(); @@ -316,10 +323,6 @@ float DdeFaceTracker::getBlendshapeCoefficient(int index) const { void DdeFaceTracker::decodePacket(const QByteArray& buffer) { _lastReceiveTimestamp = usecTimestampNow(); - if (_isMuted) { - return; - } - if (buffer.size() > MIN_PACKET_SIZE) { bool isFiltering = Menu::getInstance()->isOptionChecked(MenuOption::VelocityFilter); diff --git a/interface/src/devices/DdeFaceTracker.h b/interface/src/devices/DdeFaceTracker.h index 9fb0e943f2..9edbd4df58 100644 --- a/interface/src/devices/DdeFaceTracker.h +++ b/interface/src/devices/DdeFaceTracker.h @@ -28,6 +28,7 @@ class DdeFaceTracker : public FaceTracker, public Dependency { SINGLETON_DEPENDENCY public: + virtual void init(); virtual void reset(); virtual bool isActive() const; @@ -120,9 +121,6 @@ private: float _lastEyeBlinks[2]; float _filteredEyeBlinks[2]; float _lastEyeCoefficients[2]; - - bool _isCalculatingFPS; - int _frameCount; }; #endif // hifi_DdeFaceTracker_h diff --git a/interface/src/devices/FaceTracker.cpp b/interface/src/devices/FaceTracker.cpp index a6351c2d64..25a76ff2b1 100644 --- a/interface/src/devices/FaceTracker.cpp +++ b/interface/src/devices/FaceTracker.cpp @@ -20,15 +20,9 @@ const int FPS_TIMER_DELAY = 2000; // ms const int FPS_TIMER_DURATION = 2000; // ms -FaceTracker::FaceTracker() : - _isCalculatingFPS(false), - _frameCount(0), - _isMuted(false) -{ -} - void FaceTracker::init() { _isMuted = Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking); + _isInitialized = true; // FaceTracker can be used now } inline float FaceTracker::getBlendshapeCoefficient(int index) const { diff --git a/interface/src/devices/FaceTracker.h b/interface/src/devices/FaceTracker.h index 2ffd9f01bf..2a0c4438a4 100644 --- a/interface/src/devices/FaceTracker.h +++ b/interface/src/devices/FaceTracker.h @@ -49,11 +49,16 @@ public: signals: void muteToggled(); - + +public slots: + virtual void setEnabled(bool enabled) = 0; + protected: - FaceTracker(); virtual ~FaceTracker() {}; + bool _isInitialized = false; + bool _isMuted = true; + glm::vec3 _headTranslation = glm::vec3(0.0f); glm::quat _headRotation = glm::quat(); float _estimatedEyePitch = 0.0f; @@ -63,8 +68,6 @@ protected: float _relaxationStatus = 0.0f; // Between 0.0f and 1.0f float _fadeCoefficient = 0.0f; // Between 0.0f and 1.0f - bool _isMuted; - void countFrame(); private slots: @@ -72,8 +75,8 @@ private slots: void finishFPSTimer(); private: - bool _isCalculatingFPS; - int _frameCount; + bool _isCalculatingFPS = false; + int _frameCount = 0; }; #endif // hifi_FaceTracker_h diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp index a9b78aa792..409f359afa 100644 --- a/interface/src/devices/Faceshift.cpp +++ b/interface/src/devices/Faceshift.cpp @@ -49,8 +49,8 @@ Faceshift::Faceshift() : #ifdef HAVE_FACESHIFT void Faceshift::init() { - setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)); FaceTracker::init(); + setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift) && !_isMuted); } void Faceshift::update(float deltaTime) { @@ -128,7 +128,11 @@ void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float coefficients[FUNNEL_BLENDSHAPE] = mouth3; } -void Faceshift::setTCPEnabled(bool enabled) { +void Faceshift::setEnabled(bool enabled) { + // Don't enable until have explicitly initialized + if (!_isInitialized) { + return; + } #ifdef HAVE_FACESHIFT if ((_tcpEnabled = enabled)) { connectSocket(); @@ -199,10 +203,6 @@ void Faceshift::receive(const QByteArray& buffer) { #ifdef HAVE_FACESHIFT _lastReceiveTimestamp = usecTimestampNow(); - if (_isMuted) { - return; - } - _stream.received(buffer.size(), buffer.constData()); fsMsgPtr msg; for (fsMsgPtr msg; (msg = _stream.get_message()); ) { diff --git a/interface/src/devices/Faceshift.h b/interface/src/devices/Faceshift.h index d2d9821382..9be1766170 100644 --- a/interface/src/devices/Faceshift.h +++ b/interface/src/devices/Faceshift.h @@ -87,7 +87,7 @@ signals: void connectionStateChanged(); public slots: - void setTCPEnabled(bool enabled); + void setEnabled(bool enabled); private slots: void connectSocket(); From 333da936429f9de01f988f6c41ed7029a9cb9af7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 5 May 2015 23:20:23 -0700 Subject: [PATCH 08/10] Updated face tracker mute icons --- interface/resources/images/face-mute.svg | 46 ++++++++++++++++-------- interface/resources/images/face.svg | 44 ++++++++++++++++------- 2 files changed, 63 insertions(+), 27 deletions(-) diff --git a/interface/resources/images/face-mute.svg b/interface/resources/images/face-mute.svg index 0a93c366e0..b16b7383c5 100644 --- a/interface/resources/images/face-mute.svg +++ b/interface/resources/images/face-mute.svg @@ -1,14 +1,32 @@ - - - - - - - - - - - - - - + + + + Slice 1 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/interface/resources/images/face.svg b/interface/resources/images/face.svg index 09d05af6fc..62ce0deb25 100644 --- a/interface/resources/images/face.svg +++ b/interface/resources/images/face.svg @@ -1,13 +1,31 @@ - - - - - - - - - - - - - + + + + Slice 1 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From eb438e9ccbd01bcb5ff3e4b295d266b12f8d0b11 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 6 May 2015 09:58:14 -0700 Subject: [PATCH 09/10] Can use same clipping calc for non-Oculus --- interface/src/avatar/MyAvatar.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ec89eb0953..10d22b72f5 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1177,10 +1177,8 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode ren renderFrustum->setNearClip(DEFAULT_NEAR_CLIP); } else { float clipDistance = _skeletonModel.getHeadClipDistance(); - if (OculusManager::isConnected()) { - clipDistance = glm::length(getEyePosition() - + camera->getOrientation() * glm::vec3(0.0f, 0.0f, -clipDistance) - cameraPos); - } + clipDistance = glm::length(getEyePosition() + + camera->getOrientation() * glm::vec3(0.0f, 0.0f, -clipDistance) - cameraPos); renderFrustum->setNearClip(clipDistance); } } From de49057f17ad807141d965ae5282c964c4fa8135 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Wed, 6 May 2015 10:32:45 -0700 Subject: [PATCH 10/10] Fix for HMDTools targeting wrong screen on OSX --- interface/src/ui/HMDToolsDialog.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 4a899a641e..343fc939b5 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -162,11 +162,16 @@ void HMDToolsDialog::enterHDMMode() { close(); } - Application::getInstance()->setFullscreen(true); Application::getInstance()->setEnableVRMode(true); const int SLIGHT_DELAY = 500; - QTimer::singleShot(SLIGHT_DELAY, this, SLOT(activateWindowAfterEnterMode())); + // If we go to fullscreen immediately, it ends up on the primary monitor, + // even though we've already moved the window. By adding this delay, the + // fullscreen target screen ends up correct. + QTimer::singleShot(SLIGHT_DELAY, this, [&]{ + Application::getInstance()->setFullscreen(true); + activateWindowAfterEnterMode(); + }); _inHDMMode = true; }