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();