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/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<DdeFaceTracker>();
auto modelBlender = DependencyManager::set<ModelBlender>();
auto audioToolBox = DependencyManager::set<AudioToolBox>();
auto cameraToolBox = DependencyManager::set<CameraToolBox>();
auto avatarManager = DependencyManager::set<AvatarManager>();
auto lodManager = DependencyManager::set<LODManager>();
auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
@ -1504,7 +1506,12 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
// stop propagation
return;
}
if (DependencyManager::get<CameraToolBox>()->mousePressEvent(getMouseX(), getMouseY())) {
// stop propagation
return;
}
if (_rearMirrorTools->mousePressEvent(getMouseX(), getMouseY())) {
// stop propagation
return;

View file

@ -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;

View file

@ -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:

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 "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<CameraToolBox>()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, boxed);
}
void ApplicationOverlay::renderAudioMeter() {
auto glCanvas = Application::getInstance()->getGLWidget();
auto audio = DependencyManager::get<AudioClient>();
// 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<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<AudioIOStatsRenderer>()->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<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));
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<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_RED_START,
DependencyManager::get<GeometryCache>()->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<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_GREEN_START,
DependencyManager::get<GeometryCache>()->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<GeometryCache>()->renderQuad(AUDIO_METER_X,
DependencyManager::get<GeometryCache>()->renderQuad(audioMeterX,
audioMeterY,
audioLevel, AUDIO_METER_HEIGHT, quadColor,
_audioBlueQuad);

View file

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