Add face tracking toggle button beside microphone toggle button

This commit is contained in:
David Rowe 2015-04-30 16:55:10 -07:00
parent d053379831
commit bc05159504
7 changed files with 185 additions and 26 deletions

View file

@ -103,6 +103,7 @@
#include "audio/AudioIOStatsRenderer.h" #include "audio/AudioIOStatsRenderer.h"
#include "audio/AudioScope.h" #include "audio/AudioScope.h"
#include "devices/CameraToolBox.h"
#include "devices/DdeFaceTracker.h" #include "devices/DdeFaceTracker.h"
#include "devices/Faceshift.h" #include "devices/Faceshift.h"
#include "devices/Leapmotion.h" #include "devices/Leapmotion.h"
@ -266,6 +267,7 @@ bool setupEssentials(int& argc, char** argv) {
auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>(); auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>();
auto modelBlender = DependencyManager::set<ModelBlender>(); auto modelBlender = DependencyManager::set<ModelBlender>();
auto audioToolBox = DependencyManager::set<AudioToolBox>(); auto audioToolBox = DependencyManager::set<AudioToolBox>();
auto cameraToolBox = DependencyManager::set<CameraToolBox>();
auto avatarManager = DependencyManager::set<AvatarManager>(); auto avatarManager = DependencyManager::set<AvatarManager>();
auto lodManager = DependencyManager::set<LODManager>(); auto lodManager = DependencyManager::set<LODManager>();
auto jsConsole = DependencyManager::set<StandAloneJSConsole>(); auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
@ -1504,7 +1506,12 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
// stop propagation // stop propagation
return; return;
} }
if (DependencyManager::get<CameraToolBox>()->mousePressEvent(getMouseX(), getMouseY())) {
// stop propagation
return;
}
if (_rearMirrorTools->mousePressEvent(getMouseX(), getMouseY())) { if (_rearMirrorTools->mousePressEvent(getMouseX(), getMouseY())) {
// stop propagation // stop propagation
return; return;

View file

@ -35,7 +35,7 @@ bool AudioToolBox::mousePressEvent(int x, int y) {
return false; 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); glEnable(GL_TEXTURE_2D);
auto glCanvas = Application::getInstance()->getGLWidget(); auto glCanvas = Application::getInstance()->getGLWidget();
@ -79,7 +79,7 @@ void AudioToolBox::render(int x, int y, bool boxed) {
float iconColor = 1.0f; 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()) { if (!audioIO->isMuted()) {
glBindTexture(GL_TEXTURE_2D, _micTextureId); glBindTexture(GL_TEXTURE_2D, _micTextureId);
iconColor = 1.0f; iconColor = 1.0f;

View file

@ -18,7 +18,7 @@
class AudioToolBox : public Dependency { class AudioToolBox : public Dependency {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: 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); bool mousePressEvent(int x, int y);
protected: protected:

View file

@ -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 <GLCanvas.h>
#include <PathUtils.h>
#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<GeometryCache>()->allocateID();
}
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor, _boxQuadID);
glDisable(GL_TEXTURE_2D);
}

View file

@ -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 <DependencyManager.h>
#include <GeometryCache.h>
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

View file

@ -25,6 +25,7 @@
#include "audio/AudioToolBox.h" #include "audio/AudioToolBox.h"
#include "Application.h" #include "Application.h"
#include "ApplicationOverlay.h" #include "ApplicationOverlay.h"
#include "devices/CameraToolBox.h"
#include "devices/OculusManager.h" #include "devices/OculusManager.h"
#include "Util.h" #include "Util.h"
@ -211,6 +212,7 @@ void ApplicationOverlay::renderOverlay() {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
renderAudioMeter(); renderAudioMeter();
renderCameraToggle();
renderStatsAndLogs(); renderStatsAndLogs();
@ -808,18 +810,46 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool
} glPopMatrix(); } 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<CameraToolBox>()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, boxed);
}
void ApplicationOverlay::renderAudioMeter() { void ApplicationOverlay::renderAudioMeter() {
auto glCanvas = Application::getInstance()->getGLWidget(); auto glCanvas = Application::getInstance()->getGLWidget();
auto audio = DependencyManager::get<AudioClient>(); auto audio = DependencyManager::get<AudioClient>();
// Audio VU Meter and Mute Icon // Audio VU Meter and Mute Icon
const int MUTE_ICON_SIZE = 24; 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_HEIGHT = 8;
const int AUDIO_METER_GAP = 5; const int INTER_ICON_GAP = 2;
const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_GAP;
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; int audioMeterY;
bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !OculusManager::isConnected(); 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_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_GREEN = { 0.0, 1.0, 0.0, 1.0 };
const glm::vec4 AUDIO_METER_RED = { 1.0, 0.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 CLIPPING_INDICATOR_TIME = 1.0f;
const float AUDIO_METER_AVERAGING = 0.5; const float AUDIO_METER_AVERAGING = 0.5;
const float LOG2 = log(2.0f); const float LOG2 = log(2.0f);
const float METER_LOUDNESS_SCALE = 2.8f / 5.0f; const float METER_LOUDNESS_SCALE = 2.8f / 5.0f;
const float LOG2_LOUDNESS_FLOOR = 11.0f; const float LOG2_LOUDNESS_FLOOR = 11.0f;
float audioGreenStart = 0.25f * audioMeterScaleWidth;
float audioRedStart = 0.8f * audioMeterScaleWidth;
float audioLevel = 0.0f; float audioLevel = 0.0f;
float loudness = audio->getLastInputLoudness() + 1.0f; float loudness = audio->getLastInputLoudness() + 1.0f;
@ -848,12 +878,12 @@ void ApplicationOverlay::renderAudioMeter() {
float log2loudness = log(_trailingAudioLoudness) / LOG2; float log2loudness = log(_trailingAudioLoudness) / LOG2;
if (log2loudness <= LOG2_LOUDNESS_FLOOR) { 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 { } 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) { if (audioLevel > audioMeterScaleWidth) {
audioLevel = AUDIO_METER_SCALE_WIDTH; audioLevel = audioMeterScaleWidth;
} }
bool isClipping = ((audio->getTimeSinceLastClip() > 0.0f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)); 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); renderCollisionOverlay(glCanvas->width(), glCanvas->height(), magnitude, 1.0f);
} }
DependencyManager::get<AudioToolBox>()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, boxed); DependencyManager::get<AudioToolBox>()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, cameraSpace, boxed);
DependencyManager::get<AudioScope>()->render(glCanvas->width(), glCanvas->height()); DependencyManager::get<AudioScope>()->render(glCanvas->width(), glCanvas->height());
DependencyManager::get<AudioIOStatsRenderer>()->render(WHITE_TEXT, glCanvas->width(), glCanvas->height()); DependencyManager::get<AudioIOStatsRenderer>()->render(WHITE_TEXT, glCanvas->width(), glCanvas->height());
@ -871,10 +901,10 @@ void ApplicationOverlay::renderAudioMeter() {
audioMeterY += AUDIO_METER_HEIGHT; audioMeterY += AUDIO_METER_HEIGHT;
// Draw audio meter background Quad // Draw audio meter background Quad
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X, audioMeterY, AUDIO_METER_WIDTH, AUDIO_METER_HEIGHT, DependencyManager::get<GeometryCache>()->renderQuad(audioMeterX, audioMeterY, audioMeterWidth, AUDIO_METER_HEIGHT,
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
if (audioLevel > AUDIO_RED_START) { if (audioLevel > audioRedStart) {
glm::vec4 quadColor; glm::vec4 quadColor;
if (!isClipping) { if (!isClipping) {
quadColor = AUDIO_METER_RED; quadColor = AUDIO_METER_RED;
@ -882,16 +912,16 @@ void ApplicationOverlay::renderAudioMeter() {
quadColor = glm::vec4(1, 1, 1, 1); quadColor = glm::vec4(1, 1, 1, 1);
} }
// Draw Red Quad // Draw Red Quad
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_RED_START, DependencyManager::get<GeometryCache>()->renderQuad(audioMeterX + audioRedStart,
audioMeterY, audioMeterY,
audioLevel - AUDIO_RED_START, audioLevel - audioRedStart,
AUDIO_METER_HEIGHT, quadColor, AUDIO_METER_HEIGHT, quadColor,
_audioRedQuad); _audioRedQuad);
audioLevel = AUDIO_RED_START; audioLevel = audioRedStart;
} }
if (audioLevel > AUDIO_GREEN_START) { if (audioLevel > audioGreenStart) {
glm::vec4 quadColor; glm::vec4 quadColor;
if (!isClipping) { if (!isClipping) {
quadColor = AUDIO_METER_GREEN; quadColor = AUDIO_METER_GREEN;
@ -899,13 +929,13 @@ void ApplicationOverlay::renderAudioMeter() {
quadColor = glm::vec4(1, 1, 1, 1); quadColor = glm::vec4(1, 1, 1, 1);
} }
// Draw Green Quad // Draw Green Quad
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_GREEN_START, DependencyManager::get<GeometryCache>()->renderQuad(audioMeterX + audioGreenStart,
audioMeterY, audioMeterY,
audioLevel - AUDIO_GREEN_START, audioLevel - audioGreenStart,
AUDIO_METER_HEIGHT, quadColor, AUDIO_METER_HEIGHT, quadColor,
_audioGreenQuad); _audioGreenQuad);
audioLevel = AUDIO_GREEN_START; audioLevel = audioGreenStart;
} }
if (audioLevel >= 0) { if (audioLevel >= 0) {
@ -916,7 +946,7 @@ void ApplicationOverlay::renderAudioMeter() {
quadColor = glm::vec4(1, 1, 1, 1); quadColor = glm::vec4(1, 1, 1, 1);
} }
// Draw Blue (low level) quad // Draw Blue (low level) quad
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X, DependencyManager::get<GeometryCache>()->renderQuad(audioMeterX,
audioMeterY, audioMeterY,
audioLevel, AUDIO_METER_HEIGHT, quadColor, audioLevel, AUDIO_METER_HEIGHT, quadColor,
_audioBlueQuad); _audioBlueQuad);

View file

@ -101,6 +101,7 @@ private:
void renderPointersOculus(const glm::vec3& eyePos); void renderPointersOculus(const glm::vec3& eyePos);
void renderAudioMeter(); void renderAudioMeter();
void renderCameraToggle();
void renderStatsAndLogs(); void renderStatsAndLogs();
void renderDomainConnectionStatusBorder(); void renderDomainConnectionStatusBorder();