diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp
index f7953cdf41..9e7cf53e2f 100644
--- a/assignment-client/src/audio/AudioMixer.cpp
+++ b/assignment-client/src/audio/AudioMixer.cpp
@@ -67,7 +67,11 @@ void attachNewBufferToNode(Node *newNode) {
AudioMixer::AudioMixer(const QByteArray& packet) :
ThreadedAssignment(packet),
_trailingSleepRatio(1.0f),
- _minAudibilityThreshold(LOUDNESS_TO_DISTANCE_RATIO / 2.0f)
+ _minAudibilityThreshold(LOUDNESS_TO_DISTANCE_RATIO / 2.0f),
+ _performanceThrottling(0.0f),
+ _numStatFrames(0),
+ _sumListeners(0),
+ _sumMixes(0)
{
}
@@ -95,6 +99,8 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf
return;
}
+ ++_sumMixes;
+
glm::quat inverseOrientation = glm::inverse(listeningNodeBuffer->getOrientation());
float distanceSquareToSource = glm::dot(relativePosition, relativePosition);
@@ -352,8 +358,21 @@ void AudioMixer::readPendingDatagrams() {
void AudioMixer::sendStatsPacket() {
static QJsonObject statsObject;
- statsObject["trailing_sleep"] = _trailingSleepRatio;
- statsObject["min_audability_threshold"] = _minAudibilityThreshold;
+ statsObject["trailing_sleep_percentage"] = _trailingSleepRatio * 100.0f;
+ statsObject["performance_throttling"] = _performanceThrottling;
+
+ statsObject["average_listeners_per_frame"] = _sumListeners / (float) _numStatFrames;
+
+ if (_sumListeners > 0) {
+ statsObject["average_mixes_per_listener"] = _sumMixes / (float) _sumListeners;
+ } else {
+ statsObject["average_mixes_per_listener"] = 0.0;
+ }
+
+
+ _sumListeners = 0;
+ _sumMixes = 0;
+ _numStatFrames = 0;
NodeList::getInstance()->sendStatsToDomainServer(statsObject);
}
@@ -382,7 +401,6 @@ void AudioMixer::run() {
+ numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio)];
int usecToSleep = BUFFER_SEND_INTERVAL_USECS;
- float audabilityCutoffRatio = 0;
const int TRAILING_AVERAGE_FRAMES = 100;
int framesSinceCutoffEvent = TRAILING_AVERAGE_FRAMES;
@@ -410,7 +428,7 @@ void AudioMixer::run() {
_trailingSleepRatio = (PREVIOUS_FRAMES_RATIO * _trailingSleepRatio)
+ (usecToSleep * CURRENT_FRAME_RATIO / (float) BUFFER_SEND_INTERVAL_USECS);
- float lastCutoffRatio = audabilityCutoffRatio;
+ float lastCutoffRatio = _performanceThrottling;
bool hasRatioChanged = false;
if (framesSinceCutoffEvent >= TRAILING_AVERAGE_FRAMES) {
@@ -420,27 +438,27 @@ void AudioMixer::run() {
if (_trailingSleepRatio <= STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD) {
// we're struggling - change our min required loudness to reduce some load
- audabilityCutoffRatio = audabilityCutoffRatio + (0.5f * (1.0f - audabilityCutoffRatio));
+ _performanceThrottling = _performanceThrottling + (0.5f * (1.0f - _performanceThrottling));
qDebug() << "Mixer is struggling, sleeping" << _trailingSleepRatio * 100 << "% of frame time. Old cutoff was"
- << lastCutoffRatio << "and is now" << audabilityCutoffRatio;
+ << lastCutoffRatio << "and is now" << _performanceThrottling;
hasRatioChanged = true;
- } else if (_trailingSleepRatio >= BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD && audabilityCutoffRatio != 0) {
+ } else if (_trailingSleepRatio >= BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD && _performanceThrottling != 0) {
// we've recovered and can back off the required loudness
- audabilityCutoffRatio = audabilityCutoffRatio - RATIO_BACK_OFF;
+ _performanceThrottling = _performanceThrottling - RATIO_BACK_OFF;
- if (audabilityCutoffRatio < 0) {
- audabilityCutoffRatio = 0;
+ if (_performanceThrottling < 0) {
+ _performanceThrottling = 0;
}
qDebug() << "Mixer is recovering, sleeping" << _trailingSleepRatio * 100 << "% of frame time. Old cutoff was"
- << lastCutoffRatio << "and is now" << audabilityCutoffRatio;
+ << lastCutoffRatio << "and is now" << _performanceThrottling;
hasRatioChanged = true;
}
if (hasRatioChanged) {
// set out min audability threshold from the new ratio
- _minAudibilityThreshold = LOUDNESS_TO_DISTANCE_RATIO / (2.0f * (1.0f - audabilityCutoffRatio));
+ _minAudibilityThreshold = LOUDNESS_TO_DISTANCE_RATIO / (2.0f * (1.0f - _performanceThrottling));
qDebug() << "Minimum audability required to be mixed is now" << _minAudibilityThreshold;
framesSinceCutoffEvent = 0;
@@ -460,6 +478,8 @@ void AudioMixer::run() {
memcpy(clientMixBuffer + numBytesPacketHeader, _clientSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO);
nodeList->writeDatagram(clientMixBuffer, NETWORK_BUFFER_LENGTH_BYTES_STEREO + numBytesPacketHeader, node);
+
+ ++_sumListeners;
}
}
@@ -470,6 +490,8 @@ void AudioMixer::run() {
}
}
+ ++_numStatFrames;
+
QCoreApplication::processEvents();
if (_isFinished) {
diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h
index 0f88701303..0b1de6f069 100644
--- a/assignment-client/src/audio/AudioMixer.h
+++ b/assignment-client/src/audio/AudioMixer.h
@@ -44,6 +44,10 @@ private:
float _trailingSleepRatio;
float _minAudibilityThreshold;
+ float _performanceThrottling;
+ int _numStatFrames;
+ int _sumListeners;
+ int _sumMixes;
};
#endif /* defined(__hifi__AudioMixer__) */
diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp
index d4dfa80724..4990de2b55 100644
--- a/assignment-client/src/octree/OctreeServer.cpp
+++ b/assignment-client/src/octree/OctreeServer.cpp
@@ -236,7 +236,7 @@ void OctreeServer::initHTTPManager(int port) {
_httpManager = new HTTPManager(port, documentRoot, this, this);
}
-bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString& path) {
+bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url) {
#ifdef FORCE_CRASH
if (connection->requestOperation() == QNetworkAccessManager::GetOperation
@@ -259,9 +259,9 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
bool showStats = false;
if (connection->requestOperation() == QNetworkAccessManager::GetOperation) {
- if (path == "/") {
+ if (url.path() == "/") {
showStats = true;
- } else if (path == "/resetStats") {
+ } else if (url.path() == "/resetStats") {
_octreeInboundPacketProcessor->resetStats();
resetSendingStats();
showStats = true;
diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h
index 12091170d9..2664499b6a 100644
--- a/assignment-client/src/octree/OctreeServer.h
+++ b/assignment-client/src/octree/OctreeServer.h
@@ -97,7 +97,7 @@ public:
static void trackPacketSendingTime(float time);
static float getAveragePacketSendingTime() { return _averagePacketSendingTime.getAverage(); }
- bool handleHTTPRequest(HTTPConnection* connection, const QString& path);
+ bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url);
virtual void aboutToFinish();
diff --git a/domain-server/resources/web/footer.html b/domain-server/resources/web/footer.html
index 08ea9fba66..d1a3fc29e8 100644
--- a/domain-server/resources/web/footer.html
+++ b/domain-server/resources/web/footer.html
@@ -1,3 +1,3 @@
-
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/domain-server/resources/web/header.html b/domain-server/resources/web/header.html
index 83d7ae5c23..2be603b00e 100644
--- a/domain-server/resources/web/header.html
+++ b/domain-server/resources/web/header.html
@@ -4,8 +4,8 @@
domain-server
-
-
+
+
\ No newline at end of file
diff --git a/domain-server/resources/web/js/tables.js b/domain-server/resources/web/js/tables.js
index e32f78a63e..ae5095592b 100644
--- a/domain-server/resources/web/js/tables.js
+++ b/domain-server/resources/web/js/tables.js
@@ -7,7 +7,7 @@ $(document).ready(function(){
$.each(json.nodes, function (uuid, data) {
nodesTableBody += "
";
nodesTableBody += "" + data.type + " | ";
- nodesTableBody += "" + uuid + " | ";
+ nodesTableBody += "" + uuid + " | ";
nodesTableBody += "" + (data.pool ? data.pool : "") + " | ";
nodesTableBody += "" + data.public.ip + ":" + data.public.port + " | ";
nodesTableBody += "" + data.local.ip + ":" + data.local.port + " | ";
diff --git a/domain-server/resources/web/stats/index.shtml b/domain-server/resources/web/stats/index.shtml
new file mode 100644
index 0000000000..62115d18fe
--- /dev/null
+++ b/domain-server/resources/web/stats/index.shtml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/domain-server/resources/web/stats/js/stats.js b/domain-server/resources/web/stats/js/stats.js
new file mode 100644
index 0000000000..e82668ea9e
--- /dev/null
+++ b/domain-server/resources/web/stats/js/stats.js
@@ -0,0 +1,31 @@
+function qs(key) {
+ key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars
+ var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
+ return match && decodeURIComponent(match[1].replace(/\+/g, " "));
+}
+
+$(document).ready(function(){
+ // setup a function to grab the nodeStats
+ function getNodeStats() {
+
+ var uuid = qs("uuid");
+
+ var statsTableBody = "";
+
+ $.getJSON("/nodes/" + uuid + ".json", function(json){
+ $.each(json, function (key, value) {
+ statsTableBody += "
";
+ statsTableBody += "" + key + " | ";
+ statsTableBody += "" + value + " | ";
+ statsTableBody += "
";
+ });
+
+ $('#stats-table tbody').html(statsTableBody);
+ });
+ }
+
+ // do the first GET on page load
+ getNodeStats();
+ // grab the new assignments JSON every second
+ var getNodeStatsInterval = setInterval(getNodeStats, 1000);
+});
diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp
index 1b867501d2..0a8b70a673 100644
--- a/domain-server/src/DomainServer.cpp
+++ b/domain-server/src/DomainServer.cpp
@@ -651,14 +651,14 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
return nodeJson;
}
-bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString& path) {
+bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url) {
const QString JSON_MIME_TYPE = "application/json";
const QString URI_ASSIGNMENT = "/assignment";
const QString URI_NODES = "/nodes";
if (connection->requestOperation() == QNetworkAccessManager::GetOperation) {
- if (path == "/assignments.json") {
+ if (url.path() == "/assignments.json") {
// user is asking for json list of assignments
// setup the JSON
@@ -702,7 +702,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
// we've processed this request
return true;
- } else if (path == QString("%1.json").arg(URI_NODES)) {
+ } else if (url.path() == QString("%1.json").arg(URI_NODES)) {
// setup the JSON
QJsonObject rootJSON;
QJsonObject nodesJSON;
@@ -727,10 +727,10 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
return true;
} else {
const QString NODE_REGEX_STRING =
- QString("\\%1\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\/?$").arg(URI_NODES);
+ QString("\\%1\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}).json\\/?$").arg(URI_NODES);
QRegExp nodeShowRegex(NODE_REGEX_STRING);
- if (nodeShowRegex.indexIn(path) != -1) {
+ if (nodeShowRegex.indexIn(url.path()) != -1) {
QUuid matchingUUID = QUuid(nodeShowRegex.cap(1));
// see if we have a node that matches this ID
@@ -740,7 +740,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
QJsonDocument statsDocument(reinterpret_cast
(matchingNode->getLinkedData())
->getStatsJSONObject());
- // send the resposne
+ // send the response
connection->respond(HTTPConnection::StatusCode200, statsDocument.toJson(), qPrintable(JSON_MIME_TYPE));
// tell the caller we processed the request
@@ -749,7 +749,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
}
}
} else if (connection->requestOperation() == QNetworkAccessManager::PostOperation) {
- if (path == URI_ASSIGNMENT) {
+ if (url.path() == URI_ASSIGNMENT) {
// this is a script upload - ask the HTTPConnection to parse the form data
QList formData = connection->parseFormData();
@@ -796,11 +796,11 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
return true;
}
} else if (connection->requestOperation() == QNetworkAccessManager::DeleteOperation) {
- if (path.startsWith(URI_NODES)) {
+ if (url.path().startsWith(URI_NODES)) {
// this is a request to DELETE a node by UUID
// pull the UUID from the url
- QUuid deleteUUID = QUuid(path.mid(URI_NODES.size() + sizeof('/')));
+ QUuid deleteUUID = QUuid(url.path().mid(URI_NODES.size() + sizeof('/')));
if (!deleteUUID.isNull()) {
SharedNodePointer nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);
diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h
index 2d253cc41c..597be7f50d 100644
--- a/domain-server/src/DomainServer.h
+++ b/domain-server/src/DomainServer.h
@@ -30,7 +30,7 @@ public:
bool requiresAuthentication() const { return !_nodeAuthenticationURL.isEmpty(); }
- bool handleHTTPRequest(HTTPConnection* connection, const QString& path);
+ bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url);
void exit(int retCode = 0);
diff --git a/examples/audioDeviceExample.js b/examples/audioDeviceExample.js
new file mode 100644
index 0000000000..1ee00a1582
--- /dev/null
+++ b/examples/audioDeviceExample.js
@@ -0,0 +1,52 @@
+//
+// audioDeviceExample.js
+// hifi
+//
+// Created by Brad Hefta-Gaub on 3/22/14
+// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
+//
+// This is an example script that demonstrates use of the Menu object
+//
+
+
+var outputDevices = AudioDevice.getOutputDevices();
+var defaultOutputDevice = AudioDevice.getDefaultOutputDevice();
+var selectOutputDevice = outputDevices[0];
+print("Output Devices:");
+for(var i = 0; i < outputDevices.length; i++) {
+ if (outputDevices[i] == defaultOutputDevice) {
+ print(" " + outputDevices[i] + " << default");
+ } else {
+ print(" " + outputDevices[i]);
+ }
+}
+
+print("Default Output Device:" + defaultOutputDevice);
+print("Selected Output Device:" + selectOutputDevice);
+print("Current Audio Output Device: " + AudioDevice.getOutputDevice());
+AudioDevice.setOutputDevice(selectOutputDevice);
+print("Audio Output Device: " + AudioDevice.getOutputDevice());
+
+var inputDevices = AudioDevice.getInputDevices();
+var selectInputDevice = inputDevices[0];
+var defaultInputDevice = AudioDevice.getDefaultInputDevice();
+print("Input Devices:");
+for(var i = 0; i < inputDevices.length; i++) {
+ if (inputDevices[i] == defaultInputDevice) {
+ print(" " + inputDevices[i] + " << default");
+ } else {
+ print(" " + inputDevices[i]);
+ }
+}
+
+print("Default Input Device:" + defaultInputDevice);
+print("Selected Input Device:" + selectInputDevice);
+print("Current Audio Input Device: " + AudioDevice.getInputDevice());
+AudioDevice.setInputDevice(selectInputDevice);
+print("Audio Input Device: " + AudioDevice.getInputDevice());
+
+print("Audio Input Device Level: " + AudioDevice.getInputVolume());
+AudioDevice.setInputVolume(AudioDevice.getInputVolume() * 2); // twice as loud!
+print("Audio Input Device Level: " + AudioDevice.getInputVolume());
+
+Script.stop();
\ No newline at end of file
diff --git a/examples/settingsExample.js b/examples/settingsExample.js
new file mode 100644
index 0000000000..0dcc5482b6
--- /dev/null
+++ b/examples/settingsExample.js
@@ -0,0 +1,18 @@
+//
+// settingsExample.js
+// hifi
+//
+// Created by Brad Hefta-Gaub on 3/22/14
+// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
+//
+// This is an example script that demonstrates use of the Menu object
+//
+
+
+
+
+print("mySetting: " + Settings.getValue("mySetting"));
+Settings.setValue("mySetting", "spam");
+print("mySetting: " + Settings.getValue("mySetting"));
+
+Script.stop();
\ No newline at end of file
diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt
index 7126e8929f..f991212a6e 100644
--- a/interface/CMakeLists.txt
+++ b/interface/CMakeLists.txt
@@ -48,7 +48,7 @@ configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVe
# grab the implementation and header files from src dirs
file(GLOB INTERFACE_SRCS src/*.cpp src/*.h)
-foreach(SUBDIR avatar devices renderer ui starfield location)
+foreach(SUBDIR avatar devices renderer ui starfield location scripting voxels)
file(GLOB_RECURSE SUBDIR_SRCS src/${SUBDIR}/*.cpp src/${SUBDIR}/*.h)
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${SUBDIR_SRCS}")
endforeach(SUBDIR)
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index e896160b65..c36e9a77db 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -65,17 +65,21 @@
#include
#include "Application.h"
-#include "ClipboardScriptingInterface.h"
#include "InterfaceVersion.h"
#include "Menu.h"
-#include "MenuScriptingInterface.h"
#include "Util.h"
#include "devices/OculusManager.h"
#include "devices/TV3DManager.h"
#include "renderer/ProgramObject.h"
-#include "ui/TextRenderer.h"
-#include "InfoView.h"
+
+#include "scripting/AudioDeviceScriptingInterface.h"
+#include "scripting/ClipboardScriptingInterface.h"
+#include "scripting/MenuScriptingInterface.h"
+#include "scripting/SettingsScriptingInterface.h"
+
+#include "ui/InfoView.h"
#include "ui/Snapshot.h"
+#include "ui/TextRenderer.h"
using namespace std;
@@ -3559,6 +3563,8 @@ void Application::loadScript(const QString& fileNameString) {
scriptEngine->registerGlobalObject("Overlays", &_overlays);
scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
+ scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
+ scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance());
QThread* workerThread = new QThread(this);
diff --git a/interface/src/Application.h b/interface/src/Application.h
index 93a5044124..caeea529af 100644
--- a/interface/src/Application.h
+++ b/interface/src/Application.h
@@ -29,12 +29,12 @@
#include
#include
#include
+#include
+#include
#include "Audio.h"
-#include "BandwidthMeter.h"
#include "BuckyBalls.h"
#include "Camera.h"
-#include "ControllerScriptingInterface.h"
#include "DatagramProcessor.h"
#include "Environment.h"
#include "FileLogger.h"
@@ -44,13 +44,6 @@
#include "PacketHeaders.h"
#include "ParticleTreeRenderer.h"
#include "Stars.h"
-#include "ViewFrustum.h"
-#include "VoxelFade.h"
-#include "VoxelEditPacketSender.h"
-#include "VoxelHideShowThread.h"
-#include "VoxelPacketProcessor.h"
-#include "VoxelSystem.h"
-#include "VoxelImporter.h"
#include "avatar/Avatar.h"
#include "avatar/AvatarManager.h"
#include "avatar/MyAvatar.h"
@@ -63,13 +56,20 @@
#include "renderer/PointShader.h"
#include "renderer/TextureCache.h"
#include "renderer/VoxelShader.h"
+#include "scripting/ControllerScriptingInterface.h"
#include "ui/BandwidthDialog.h"
+#include "ui/BandwidthMeter.h"
#include "ui/OctreeStatsDialog.h"
#include "ui/RearMirrorTools.h"
#include "ui/LodToolsDialog.h"
#include "ui/LogDialog.h"
#include "ui/UpdateDialog.h"
-#include "ui/Overlays.h"
+#include "ui/overlays/Overlays.h"
+#include "voxels/VoxelFade.h"
+#include "voxels/VoxelHideShowThread.h"
+#include "voxels/VoxelImporter.h"
+#include "voxels/VoxelPacketProcessor.h"
+#include "voxels/VoxelSystem.h"
class QAction;
@@ -172,7 +172,11 @@ public:
Visage* getVisage() { return &_visage; }
SixenseManager* getSixenseManager() { return &_sixenseManager; }
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
- QSettings* getSettings() { return _settings; }
+
+ /// if you need to access the application settings, use lockSettings()/unlockSettings()
+ QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
+ void unlockSettings() { _settingsMutex.unlock(); }
+
QMainWindow* getWindow() { return _window; }
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); }
@@ -353,6 +357,7 @@ private:
DatagramProcessor _datagramProcessor;
QNetworkAccessManager* _networkAccessManager;
+ QMutex _settingsMutex;
QSettings* _settings;
glm::vec3 _gravity;
diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp
index b684cec46e..734b5345fb 100644
--- a/interface/src/Audio.cpp
+++ b/interface/src/Audio.cpp
@@ -92,6 +92,16 @@ void Audio::reset() {
_ringBuffer.reset();
}
+QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) {
+ QAudioDeviceInfo result;
+ foreach(QAudioDeviceInfo audioDevice, QAudioDeviceInfo::availableDevices(mode)) {
+ if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) {
+ result = audioDevice;
+ }
+ }
+ return result;
+}
+
QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
#ifdef __APPLE__
if (QAudioDeviceInfo::availableDevices(mode).size() > 1) {
@@ -249,27 +259,105 @@ void Audio::start() {
_desiredOutputFormat.setChannelCount(2);
QAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput);
- qDebug() << "The audio input device is" << inputDeviceInfo.deviceName();
+ qDebug() << "The default audio input device is" << inputDeviceInfo.deviceName();
+ bool inputFormatSupported = switchInputToAudioDevice(inputDeviceInfo.deviceName());
+
+ QAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput);
+ qDebug() << "The default audio output device is" << outputDeviceInfo.deviceName();
+ bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo.deviceName());
- if (adjustedFormatForAudioDevice(inputDeviceInfo, _desiredInputFormat, _inputFormat)) {
- qDebug() << "The format to be used for audio input is" << _inputFormat;
+ if (!inputFormatSupported || !outputFormatSupported) {
+ qDebug() << "Unable to set up audio I/O because of a problem with input or output formats.";
+ }
+}
+
+QString Audio::getDefaultDeviceName(QAudio::Mode mode) {
+ QAudioDeviceInfo deviceInfo = defaultAudioDeviceForMode(mode);
+ return deviceInfo.deviceName();
+}
+
+QVector Audio::getDeviceNames(QAudio::Mode mode) {
+ QVector deviceNames;
+ foreach(QAudioDeviceInfo audioDevice, QAudioDeviceInfo::availableDevices(mode)) {
+ deviceNames << audioDevice.deviceName().trimmed();
+ }
+ return deviceNames;
+}
+
+bool Audio::switchInputToAudioDevice(const QString& inputDeviceName) {
+ bool supportedFormat = false;
+
+ // cleanup any previously initialized device
+ if (_audioInput) {
+ _audioInput->stop();
+ disconnect(_inputDevice, 0, 0, 0);
+ _inputDevice = NULL;
+
+ delete _audioInput;
+ _audioInput = NULL;
+ _numInputCallbackBytes = 0;
+
+ _inputAudioDeviceName = "";
+ }
+
+ QAudioDeviceInfo inputDeviceInfo = getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName);
+
+ if (!inputDeviceInfo.isNull()) {
+ qDebug() << "The audio input device " << inputDeviceInfo.deviceName() << "is available.";
+ _inputAudioDeviceName = inputDeviceInfo.deviceName().trimmed();
+
+ if (adjustedFormatForAudioDevice(inputDeviceInfo, _desiredInputFormat, _inputFormat)) {
+ qDebug() << "The format to be used for audio input is" << _inputFormat;
- _audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this);
- _numInputCallbackBytes = NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL * _inputFormat.channelCount()
- * (_inputFormat.sampleRate() / SAMPLE_RATE)
- / CALLBACK_ACCELERATOR_RATIO;
- _audioInput->setBufferSize(_numInputCallbackBytes);
+ _audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this);
+ _numInputCallbackBytes = NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL * _inputFormat.channelCount()
+ * (_inputFormat.sampleRate() / SAMPLE_RATE)
+ / CALLBACK_ACCELERATOR_RATIO;
+ _audioInput->setBufferSize(_numInputCallbackBytes);
- QAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput);
- qDebug() << "The audio output device is" << outputDeviceInfo.deviceName();
-
- if (adjustedFormatForAudioDevice(outputDeviceInfo, _desiredOutputFormat, _outputFormat)) {
- qDebug() << "The format to be used for audio output is" << _outputFormat;
-
+ // how do we want to handle input working, but output not working?
_inputRingBuffer.resizeForFrameSize(_numInputCallbackBytes * CALLBACK_ACCELERATOR_RATIO / sizeof(int16_t));
_inputDevice = _audioInput->start();
connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleAudioInput()));
+ supportedFormat = true;
+ }
+ }
+ return supportedFormat;
+}
+
+bool Audio::switchOutputToAudioDevice(const QString& outputDeviceName) {
+ bool supportedFormat = false;
+
+ // cleanup any previously initialized device
+ if (_audioOutput) {
+ _audioOutput->stop();
+ disconnect(_outputDevice, 0, 0, 0);
+ _outputDevice = NULL;
+
+ delete _audioOutput;
+ _audioOutput = NULL;
+ _numInputCallbackBytes = 0;
+
+ _loopbackOutputDevice = NULL;
+ delete _loopbackAudioOutput;
+ _loopbackAudioOutput = NULL;
+
+ _proceduralOutputDevice = NULL;
+ delete _proceduralAudioOutput;
+ _proceduralAudioOutput = NULL;
+ _outputAudioDeviceName = "";
+ }
+
+ QAudioDeviceInfo outputDeviceInfo = getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName);
+
+ if (!outputDeviceInfo.isNull()) {
+ qDebug() << "The audio output device " << outputDeviceInfo.deviceName() << "is available.";
+ _outputAudioDeviceName = outputDeviceInfo.deviceName().trimmed();
+
+ if (adjustedFormatForAudioDevice(outputDeviceInfo, _desiredOutputFormat, _outputFormat)) {
+ qDebug() << "The format to be used for audio output is" << _outputFormat;
+
// setup our general output device for audio-mixer audio
_audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
_audioOutput->setBufferSize(_ringBuffer.getSampleCapacity() * sizeof(int16_t));
@@ -278,17 +366,15 @@ void Audio::start() {
// setup a loopback audio output device
_loopbackAudioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
-
+
// setup a procedural audio output device
_proceduralAudioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
gettimeofday(&_lastReceiveTime, NULL);
+ supportedFormat = true;
}
-
- return;
}
-
- qDebug() << "Unable to set up audio I/O because of a problem with input or output formats.";
+ return supportedFormat;
}
void Audio::handleAudioInput() {
@@ -309,13 +395,15 @@ void Audio::handleAudioInput() {
if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio) && !_muted) {
// if this person wants local loopback add that to the locally injected audio
- if (!_loopbackOutputDevice) {
+ if (!_loopbackOutputDevice && _loopbackAudioOutput) {
// we didn't have the loopback output device going so set that up now
_loopbackOutputDevice = _loopbackAudioOutput->start();
}
if (_inputFormat == _outputFormat) {
- _loopbackOutputDevice->write(inputByteArray);
+ if (_loopbackOutputDevice) {
+ _loopbackOutputDevice->write(inputByteArray);
+ }
} else {
static float loopbackOutputToInputRatio = (_outputFormat.sampleRate() / (float) _inputFormat.sampleRate())
* (_outputFormat.channelCount() / _inputFormat.channelCount());
@@ -326,7 +414,9 @@ void Audio::handleAudioInput() {
inputByteArray.size() / sizeof(int16_t),
loopBackByteArray.size() / sizeof(int16_t), _inputFormat, _outputFormat);
- _loopbackOutputDevice->write(loopBackByteArray);
+ if (_loopbackOutputDevice) {
+ _loopbackOutputDevice->write(loopBackByteArray);
+ }
}
}
@@ -455,7 +545,7 @@ void Audio::handleAudioInput() {
addProceduralSounds(monoAudioSamples,
NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
- if (!_proceduralOutputDevice) {
+ if (!_proceduralOutputDevice && _proceduralAudioOutput) {
_proceduralOutputDevice = _proceduralAudioOutput->start();
}
@@ -469,7 +559,9 @@ void Audio::handleAudioInput() {
NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 4,
_desiredInputFormat, _outputFormat);
- _proceduralOutputDevice->write(proceduralOutput);
+ if (_proceduralOutputDevice) {
+ _proceduralOutputDevice->write(proceduralOutput);
+ }
NodeList* nodeList = NodeList::getInstance();
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
@@ -553,7 +645,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
static float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float) _outputFormat.sampleRate())
* (_desiredOutputFormat.channelCount() / (float) _outputFormat.channelCount());
- if (!_ringBuffer.isStarved() && _audioOutput->bytesFree() == _audioOutput->bufferSize()) {
+ if (!_ringBuffer.isStarved() && _audioOutput && _audioOutput->bytesFree() == _audioOutput->bufferSize()) {
// we don't have any audio data left in the output buffer
// we just starved
//qDebug() << "Audio output just starved.";
diff --git a/interface/src/Audio.h b/interface/src/Audio.h
index 880391d7f3..7aa1ef5afe 100644
--- a/interface/src/Audio.h
+++ b/interface/src/Audio.h
@@ -19,17 +19,20 @@
#include "InterfaceConfig.h"
+#include
+#include
+#include
#include
#include
#include
+#include
#include
#include
#include
-#include "Oscilloscope.h"
+#include "ui/Oscilloscope.h"
-#include
static const int NUM_AUDIO_CHANNELS = 2;
@@ -72,7 +75,7 @@ public:
int getNetworkSampleRate() { return SAMPLE_RATE; }
int getNetworkBufferLengthSamplesPerChannel() { return NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; }
-
+
public slots:
void start();
void addReceivedAudioToBuffer(const QByteArray& audioByteArray);
@@ -83,10 +86,21 @@ public slots:
virtual void handleAudioByteArray(const QByteArray& audioByteArray);
+ bool switchInputToAudioDevice(const QString& inputDeviceName);
+ bool switchOutputToAudioDevice(const QString& outputDeviceName);
+ QString getDeviceName(QAudio::Mode mode) const { return (mode == QAudio::AudioInput) ?
+ _inputAudioDeviceName : _outputAudioDeviceName; }
+ QString getDefaultDeviceName(QAudio::Mode mode);
+ QVector getDeviceNames(QAudio::Mode mode);
+
+ float getInputVolume() const { return (_audioInput) ? _audioInput->volume() : 0.0f; }
+ void setInputVolume(float volume) { if (_audioInput) _audioInput->setVolume(volume); }
+
signals:
bool muteToggled();
private:
+
QByteArray firstInputFrame;
QAudioInput* _audioInput;
QAudioFormat _desiredInputFormat;
@@ -105,6 +119,9 @@ private:
QIODevice* _proceduralOutputDevice;
AudioRingBuffer _inputRingBuffer;
AudioRingBuffer _ringBuffer;
+
+ QString _inputAudioDeviceName;
+ QString _outputAudioDeviceName;
Oscilloscope* _scope;
StDev _stdev;
diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp
index e62c7e1102..6eb03021b3 100644
--- a/interface/src/Menu.cpp
+++ b/interface/src/Menu.cpp
@@ -33,11 +33,11 @@
#include "Application.h"
#include "Menu.h"
-#include "MenuScriptingInterface.h"
+#include "scripting/MenuScriptingInterface.h"
#include "Util.h"
-#include "InfoView.h"
+#include "ui/InfoView.h"
#include "ui/MetavoxelEditor.h"
-#include "ModelBrowser.h"
+#include "ui/ModelBrowser.h"
Menu* Menu::_instance = NULL;
@@ -374,8 +374,10 @@ Menu::~Menu() {
}
void Menu::loadSettings(QSettings* settings) {
+ bool lockedSettings = false;
if (!settings) {
- settings = Application::getInstance()->getSettings();
+ settings = Application::getInstance()->lockSettings();
+ lockedSettings = true;
}
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
@@ -404,11 +406,17 @@ void Menu::loadSettings(QSettings* settings) {
// TODO: cache more settings in MyAvatar that are checked with very high frequency.
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
myAvatar->updateCollisionFlags();
+
+ if (lockedSettings) {
+ Application::getInstance()->unlockSettings();
+ }
}
void Menu::saveSettings(QSettings* settings) {
+ bool lockedSettings = false;
if (!settings) {
- settings = Application::getInstance()->getSettings();
+ settings = Application::getInstance()->lockSettings();
+ lockedSettings = true;
}
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
@@ -430,6 +438,9 @@ void Menu::saveSettings(QSettings* settings) {
Application::getInstance()->getAvatar()->saveData(settings);
NodeList::getInstance()->saveData(settings);
+ if (lockedSettings) {
+ Application::getInstance()->unlockSettings();
+ }
}
void Menu::importSettings() {
diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp
index 43a1787d13..77586dd7ae 100644
--- a/interface/src/avatar/Hand.cpp
+++ b/interface/src/avatar/Hand.cpp
@@ -27,10 +27,7 @@ Hand::Hand(Avatar* owningAvatar) :
HandData((AvatarData*)owningAvatar),
_owningAvatar(owningAvatar),
- _renderAlpha(1.0),
- _collisionCenter(0,0,0),
- _collisionAge(0),
- _collisionDuration(0)
+ _renderAlpha(1.0)
{
}
@@ -42,10 +39,6 @@ void Hand::reset() {
void Hand::simulate(float deltaTime, bool isMine) {
- if (_collisionAge > 0.f) {
- _collisionAge += deltaTime;
- }
-
calculateGeometry();
if (isMine) {
@@ -222,26 +215,6 @@ void Hand::collideAgainstOurself() {
}
}
-void Hand::handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime) {
- // Collision between finger and a voxel plays sound
- const float LOWEST_FREQUENCY = 100.f;
- const float HERTZ_PER_RGB = 3.f;
- const float DECAY_PER_SAMPLE = 0.0005f;
- const float DURATION_MAX = 2.0f;
- const float MIN_VOLUME = 0.1f;
- float volume = MIN_VOLUME + glm::clamp(glm::length(palm->getRawVelocity()), 0.f, (1.f - MIN_VOLUME));
- float duration = volume;
- _collisionCenter = fingerTipPosition;
- _collisionAge = deltaTime;
- _collisionDuration = duration;
- int voxelBrightness = voxel->getColor()[0] + voxel->getColor()[1] + voxel->getColor()[2];
- float frequency = LOWEST_FREQUENCY + (voxelBrightness * HERTZ_PER_RGB);
- Application::getInstance()->getAudio()->startDrumSound(volume,
- frequency,
- DURATION_MAX,
- DECAY_PER_SAMPLE);
-}
-
void Hand::calculateGeometry() {
// generate finger tip balls....
_leapFingerTipBalls.clear();
@@ -312,21 +285,6 @@ void Hand::render(bool isMine) {
renderLeapHands(isMine);
}
- if (isMine) {
- // If hand/voxel collision has happened, render a little expanding sphere
- if (_collisionAge > 0.f) {
- float opacity = glm::clamp(1.f - (_collisionAge / _collisionDuration), 0.f, 1.f);
- glColor4f(1, 0, 0, 0.5 * opacity);
- glPushMatrix();
- glTranslatef(_collisionCenter.x, _collisionCenter.y, _collisionCenter.z);
- glutSolidSphere(_collisionAge * 0.25f, 20, 20);
- glPopMatrix();
- if (_collisionAge > _collisionDuration) {
- _collisionAge = 0.f;
- }
- }
- }
-
glEnable(GL_DEPTH_TEST);
glEnable(GL_RESCALE_NORMAL);
diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h
index a1b1875424..f6ee5b281f 100755
--- a/interface/src/avatar/Hand.h
+++ b/interface/src/avatar/Hand.h
@@ -22,7 +22,6 @@
#include "InterfaceConfig.h"
#include "world.h"
-#include "VoxelSystem.h"
class Avatar;
@@ -72,13 +71,6 @@ private:
std::vector _leapFingerTipBalls;
std::vector _leapFingerRootBalls;
- glm::vec3 _lastFingerAddVoxel, _lastFingerDeleteVoxel;
- VoxelDetail _collidingVoxel;
-
- glm::vec3 _collisionCenter;
- float _collisionAge;
- float _collisionDuration;
-
// private methods
void setLeapHands(const std::vector& handPositions,
const std::vector& handNormals);
@@ -88,8 +80,6 @@ private:
void calculateGeometry();
- void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime);
-
void playSlaps(PalmData& palm, Avatar* avatar);
};
diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index 711e1d32c3..19d15fb803 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -26,7 +26,6 @@
#include "Menu.h"
#include "MyAvatar.h"
#include "Physics.h"
-#include "VoxelSystem.h"
#include "devices/Faceshift.h"
#include "devices/OculusManager.h"
#include "ui/TextRenderer.h"
diff --git a/interface/src/scripting/AudioDeviceScriptingInterface.cpp b/interface/src/scripting/AudioDeviceScriptingInterface.cpp
new file mode 100644
index 0000000000..a184e8a2f6
--- /dev/null
+++ b/interface/src/scripting/AudioDeviceScriptingInterface.cpp
@@ -0,0 +1,69 @@
+//
+// AudioDeviceScriptingInterface.cpp
+// hifi
+//
+// Created by Brad Hefta-Gaub on 3/23/14
+// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
+//
+
+#include "Application.h"
+#include "AudioDeviceScriptingInterface.h"
+
+
+AudioDeviceScriptingInterface* AudioDeviceScriptingInterface::getInstance() {
+ static AudioDeviceScriptingInterface sharedInstance;
+ return &sharedInstance;
+}
+
+bool AudioDeviceScriptingInterface::setInputDevice(const QString& deviceName) {
+ bool result;
+ QMetaObject::invokeMethod(Application::getInstance()->getAudio(), "switchInputToAudioDevice",
+ Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(bool, result),
+ Q_ARG(const QString&, deviceName));
+
+ return result;
+}
+
+bool AudioDeviceScriptingInterface::setOutputDevice(const QString& deviceName) {
+ bool result;
+ QMetaObject::invokeMethod(Application::getInstance()->getAudio(), "switchOutputToAudioDevice",
+ Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(bool, result),
+ Q_ARG(const QString&, deviceName));
+
+ return result;
+}
+
+QString AudioDeviceScriptingInterface::getInputDevice() {
+ return Application::getInstance()->getAudio()->getDeviceName(QAudio::AudioInput);
+}
+
+QString AudioDeviceScriptingInterface::getOutputDevice() {
+ return Application::getInstance()->getAudio()->getDeviceName(QAudio::AudioOutput);
+}
+
+QString AudioDeviceScriptingInterface::getDefaultInputDevice() {
+ return Application::getInstance()->getAudio()->getDefaultDeviceName(QAudio::AudioInput);
+}
+
+QString AudioDeviceScriptingInterface::getDefaultOutputDevice() {
+ return Application::getInstance()->getAudio()->getDefaultDeviceName(QAudio::AudioOutput);
+}
+
+QVector AudioDeviceScriptingInterface::getInputDevices() {
+ return Application::getInstance()->getAudio()->getDeviceNames(QAudio::AudioInput);
+}
+
+QVector AudioDeviceScriptingInterface::getOutputDevices() {
+ return Application::getInstance()->getAudio()->getDeviceNames(QAudio::AudioOutput);
+}
+
+
+float AudioDeviceScriptingInterface::getInputVolume() {
+ return Application::getInstance()->getAudio()->getInputVolume();
+}
+
+void AudioDeviceScriptingInterface::setInputVolume(float volume) {
+ Application::getInstance()->getAudio()->setInputVolume(volume);
+}
diff --git a/interface/src/scripting/AudioDeviceScriptingInterface.h b/interface/src/scripting/AudioDeviceScriptingInterface.h
new file mode 100644
index 0000000000..adc86cb15c
--- /dev/null
+++ b/interface/src/scripting/AudioDeviceScriptingInterface.h
@@ -0,0 +1,41 @@
+//
+// AudioDeviceScriptingInterface.h
+// hifi
+//
+// Created by Brad Hefta-Gaub on 3/22/14
+// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
+//
+
+#ifndef __hifi__AudioDeviceScriptingInterface__
+#define __hifi__AudioDeviceScriptingInterface__
+
+#include
+#include
+#include
+
+#include "Application.h"
+
+class AudioDeviceScriptingInterface : public QObject {
+ Q_OBJECT
+ AudioDeviceScriptingInterface() { };
+public:
+ static AudioDeviceScriptingInterface* getInstance();
+
+public slots:
+ bool setInputDevice(const QString& deviceName);
+ bool setOutputDevice(const QString& deviceName);
+
+ QString getInputDevice();
+ QString getOutputDevice();
+
+ QString getDefaultInputDevice();
+ QString getDefaultOutputDevice();
+
+ QVector getInputDevices();
+ QVector getOutputDevices();
+
+ float getInputVolume();
+ void setInputVolume(float volume);
+};
+
+#endif /* defined(__hifi__AudioDeviceScriptingInterface__) */
diff --git a/interface/src/ClipboardScriptingInterface.cpp b/interface/src/scripting/ClipboardScriptingInterface.cpp
similarity index 100%
rename from interface/src/ClipboardScriptingInterface.cpp
rename to interface/src/scripting/ClipboardScriptingInterface.cpp
diff --git a/interface/src/ClipboardScriptingInterface.h b/interface/src/scripting/ClipboardScriptingInterface.h
similarity index 100%
rename from interface/src/ClipboardScriptingInterface.h
rename to interface/src/scripting/ClipboardScriptingInterface.h
diff --git a/interface/src/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp
similarity index 100%
rename from interface/src/ControllerScriptingInterface.cpp
rename to interface/src/scripting/ControllerScriptingInterface.cpp
diff --git a/interface/src/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h
similarity index 100%
rename from interface/src/ControllerScriptingInterface.h
rename to interface/src/scripting/ControllerScriptingInterface.h
diff --git a/interface/src/MenuScriptingInterface.cpp b/interface/src/scripting/MenuScriptingInterface.cpp
similarity index 100%
rename from interface/src/MenuScriptingInterface.cpp
rename to interface/src/scripting/MenuScriptingInterface.cpp
diff --git a/interface/src/MenuScriptingInterface.h b/interface/src/scripting/MenuScriptingInterface.h
similarity index 100%
rename from interface/src/MenuScriptingInterface.h
rename to interface/src/scripting/MenuScriptingInterface.h
diff --git a/interface/src/scripting/SettingsScriptingInterface.cpp b/interface/src/scripting/SettingsScriptingInterface.cpp
new file mode 100644
index 0000000000..2a788c2776
--- /dev/null
+++ b/interface/src/scripting/SettingsScriptingInterface.cpp
@@ -0,0 +1,36 @@
+//
+// SettingsScriptingInterface.cpp
+// hifi
+//
+// Created by Brad Hefta-Gaub on 2/25/14
+// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
+//
+
+#include "Application.h"
+#include "SettingsScriptingInterface.h"
+
+
+SettingsScriptingInterface* SettingsScriptingInterface::getInstance() {
+ static SettingsScriptingInterface sharedInstance;
+ return &sharedInstance;
+}
+
+QVariant SettingsScriptingInterface::getValue(const QString& setting) {
+ QSettings* settings = Application::getInstance()->lockSettings();
+ QVariant value = settings->value(setting);
+ Application::getInstance()->unlockSettings();
+ return value;
+}
+
+QVariant SettingsScriptingInterface::getValue(const QString& setting, const QVariant& defaultValue) {
+ QSettings* settings = Application::getInstance()->lockSettings();
+ QVariant value = settings->value(setting, defaultValue);
+ Application::getInstance()->unlockSettings();
+ return value;
+}
+
+void SettingsScriptingInterface::setValue(const QString& setting, const QVariant& value) {
+ QSettings* settings = Application::getInstance()->lockSettings();
+ settings->setValue(setting, value);
+ Application::getInstance()->unlockSettings();
+}
diff --git a/interface/src/scripting/SettingsScriptingInterface.h b/interface/src/scripting/SettingsScriptingInterface.h
new file mode 100644
index 0000000000..12bda2173f
--- /dev/null
+++ b/interface/src/scripting/SettingsScriptingInterface.h
@@ -0,0 +1,30 @@
+//
+// SettingsScriptingInterface.h
+// hifi
+//
+// Created by Brad Hefta-Gaub on 3/22/14
+// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
+//
+
+#ifndef __hifi__SettingsScriptingInterface__
+#define __hifi__SettingsScriptingInterface__
+
+#include
+#include
+#include
+
+#include "Application.h"
+
+class SettingsScriptingInterface : public QObject {
+ Q_OBJECT
+ SettingsScriptingInterface() { };
+public:
+ static SettingsScriptingInterface* getInstance();
+
+public slots:
+ QVariant getValue(const QString& setting);
+ QVariant getValue(const QString& setting, const QVariant& defaultValue);
+ void setValue(const QString& setting, const QVariant& value);
+};
+
+#endif /* defined(__hifi__SettingsScriptingInterface__) */
diff --git a/interface/src/BandwidthMeter.cpp b/interface/src/ui/BandwidthMeter.cpp
similarity index 100%
rename from interface/src/BandwidthMeter.cpp
rename to interface/src/ui/BandwidthMeter.cpp
diff --git a/interface/src/BandwidthMeter.h b/interface/src/ui/BandwidthMeter.h
similarity index 100%
rename from interface/src/BandwidthMeter.h
rename to interface/src/ui/BandwidthMeter.h
diff --git a/interface/src/ImportDialog.cpp b/interface/src/ui/ImportDialog.cpp
similarity index 100%
rename from interface/src/ImportDialog.cpp
rename to interface/src/ui/ImportDialog.cpp
diff --git a/interface/src/ImportDialog.h b/interface/src/ui/ImportDialog.h
similarity index 100%
rename from interface/src/ImportDialog.h
rename to interface/src/ui/ImportDialog.h
diff --git a/interface/src/InfoView.cpp b/interface/src/ui/InfoView.cpp
similarity index 89%
rename from interface/src/InfoView.cpp
rename to interface/src/ui/InfoView.cpp
index fbf63666d8..8ed4da254c 100644
--- a/interface/src/InfoView.cpp
+++ b/interface/src/ui/InfoView.cpp
@@ -38,11 +38,12 @@ void InfoView::forcedShow() {
}
bool InfoView::shouldShow() {
+ bool shouldShow = false;
if (_forced) {
return true;
}
- QSettings* settings = Application::getInstance()->getSettings();
+ QSettings* settings = Application::getInstance()->lockSettings();
QString lastVersion = settings->value(SETTINGS_VERSION_KEY).toString();
@@ -51,10 +52,12 @@ bool InfoView::shouldShow() {
if (version != QString::null && (lastVersion == QString::null || lastVersion != version)) {
settings->setValue(SETTINGS_VERSION_KEY, version);
- return true;
+ shouldShow = true;
} else {
- return false;
- }
+ shouldShow = false;
+ }
+ Application::getInstance()->unlockSettings();
+ return shouldShow;
}
void InfoView::loaded(bool ok) {
diff --git a/interface/src/InfoView.h b/interface/src/ui/InfoView.h
similarity index 100%
rename from interface/src/InfoView.h
rename to interface/src/ui/InfoView.h
diff --git a/interface/src/ModelBrowser.cpp b/interface/src/ui/ModelBrowser.cpp
similarity index 100%
rename from interface/src/ModelBrowser.cpp
rename to interface/src/ui/ModelBrowser.cpp
diff --git a/interface/src/ModelBrowser.h b/interface/src/ui/ModelBrowser.h
similarity index 100%
rename from interface/src/ModelBrowser.h
rename to interface/src/ui/ModelBrowser.h
diff --git a/interface/src/Oscilloscope.cpp b/interface/src/ui/Oscilloscope.cpp
similarity index 100%
rename from interface/src/Oscilloscope.cpp
rename to interface/src/ui/Oscilloscope.cpp
diff --git a/interface/src/Oscilloscope.h b/interface/src/ui/Oscilloscope.h
similarity index 100%
rename from interface/src/Oscilloscope.h
rename to interface/src/ui/Oscilloscope.h
diff --git a/interface/src/ui/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp
similarity index 98%
rename from interface/src/ui/Base3DOverlay.cpp
rename to interface/src/ui/overlays/Base3DOverlay.cpp
index 67e7ea25f2..bcd2ca1cd2 100644
--- a/interface/src/ui/Base3DOverlay.cpp
+++ b/interface/src/ui/overlays/Base3DOverlay.cpp
@@ -12,7 +12,6 @@
#include
#include "Base3DOverlay.h"
-#include "TextRenderer.h"
const glm::vec3 DEFAULT_POSITION = glm::vec3(0.0f, 0.0f, 0.0f);
const float DEFAULT_LINE_WIDTH = 1.0f;
diff --git a/interface/src/ui/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h
similarity index 100%
rename from interface/src/ui/Base3DOverlay.h
rename to interface/src/ui/overlays/Base3DOverlay.h
diff --git a/interface/src/ui/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp
similarity index 100%
rename from interface/src/ui/Cube3DOverlay.cpp
rename to interface/src/ui/overlays/Cube3DOverlay.cpp
diff --git a/interface/src/ui/Cube3DOverlay.h b/interface/src/ui/overlays/Cube3DOverlay.h
similarity index 100%
rename from interface/src/ui/Cube3DOverlay.h
rename to interface/src/ui/overlays/Cube3DOverlay.h
diff --git a/interface/src/ui/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp
similarity index 100%
rename from interface/src/ui/ImageOverlay.cpp
rename to interface/src/ui/overlays/ImageOverlay.cpp
diff --git a/interface/src/ui/ImageOverlay.h b/interface/src/ui/overlays/ImageOverlay.h
similarity index 100%
rename from interface/src/ui/ImageOverlay.h
rename to interface/src/ui/overlays/ImageOverlay.h
diff --git a/interface/src/ui/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp
similarity index 100%
rename from interface/src/ui/Line3DOverlay.cpp
rename to interface/src/ui/overlays/Line3DOverlay.cpp
diff --git a/interface/src/ui/Line3DOverlay.h b/interface/src/ui/overlays/Line3DOverlay.h
similarity index 100%
rename from interface/src/ui/Line3DOverlay.h
rename to interface/src/ui/overlays/Line3DOverlay.h
diff --git a/interface/src/ui/LocalVoxelsOverlay.cpp b/interface/src/ui/overlays/LocalVoxelsOverlay.cpp
similarity index 98%
rename from interface/src/ui/LocalVoxelsOverlay.cpp
rename to interface/src/ui/overlays/LocalVoxelsOverlay.cpp
index 7eaf9ed5c5..460f4eadb6 100644
--- a/interface/src/ui/LocalVoxelsOverlay.cpp
+++ b/interface/src/ui/overlays/LocalVoxelsOverlay.cpp
@@ -12,10 +12,10 @@
#include
#include
-#include
#include
#include "LocalVoxelsOverlay.h"
+#include "voxels/VoxelSystem.h"
QMap LocalVoxelsOverlay::_voxelSystemMap;
diff --git a/interface/src/ui/LocalVoxelsOverlay.h b/interface/src/ui/overlays/LocalVoxelsOverlay.h
similarity index 100%
rename from interface/src/ui/LocalVoxelsOverlay.h
rename to interface/src/ui/overlays/LocalVoxelsOverlay.h
diff --git a/interface/src/ui/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp
similarity index 100%
rename from interface/src/ui/Overlay.cpp
rename to interface/src/ui/overlays/Overlay.cpp
diff --git a/interface/src/ui/Overlay.h b/interface/src/ui/overlays/Overlay.h
similarity index 100%
rename from interface/src/ui/Overlay.h
rename to interface/src/ui/overlays/Overlay.h
diff --git a/interface/src/ui/Overlay2D.cpp b/interface/src/ui/overlays/Overlay2D.cpp
similarity index 100%
rename from interface/src/ui/Overlay2D.cpp
rename to interface/src/ui/overlays/Overlay2D.cpp
diff --git a/interface/src/ui/Overlay2D.h b/interface/src/ui/overlays/Overlay2D.h
similarity index 100%
rename from interface/src/ui/Overlay2D.h
rename to interface/src/ui/overlays/Overlay2D.h
diff --git a/interface/src/ui/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp
similarity index 100%
rename from interface/src/ui/Overlays.cpp
rename to interface/src/ui/overlays/Overlays.cpp
diff --git a/interface/src/ui/Overlays.h b/interface/src/ui/overlays/Overlays.h
similarity index 100%
rename from interface/src/ui/Overlays.h
rename to interface/src/ui/overlays/Overlays.h
diff --git a/interface/src/ui/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp
similarity index 100%
rename from interface/src/ui/Sphere3DOverlay.cpp
rename to interface/src/ui/overlays/Sphere3DOverlay.cpp
diff --git a/interface/src/ui/Sphere3DOverlay.h b/interface/src/ui/overlays/Sphere3DOverlay.h
similarity index 100%
rename from interface/src/ui/Sphere3DOverlay.h
rename to interface/src/ui/overlays/Sphere3DOverlay.h
diff --git a/interface/src/ui/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp
similarity index 98%
rename from interface/src/ui/TextOverlay.cpp
rename to interface/src/ui/overlays/TextOverlay.cpp
index edaec6849a..1a6edb3ea2 100644
--- a/interface/src/ui/TextOverlay.cpp
+++ b/interface/src/ui/overlays/TextOverlay.cpp
@@ -12,7 +12,7 @@
#include
#include "TextOverlay.h"
-#include "TextRenderer.h"
+#include "ui/TextRenderer.h"
TextOverlay::TextOverlay() :
_leftMargin(DEFAULT_MARGIN),
diff --git a/interface/src/ui/TextOverlay.h b/interface/src/ui/overlays/TextOverlay.h
similarity index 100%
rename from interface/src/ui/TextOverlay.h
rename to interface/src/ui/overlays/TextOverlay.h
diff --git a/interface/src/ui/Volume3DOverlay.cpp b/interface/src/ui/overlays/Volume3DOverlay.cpp
similarity index 100%
rename from interface/src/ui/Volume3DOverlay.cpp
rename to interface/src/ui/overlays/Volume3DOverlay.cpp
diff --git a/interface/src/ui/Volume3DOverlay.h b/interface/src/ui/overlays/Volume3DOverlay.h
similarity index 100%
rename from interface/src/ui/Volume3DOverlay.h
rename to interface/src/ui/overlays/Volume3DOverlay.h
diff --git a/interface/src/PrimitiveRenderer.cpp b/interface/src/voxels/PrimitiveRenderer.cpp
similarity index 100%
rename from interface/src/PrimitiveRenderer.cpp
rename to interface/src/voxels/PrimitiveRenderer.cpp
diff --git a/interface/src/PrimitiveRenderer.h b/interface/src/voxels/PrimitiveRenderer.h
similarity index 100%
rename from interface/src/PrimitiveRenderer.h
rename to interface/src/voxels/PrimitiveRenderer.h
diff --git a/interface/src/VoxelFade.cpp b/interface/src/voxels/VoxelFade.cpp
similarity index 100%
rename from interface/src/VoxelFade.cpp
rename to interface/src/voxels/VoxelFade.cpp
diff --git a/interface/src/VoxelFade.h b/interface/src/voxels/VoxelFade.h
similarity index 100%
rename from interface/src/VoxelFade.h
rename to interface/src/voxels/VoxelFade.h
diff --git a/interface/src/VoxelHideShowThread.cpp b/interface/src/voxels/VoxelHideShowThread.cpp
similarity index 100%
rename from interface/src/VoxelHideShowThread.cpp
rename to interface/src/voxels/VoxelHideShowThread.cpp
diff --git a/interface/src/VoxelHideShowThread.h b/interface/src/voxels/VoxelHideShowThread.h
similarity index 100%
rename from interface/src/VoxelHideShowThread.h
rename to interface/src/voxels/VoxelHideShowThread.h
diff --git a/interface/src/VoxelImporter.cpp b/interface/src/voxels/VoxelImporter.cpp
similarity index 97%
rename from interface/src/VoxelImporter.cpp
rename to interface/src/voxels/VoxelImporter.cpp
index 9d8b8ad811..d3c1b259ae 100644
--- a/interface/src/VoxelImporter.cpp
+++ b/interface/src/voxels/VoxelImporter.cpp
@@ -6,13 +6,17 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
-#include
-#include
-#include
+// include this before QGLWidget, which includes an earlier version of OpenGL
+#include "InterfaceConfig.h"
#include
#include
+#include
+#include
+
+#include "voxels/VoxelImporter.h"
+
const QString SETTINGS_GROUP_NAME = "VoxelImport";
const QString IMPORT_DIALOG_SETTINGS_KEY = "ImportDialogSettings";
diff --git a/interface/src/VoxelImporter.h b/interface/src/voxels/VoxelImporter.h
similarity index 93%
rename from interface/src/VoxelImporter.h
rename to interface/src/voxels/VoxelImporter.h
index e77abaf18d..9ebfc2eef2 100644
--- a/interface/src/VoxelImporter.h
+++ b/interface/src/voxels/VoxelImporter.h
@@ -9,12 +9,12 @@
#ifndef __hifi__VoxelImporter__
#define __hifi__VoxelImporter__
-#include
-#include
-
#include
#include
+#include "ui/ImportDialog.h"
+#include "voxels/VoxelSystem.h"
+
class ImportTask;
class VoxelImporter : public QObject {
diff --git a/interface/src/VoxelPacketProcessor.cpp b/interface/src/voxels/VoxelPacketProcessor.cpp
similarity index 100%
rename from interface/src/VoxelPacketProcessor.cpp
rename to interface/src/voxels/VoxelPacketProcessor.cpp
diff --git a/interface/src/VoxelPacketProcessor.h b/interface/src/voxels/VoxelPacketProcessor.h
similarity index 100%
rename from interface/src/VoxelPacketProcessor.h
rename to interface/src/voxels/VoxelPacketProcessor.h
diff --git a/interface/src/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp
similarity index 100%
rename from interface/src/VoxelSystem.cpp
rename to interface/src/voxels/VoxelSystem.cpp
diff --git a/interface/src/VoxelSystem.h b/interface/src/voxels/VoxelSystem.h
similarity index 100%
rename from interface/src/VoxelSystem.h
rename to interface/src/voxels/VoxelSystem.h
diff --git a/libraries/embedded-webserver/src/HTTPConnection.cpp b/libraries/embedded-webserver/src/HTTPConnection.cpp
index 50ce72e0cd..8fc0a25dca 100755
--- a/libraries/embedded-webserver/src/HTTPConnection.cpp
+++ b/libraries/embedded-webserver/src/HTTPConnection.cpp
@@ -180,7 +180,7 @@ void HTTPConnection::readHeaders() {
QByteArray clength = _requestHeaders.value("Content-Length");
if (clength.isEmpty()) {
- _parentManager->handleHTTPRequest(this, _requestUrl.path());
+ _parentManager->handleHTTPRequest(this, _requestUrl);
} else {
_requestContent.resize(clength.toInt());
diff --git a/libraries/embedded-webserver/src/HTTPManager.cpp b/libraries/embedded-webserver/src/HTTPManager.cpp
index a217555a78..d106b6df59 100755
--- a/libraries/embedded-webserver/src/HTTPManager.cpp
+++ b/libraries/embedded-webserver/src/HTTPManager.cpp
@@ -15,15 +15,15 @@
#include "HTTPConnection.h"
#include "HTTPManager.h"
-bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QString& path) {
- if (_requestHandler && _requestHandler->handleHTTPRequest(connection, path)) {
+bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QUrl& url) {
+ if (_requestHandler && _requestHandler->handleHTTPRequest(connection, url)) {
// this request was handled by our _requestHandler object
// so we don't need to attempt to do so in the document root
return true;
}
// check to see if there is a file to serve from the document root for this path
- QString subPath = path;
+ QString subPath = url.path();
// remove any slash at the beginning of the path
if (subPath.startsWith('/')) {
@@ -38,6 +38,10 @@ bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QString& p
// this could be a directory with a trailing slash
// send a redirect to the path with a slash so we can
QString redirectLocation = '/' + subPath + '/';
+
+ if (!url.query().isEmpty()) {
+ redirectLocation += "?" + url.query();
+ }
QHash redirectHeader;
redirectHeader.insert(QByteArray("Location"), redirectLocation.toUtf8());
diff --git a/libraries/embedded-webserver/src/HTTPManager.h b/libraries/embedded-webserver/src/HTTPManager.h
index e3b44e7cdc..a8f9d723fa 100755
--- a/libraries/embedded-webserver/src/HTTPManager.h
+++ b/libraries/embedded-webserver/src/HTTPManager.h
@@ -20,7 +20,7 @@ class HTTPConnection;
class HTTPRequestHandler {
public:
/// Handles an HTTP request.
- virtual bool handleHTTPRequest(HTTPConnection* connection, const QString& path) = 0;
+ virtual bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url) = 0;
};
/// Handles HTTP connections
@@ -30,7 +30,7 @@ public:
/// Initializes the manager.
HTTPManager(quint16 port, const QString& documentRoot, HTTPRequestHandler* requestHandler = NULL, QObject* parent = 0);
- bool handleHTTPRequest(HTTPConnection* connection, const QString& path);
+ bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url);
protected slots:
/// Accepts all pending connections
diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index c820347cab..38948071ff 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -144,6 +144,7 @@ void ScriptEngine::init() {
qScriptRegisterMetaType(&_engine, ParticleIDtoScriptValue, ParticleIDfromScriptValue);
qScriptRegisterSequenceMetaType >(&_engine);
qScriptRegisterSequenceMetaType >(&_engine);
+ qScriptRegisterSequenceMetaType >(&_engine);
QScriptValue soundConstructorValue = _engine.newFunction(soundConstructor);
QScriptValue soundMetaObject = _engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue);