History

resolve conflicts on merge with upstream master

Stephen Birarda committed 12 years ago

Commit efcf5062 parents 45d796e 72d09a576 files · +5243 −2058Browse files

Showing the changes to interface/src/Application.cpp (1 of 76 files). Show all

Unified · Split

interface/src/Application.cpp+305−593
@@ -49,7 +49,7 @@ · 48 unmodified lines
49#include <QXmlStreamReader>49#include <QXmlStreamReader>
50#include <QXmlStreamAttributes>50#include <QXmlStreamAttributes>
51#include <QMediaPlayer>51#include <QMediaPlayer>
52#include <QMimeData> 52#include <QMimeData>
53#include <QMessageBox>53#include <QMessageBox>
54 54
55#include <AccountManager.h>55#include <AccountManager.h>
@@ -63,7 +63,7 @@ · 7 unmodified lines
63#include <UUID.h>63#include <UUID.h>
64#include <OctreeSceneStats.h>64#include <OctreeSceneStats.h>
65#include <LocalVoxelsList.h>65#include <LocalVoxelsList.h>
66#include <FstReader.h>66#include <ModelUploader.h>
67 67
68#include "Application.h"68#include "Application.h"
69#include "InterfaceVersion.h"69#include "InterfaceVersion.h"
@@ -81,6 +81,7 @@ · 11 unmodified lines
81#include "ui/InfoView.h"81#include "ui/InfoView.h"
82#include "ui/Snapshot.h"82#include "ui/Snapshot.h"
83#include "ui/TextRenderer.h"83#include "ui/TextRenderer.h"
84#include "ui/Stats.h"
84 85
85using namespace std;86using namespace std;
86 87
@@ -110,15 +111,11 @@ const float MIRROR_FIELD_OF_VIEW = 30.0f; · 23 unmodified lines
110const QString CHECK_VERSION_URL = "http://highfidelity.io/latestVersion.xml";111const QString CHECK_VERSION_URL = "http://highfidelity.io/latestVersion.xml";
111const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion";112const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion";
112 113
113const int STATS_PELS_PER_LINE = 20;
114
115const QString CUSTOM_URL_SCHEME = "hifi:";
116
117void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {114void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
118 if (message.size() > 0) {115 if (message.size() > 0) {
119 QString dateString = QDateTime::currentDateTime().toTimeSpec(Qt::LocalTime).toString(Qt::ISODate);116 QString dateString = QDateTime::currentDateTime().toTimeSpec(Qt::LocalTime).toString(Qt::ISODate);
120 QString formattedMessage = QString("[%1] %2\n").arg(dateString).arg(message);117 QString formattedMessage = QString("[%1] %2\n").arg(dateString).arg(message);
121 118
122 fprintf(stdout, "%s", qPrintable(formattedMessage));119 fprintf(stdout, "%s", qPrintable(formattedMessage));
123 Application::getInstance()->getLogger()->addMessage(qPrintable(formattedMessage));120 Application::getInstance()->getLogger()->addMessage(qPrintable(formattedMessage));
124 }121 }
@@ -137,7 +134,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 12 unmodified lines
137 QApplication(argc, argv),134 QApplication(argc, argv),
138 _window(new QMainWindow(desktop())),135 _window(new QMainWindow(desktop())),
139 _glWidget(new GLCanvas()),136 _glWidget(new GLCanvas()),
140 _statsExpanded(false),
141 _nodeThread(new QThread(this)),137 _nodeThread(new QThread(this)),
142 _datagramProcessor(),138 _datagramProcessor(),
143 _frameCount(0),139 _frameCount(0),
@@ -167,8 +163,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 23 unmodified lines
167 _voxelHideShowThread(&_voxels),163 _voxelHideShowThread(&_voxels),
168 _packetsPerSecond(0),164 _packetsPerSecond(0),
169 _bytesPerSecond(0),165 _bytesPerSecond(0),
170 _recentMaxPackets(0),166 _previousScriptLocation(),
171 _resetRecentMaxPacketsSoon(true),
172 _logger(new FileLogger(this))167 _logger(new FileLogger(this))
173{168{
174 // init GnuTLS for DTLS with domain-servers169 // init GnuTLS for DTLS with domain-servers
@@ -176,23 +171,23 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 1 unmodified line
176 171
177 // read the ApplicationInfo.ini file for Name/Version/Domain information172 // read the ApplicationInfo.ini file for Name/Version/Domain information
178 QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat);173 QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat);
179 174
180 // set the associated application properties175 // set the associated application properties
181 applicationInfo.beginGroup("INFO");176 applicationInfo.beginGroup("INFO");
182 177
183 qDebug() << "[VERSION] Build sequence: " << qPrintable(applicationVersion());178 qDebug() << "[VERSION] Build sequence: " << qPrintable(applicationVersion());
184 179
185 setApplicationName(applicationInfo.value("name").toString());180 setApplicationName(applicationInfo.value("name").toString());
186 setApplicationVersion(BUILD_VERSION);181 setApplicationVersion(BUILD_VERSION);
187 setOrganizationName(applicationInfo.value("organizationName").toString());182 setOrganizationName(applicationInfo.value("organizationName").toString());
188 setOrganizationDomain(applicationInfo.value("organizationDomain").toString());183 setOrganizationDomain(applicationInfo.value("organizationDomain").toString());
189 184
190 QSettings::setDefaultFormat(QSettings::IniFormat);185 QSettings::setDefaultFormat(QSettings::IniFormat);
191 186
192 _myAvatar = _avatarManager.getMyAvatar();187 _myAvatar = _avatarManager.getMyAvatar();
193 188
194 _applicationStartupTime = startup_time;189 _applicationStartupTime = startup_time;
195 190
196 QFontDatabase::addApplicationFont(Application::resourcesPath() + "styles/Inconsolata.otf");191 QFontDatabase::addApplicationFont(Application::resourcesPath() + "styles/Inconsolata.otf");
197 _window->setWindowTitle("Interface");192 _window->setWindowTitle("Interface");
198 193
@@ -207,19 +202,19 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 8 unmodified lines
207 if (portStr) {202 if (portStr) {
208 listenPort = atoi(portStr);203 listenPort = atoi(portStr);
209 }204 }
210 205
211 // start the nodeThread so its event loop is running206 // start the nodeThread so its event loop is running
212 _nodeThread->start();207 _nodeThread->start();
213 208
214 // make sure the node thread is given highest priority209 // make sure the node thread is given highest priority
215 _nodeThread->setPriority(QThread::TimeCriticalPriority);210 _nodeThread->setPriority(QThread::TimeCriticalPriority);
216 211
217 // put the NodeList and datagram processing on the node thread212 // put the NodeList and datagram processing on the node thread
218 NodeList* nodeList = NodeList::createInstance(NodeType::Agent, listenPort);213 NodeList* nodeList = NodeList::createInstance(NodeType::Agent, listenPort);
219 214
220 nodeList->moveToThread(_nodeThread);215 nodeList->moveToThread(_nodeThread);
221 _datagramProcessor.moveToThread(_nodeThread);216 _datagramProcessor.moveToThread(_nodeThread);
222 217
223 // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal218 // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
224 connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), &_datagramProcessor, SLOT(processDatagrams()));219 connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), &_datagramProcessor, SLOT(processDatagrams()));
225 220
@@ -241,20 +236,20 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 15 unmodified lines
241 connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), &_voxels, SLOT(nodeKilled(SharedNodePointer)));236 connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), &_voxels, SLOT(nodeKilled(SharedNodePointer)));
242 connect(nodeList, &NodeList::uuidChanged, this, &Application::updateWindowTitle);237 connect(nodeList, &NodeList::uuidChanged, this, &Application::updateWindowTitle);
243 connect(nodeList, &NodeList::limitOfSilentDomainCheckInsReached, nodeList, &NodeList::reset);238 connect(nodeList, &NodeList::limitOfSilentDomainCheckInsReached, nodeList, &NodeList::reset);
244 239
245 // connect to appropriate slots on AccountManager240 // connect to appropriate slots on AccountManager
246 AccountManager& accountManager = AccountManager::getInstance();241 AccountManager& accountManager = AccountManager::getInstance();
247 connect(&accountManager, &AccountManager::authRequired, Menu::getInstance(), &Menu::loginForCurrentDomain);242 connect(&accountManager, &AccountManager::authRequired, Menu::getInstance(), &Menu::loginForCurrentDomain);
248 connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);243 connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
249 244
250 // set the account manager's root URL and trigger a login request if we don't have the access token245 // set the account manager's root URL and trigger a login request if we don't have the access token
251 accountManager.setAuthURL(DEFAULT_NODE_AUTH_URL);246 accountManager.setAuthURL(DEFAULT_NODE_AUTH_URL);
252 247
253 // once the event loop has started, check and signal for an access token248 // once the event loop has started, check and signal for an access token
254 QMetaObject::invokeMethod(&accountManager, "checkAndSignalForAccessToken", Qt::QueuedConnection);249 QMetaObject::invokeMethod(&accountManager, "checkAndSignalForAccessToken", Qt::QueuedConnection);
255 250
256 _settings = new QSettings(this);251 _settings = new QSettings(this);
257 252
258 // Check to see if the user passed in a command line option for loading a local253 // Check to see if the user passed in a command line option for loading a local
259 // Voxel File.254 // Voxel File.
260 _voxelsFilename = getCmdOption(argc, constArgv, "-i");255 _voxelsFilename = getCmdOption(argc, constArgv, "-i");
@@ -268,7 +263,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 7 unmodified lines
268 nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer263 nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer
269 << NodeType::VoxelServer << NodeType::ParticleServer264 << NodeType::VoxelServer << NodeType::ParticleServer
270 << NodeType::MetavoxelServer);265 << NodeType::MetavoxelServer);
271 266
272 // connect to the packet sent signal of the _voxelEditSender and the _particleEditSender267 // connect to the packet sent signal of the _voxelEditSender and the _particleEditSender
273 connect(&_voxelEditSender, &VoxelEditPacketSender::packetSent, this, &Application::packetSent);268 connect(&_voxelEditSender, &VoxelEditPacketSender::packetSent, this, &Application::packetSent);
274 connect(&_particleEditSender, &ParticleEditPacketSender::packetSent, this, &Application::packetSent);269 connect(&_particleEditSender, &ParticleEditPacketSender::packetSent, this, &Application::packetSent);
@@ -278,7 +273,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 3 unmodified lines
278 connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes()));273 connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes()));
279 silentNodeTimer->moveToThread(_nodeThread);274 silentNodeTimer->moveToThread(_nodeThread);
280 silentNodeTimer->start(NODE_SILENCE_THRESHOLD_MSECS);275 silentNodeTimer->start(NODE_SILENCE_THRESHOLD_MSECS);
281 276
282 // send the identity packet for our avatar each second to our avatar mixer277 // send the identity packet for our avatar each second to our avatar mixer
283 QTimer* identityPacketTimer = new QTimer();278 QTimer* identityPacketTimer = new QTimer();
284 connect(identityPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendIdentityPacket);279 connect(identityPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendIdentityPacket);
@@ -326,14 +321,18 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 41 unmodified lines
326 321
327 // Set the sixense filtering322 // Set the sixense filtering
328 _sixenseManager.setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));323 _sixenseManager.setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
329 324
330 checkVersion();325 checkVersion();
331 326
332 _overlays.init(_glWidget); // do this before scripts load327 _overlays.init(_glWidget); // do this before scripts load
333 328
334 LocalVoxelsList::getInstance()->addPersistantTree(DOMAIN_TREE_NAME, _voxels.getTree());329 LocalVoxelsList::getInstance()->addPersistantTree(DOMAIN_TREE_NAME, _voxels.getTree());
335 LocalVoxelsList::getInstance()->addPersistantTree(CLIPBOARD_TREE_NAME, &_clipboard);330 LocalVoxelsList::getInstance()->addPersistantTree(CLIPBOARD_TREE_NAME, &_clipboard);
336 331
332 _window->addDockWidget(Qt::NoDockWidgetArea, _runningScriptsWidget = new RunningScriptsWidget());
333 _runningScriptsWidget->setRunningScripts(getRunningScripts());
334 connect(_runningScriptsWidget, &RunningScriptsWidget::stopScriptName, this, &Application::stopScript);
335
337 // check first run...336 // check first run...
338 QVariant firstRunValue = _settings->value("firstRun",QVariant(true));337 QVariant firstRunValue = _settings->value("firstRun",QVariant(true));
339 if (firstRunValue.isValid() && firstRunValue.toBool()) {338 if (firstRunValue.isValid() && firstRunValue.toBool()) {
@@ -341,7 +340,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 1 unmodified line
341 // clear the scripts, and set out script to our default scripts340 // clear the scripts, and set out script to our default scripts
342 clearScriptsBeforeRunning();341 clearScriptsBeforeRunning();
343 loadScript("http://public.highfidelity.io/scripts/defaultScripts.js");342 loadScript("http://public.highfidelity.io/scripts/defaultScripts.js");
344 343
345 _settings->setValue("firstRun",QVariant(false));344 _settings->setValue("firstRun",QVariant(false));
346 } else {345 } else {
347 // do this as late as possible so that all required subsystems are inialized346 // do this as late as possible so that all required subsystems are inialized
@@ -352,31 +351,34 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : · 4 unmodified lines
352Application::~Application() {351Application::~Application() {
353 352
354 qInstallMessageHandler(NULL);353 qInstallMessageHandler(NULL);
355 354
356 // make sure we don't call the idle timer any more355 // make sure we don't call the idle timer any more
357 delete idleTimer;356 delete idleTimer;
358 357
359 Menu::getInstance()->saveSettings();358 Menu::getInstance()->saveSettings();
360 _rearMirrorTools->saveSettings(_settings);359 _rearMirrorTools->saveSettings(_settings);
361 360
362 _sharedVoxelSystem.changeTree(new VoxelTree);361 _sharedVoxelSystem.changeTree(new VoxelTree);
363 if (_voxelImporter) {362 if (_voxelImporter) {
364 _voxelImporter->saveSettings(_settings);363 _voxelImporter->saveSettings(_settings);
365 delete _voxelImporter;364 delete _voxelImporter;
366 }365 }
367 _settings->sync();366 _settings->sync();
368 367
369 // let the avatar mixer know we're out368 // let the avatar mixer know we're out
370 MyAvatar::sendKillAvatar();369 MyAvatar::sendKillAvatar();
371 370
372 // ask the datagram processing thread to quit and wait until it is done371 // ask the datagram processing thread to quit and wait until it is done
373 _nodeThread->quit();372 _nodeThread->quit();
374 _nodeThread->wait();373 _nodeThread->wait();
375 374
375 // stop the audio process
376 QMetaObject::invokeMethod(&_audio, "stop");
377
376 // ask the audio thread to quit and wait until it is done378 // ask the audio thread to quit and wait until it is done
377 _audio.thread()->quit();379 _audio.thread()->quit();
378 _audio.thread()->wait();380 _audio.thread()->wait();
379 381
380 _voxelProcessor.terminate();382 _voxelProcessor.terminate();
381 _voxelHideShowThread.terminate();383 _voxelHideShowThread.terminate();
382 _voxelEditSender.terminate();384 _voxelEditSender.terminate();
@@ -389,9 +391,9 @@ Application::~Application() { · 6 unmodified lines
389 Menu::getInstance()->deleteLater();391 Menu::getInstance()->deleteLater();
390 392
391 _myAvatar = NULL;393 _myAvatar = NULL;
392 394
393 delete _glWidget;395 delete _glWidget;
394 396
395 AccountManager::getInstance().destroy();397 AccountManager::getInstance().destroy();
396 398
397 gnutls_global_deinit();399 gnutls_global_deinit();
@@ -513,7 +515,7 @@ void Application::paintGL() { · 115 unmodified lines
513 _myCamera.setDistance(0.0f);515 _myCamera.setDistance(0.0f);
514 _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing516 _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing
515 _myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition());517 _myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition());
516 _myCamera.setTargetRotation(_myAvatar->getHead()->getOrientation());518 _myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation());
517 519
518 } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {520 } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
519 _myCamera.setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay521 _myCamera.setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay
@@ -585,7 +587,7 @@ void Application::paintGL() { · 65 unmodified lines
585 587
586 if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {588 if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
587 renderRearViewMirror(_mirrorViewRect);589 renderRearViewMirror(_mirrorViewRect);
588 590
589 } else if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {591 } else if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
590 _rearMirrorTools->render(true);592 _rearMirrorTools->render(true);
591 }593 }
@@ -615,6 +617,14 @@ void Application::resizeGL(int width, int height) { · 23 unmodified lines
615 617
616 updateProjectionMatrix();618 updateProjectionMatrix();
617 glLoadIdentity();619 glLoadIdentity();
620
621 // update Stats width
622 int horizontalOffset = 0;
623 if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
624 // mirror is enabled, let's set horizontal offset to give stats some margin
625 horizontalOffset += MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
626 }
627 Stats::getInstance()->resetWidth(width, horizontalOffset);
618}628}
619 629
620void Application::updateProjectionMatrix() {630void Application::updateProjectionMatrix() {
@@ -658,10 +668,10 @@ void Application::controlledBroadcastToNodes(const QByteArray& packet, const Nod · 37 unmodified lines
658 if (type == NodeType::VoxelServer && !Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {668 if (type == NodeType::VoxelServer && !Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
659 continue;669 continue;
660 }670 }
661 671
662 // Perform the broadcast for one type672 // Perform the broadcast for one type
663 int nReceivingNodes = NodeList::getInstance()->broadcastToNodes(packet, NodeSet() << type);673 int nReceivingNodes = NodeList::getInstance()->broadcastToNodes(packet, NodeSet() << type);
664 674
665 // Feed number of bytes to corresponding channel of the bandwidth meter, if any (done otherwise)675 // Feed number of bytes to corresponding channel of the bandwidth meter, if any (done otherwise)
666 BandwidthMeter::ChannelIndex channel;676 BandwidthMeter::ChannelIndex channel;
667 switch (type) {677 switch (type) {
@@ -680,32 +690,15 @@ void Application::controlledBroadcastToNodes(const QByteArray& packet, const Nod · 12 unmodified lines
680}690}
681 691
682bool Application::event(QEvent* event) {692bool Application::event(QEvent* event) {
683 693
684 // handle custom URL694 // handle custom URL
685 if (event->type() == QEvent::FileOpen) {695 if (event->type() == QEvent::FileOpen) {
686 QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);696 QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
687 if (!fileEvent->url().isEmpty() && fileEvent->url().toLocalFile().startsWith(CUSTOM_URL_SCHEME)) {697 bool isHifiSchemeURL = !fileEvent->url().isEmpty() && fileEvent->url().toLocalFile().startsWith(CUSTOM_URL_SCHEME);
688 QString destination = fileEvent->url().toLocalFile().remove(CUSTOM_URL_SCHEME);698 if (isHifiSchemeURL) {
689 QStringList urlParts = destination.split('/', QString::SkipEmptyParts);699 Menu::getInstance()->goTo(fileEvent->url().toString());
690
691 if (urlParts.count() > 1) {
692 // if url has 2 or more parts, the first one is domain name
693 Menu::getInstance()->goToDomain(urlParts[0]);
694
695 // location coordinates
696 Menu::getInstance()->goToDestination(urlParts[1]);
697 if (urlParts.count() > 2) {
698
699 // location orientation
700 Menu::getInstance()->goToOrientation(urlParts[2]);
701 }
702 } else if (urlParts.count() == 1) {
703
704 // location coordinates
705 Menu::getInstance()->goToDestination(urlParts[0]);
706 }
707 }700 }
708 701
709 return false;702 return false;
710 }703 }
711 return QApplication::event(event);704 return QApplication::event(event);
@@ -716,7 +709,7 @@ void Application::keyPressEvent(QKeyEvent* event) { · 4 unmodified lines
716 _keysPressed.insert(event->key());709 _keysPressed.insert(event->key());
717 710
718 _controllerScriptingInterface.emitKeyPressEvent(event); // send events to any registered scripts711 _controllerScriptingInterface.emitKeyPressEvent(event); // send events to any registered scripts
719 712
720 // if one of our scripts have asked to capture this event, then stop processing it713 // if one of our scripts have asked to capture this event, then stop processing it
721 if (_controllerScriptingInterface.isKeyCaptured(event)) {714 if (_controllerScriptingInterface.isKeyCaptured(event)) {
722 return;715 return;
@@ -1074,8 +1067,12 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { · 351 unmodified lines
1074 _mousePressed = false;1067 _mousePressed = false;
1075 checkBandwidthMeterClick();1068 checkBandwidthMeterClick();
1076 if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {1069 if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
1077 checkStatsClick();1070 int horizontalOffset = 0;
1078 } 1071 if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
1072 horizontalOffset = MIRROR_VIEW_WIDTH;
1073 }
1074 Stats::getInstance()->checkClick(_mouseX, _mouseY, _mouseDragStartedX, _mouseDragStartedY, horizontalOffset);
1075 }
1079 }1076 }
1080 }1077 }
1081}1078}
@@ -1124,7 +1121,7 @@ void Application::touchBeginEvent(QTouchEvent* event) { · 42 unmodified lines
1124 if (_controllerScriptingInterface.isTouchCaptured()) {1121 if (_controllerScriptingInterface.isTouchCaptured()) {
1125 return;1122 return;
1126 }1123 }
1127 1124
1128 // put any application specific touch behavior below here..1125 // put any application specific touch behavior below here..
1129 _lastTouchAvgX = _touchAvgX;1126 _lastTouchAvgX = _touchAvgX;
1130 _lastTouchAvgY = _touchAvgY;1127 _lastTouchAvgY = _touchAvgY;
@@ -1167,13 +1164,13 @@ void Application::dropEvent(QDropEvent *event) { · 36 unmodified lines
1167 break;1164 break;
1168 }1165 }
1169 }1166 }
1170 1167
1171 SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath);1168 SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath);
1172 if (snapshotData) {1169 if (snapshotData) {
1173 if (!snapshotData->getDomain().isEmpty()) {1170 if (!snapshotData->getDomain().isEmpty()) {
1174 Menu::getInstance()->goToDomain(snapshotData->getDomain());1171 Menu::getInstance()->goToDomain(snapshotData->getDomain());
1175 }1172 }
1176 1173
1177 _myAvatar->setPosition(snapshotData->getLocation());1174 _myAvatar->setPosition(snapshotData->getLocation());
1178 _myAvatar->setOrientation(snapshotData->getOrientation());1175 _myAvatar->setOrientation(snapshotData->getOrientation());
1179 } else {1176 } else {
@@ -1201,19 +1198,19 @@ void Application::timer() { · 21 unmodified lines
1201 }1198 }
1202 1199
1203 _fps = (float)_frameCount / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);1200 _fps = (float)_frameCount / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);
1204 1201
1205 _packetsPerSecond = (float) _datagramProcessor.getPacketCount() / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);1202 _packetsPerSecond = (float) _datagramProcessor.getPacketCount() / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);
1206 _bytesPerSecond = (float) _datagramProcessor.getByteCount() / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);1203 _bytesPerSecond = (float) _datagramProcessor.getByteCount() / ((float)diffclock(&_timerStart, &_timerEnd) / 1000.f);
1207 _frameCount = 0;1204 _frameCount = 0;
1208 1205
1209 _datagramProcessor.resetCounters();1206 _datagramProcessor.resetCounters();
1210 1207
1211 gettimeofday(&_timerStart, NULL);1208 gettimeofday(&_timerStart, NULL);
1212 1209
1213 // ask the node list to check in with the domain server1210 // ask the node list to check in with the domain server
1214 NodeList::getInstance()->sendDomainServerCheckIn();1211 NodeList::getInstance()->sendDomainServerCheckIn();
1215 1212
1216 1213
1217}1214}
1218 1215
1219void Application::idle() {1216void Application::idle() {
@@ -1250,11 +1247,11 @@ void Application::idle() { · 30 unmodified lines
1250 _idleLoopMeasuredJitter = _idleLoopStdev.getStDev();1247 _idleLoopMeasuredJitter = _idleLoopStdev.getStDev();
1251 _idleLoopStdev.reset();1248 _idleLoopStdev.reset();
1252 }1249 }
1253 1250
1254 if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {1251 if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
1255 _buckyBalls.simulate(timeSinceLastUpdate / 1000.f, Application::getInstance()->getAvatar()->getHandData());1252 _buckyBalls.simulate(timeSinceLastUpdate / 1000.f, Application::getInstance()->getAvatar()->getHandData());
1256 }1253 }
1257 1254
1258 // After finishing all of the above work, restart the idle timer, allowing 2ms to process events.1255 // After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
1259 idleTimer->start(2);1256 idleTimer->start(2);
1260 }1257 }
@@ -1386,7 +1383,7 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) { · 125 unmodified lines
1386 tr("Sparse Voxel Octree Files (*.svo)"));1383 tr("Sparse Voxel Octree Files (*.svo)"));
1387 QByteArray fileNameAscii = fileNameString.toLocal8Bit();1384 QByteArray fileNameAscii = fileNameString.toLocal8Bit();
1388 const char* fileName = fileNameAscii.data();1385 const char* fileName = fileNameAscii.data();
1389 1386
1390 VoxelTreeElement* selectedNode = _voxels.getTree()->getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);1387 VoxelTreeElement* selectedNode = _voxels.getTree()->getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
1391 if (selectedNode) {1388 if (selectedNode) {
1392 VoxelTree exportTree;1389 VoxelTree exportTree;
@@ -1400,12 +1397,12 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) { · 7 unmodified lines
1400 1397
1401void Application::importVoxels() {1398void Application::importVoxels() {
1402 _importSucceded = false;1399 _importSucceded = false;
1403 1400
1404 if (!_voxelImporter) {1401 if (!_voxelImporter) {
1405 _voxelImporter = new VoxelImporter(_window);1402 _voxelImporter = new VoxelImporter(_window);
1406 _voxelImporter->loadSettings(_settings);1403 _voxelImporter->loadSettings(_settings);
1407 }1404 }
1408 1405
1409 if (!_voxelImporter->exec()) {1406 if (!_voxelImporter->exec()) {
1410 qDebug() << "[DEBUG] Import succeeded." << endl;1407 qDebug() << "[DEBUG] Import succeeded." << endl;
1411 _importSucceded = true;1408 _importSucceded = true;
@@ -1419,7 +1416,7 @@ void Application::importVoxels() { · 7 unmodified lines
1419 1416
1420 // restore the main window's active state1417 // restore the main window's active state
1421 _window->activateWindow();1418 _window->activateWindow();
1422 1419
1423 emit importDone();1420 emit importDone();
1424}1421}
1425 1422
@@ -1475,7 +1472,7 @@ void Application::pasteVoxels(const VoxelDetail& sourceVoxel) { · 49 unmodified lines
1475 }1472 }
1476 1473
1477 pasteVoxelsToOctalCode(octalCodeDestination);1474 pasteVoxelsToOctalCode(octalCodeDestination);
1478 1475
1479 if (calculatedOctCode) {1476 if (calculatedOctCode) {
1480 delete[] calculatedOctCode;1477 delete[] calculatedOctCode;
1481 }1478 }
@@ -1512,9 +1509,9 @@ void Application::init() { · 30 unmodified lines
1512 1509
1513 // Cleanup of the original shared tree1510 // Cleanup of the original shared tree
1514 _sharedVoxelSystem.init();1511 _sharedVoxelSystem.init();
1515 1512
1516 _voxelImporter = new VoxelImporter(_window);1513 _voxelImporter = new VoxelImporter(_window);
1517 1514
1518 _environment.init();1515 _environment.init();
1519 1516
1520 _glowEffect.init();1517 _glowEffect.init();
@@ -1556,11 +1553,11 @@ void Application::init() { · 35 unmodified lines
1556 _audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());1553 _audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());
1557 }1554 }
1558 qDebug("Loaded settings");1555 qDebug("Loaded settings");
1559 1556
1560 // initialize Visage and Faceshift after loading the menu settings1557 // initialize Visage and Faceshift after loading the menu settings
1561 _faceshift.init();1558 _faceshift.init();
1562 _visage.init();1559 _visage.init();
1563 1560
1564 // fire off an immediate domain-server check in now that settings are loaded1561 // fire off an immediate domain-server check in now that settings are loaded
1565 NodeList::getInstance()->sendDomainServerCheckIn();1562 NodeList::getInstance()->sendDomainServerCheckIn();
1566 1563
@@ -1579,20 +1576,20 @@ void Application::init() { · 12 unmodified lines
1579 _particleCollisionSystem.init(&_particleEditSender, _particles.getTree(), _voxels.getTree(), &_audio, &_avatarManager);1576 _particleCollisionSystem.init(&_particleEditSender, _particles.getTree(), _voxels.getTree(), &_audio, &_avatarManager);
1580 1577
1581 // connect the _particleCollisionSystem to our script engine's ParticleScriptingInterface1578 // connect the _particleCollisionSystem to our script engine's ParticleScriptingInterface
1582 connect(&_particleCollisionSystem, 1579 connect(&_particleCollisionSystem,
1583 SIGNAL(particleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const glm::vec3&)),1580 SIGNAL(particleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const glm::vec3&)),
1584 ScriptEngine::getParticlesScriptingInterface(), 1581 ScriptEngine::getParticlesScriptingInterface(),
1585 SLOT(forwardParticleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const glm::vec3&)));1582 SLOT(forwardParticleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const glm::vec3&)));
1586 1583
1587 connect(&_particleCollisionSystem, 1584 connect(&_particleCollisionSystem,
1588 SIGNAL(particleCollisionWithParticle(const ParticleID&, const ParticleID&, const glm::vec3&)),1585 SIGNAL(particleCollisionWithParticle(const ParticleID&, const ParticleID&, const glm::vec3&)),
1589 ScriptEngine::getParticlesScriptingInterface(), 1586 ScriptEngine::getParticlesScriptingInterface(),
1590 SLOT(forwardParticleCollisionWithParticle(const ParticleID&, const ParticleID&, const glm::vec3&)));1587 SLOT(forwardParticleCollisionWithParticle(const ParticleID&, const ParticleID&, const glm::vec3&)));
1591 1588
1592 _audio.init(_glWidget);1589 _audio.init(_glWidget);
1593 1590
1594 _rearMirrorTools = new RearMirrorTools(_glWidget, _mirrorViewRect, _settings);1591 _rearMirrorTools = new RearMirrorTools(_glWidget, _mirrorViewRect, _settings);
1595 1592
1596 connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView()));1593 connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView()));
1597 connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView()));1594 connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView()));
1598 connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView()));1595 connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView()));
@@ -1715,7 +1712,7 @@ void Application::updateMyAvatarLookAtPosition() { · 116 unmodified lines
1715 float distance = TREE_SCALE;1712 float distance = TREE_SCALE;
1716 if (_myAvatar->getLookAtTargetAvatar() && _myAvatar != _myAvatar->getLookAtTargetAvatar()) {1713 if (_myAvatar->getLookAtTargetAvatar() && _myAvatar != _myAvatar->getLookAtTargetAvatar()) {
1717 distance = glm::distance(_mouseRayOrigin,1714 distance = glm::distance(_mouseRayOrigin,
1718 static_cast<Avatar*>(_myAvatar->getLookAtTargetAvatar())->getHead()->calculateAverageEyePosition()); 1715 static_cast<Avatar*>(_myAvatar->getLookAtTargetAvatar())->getHead()->calculateAverageEyePosition());
1719 }1716 }
1720 const float FIXED_MIN_EYE_DISTANCE = 0.3f;1717 const float FIXED_MIN_EYE_DISTANCE = 0.3f;
1721 float minEyeDistance = FIXED_MIN_EYE_DISTANCE + (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON ? 0.0f :1718 float minEyeDistance = FIXED_MIN_EYE_DISTANCE + (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON ? 0.0f :
@@ -1728,7 +1725,7 @@ void Application::updateMyAvatarLookAtPosition() { · 6 unmodified lines
1728 eyePitch = _faceshift.getEstimatedEyePitch();1725 eyePitch = _faceshift.getEstimatedEyePitch();
1729 eyeYaw = _faceshift.getEstimatedEyeYaw();1726 eyeYaw = _faceshift.getEstimatedEyeYaw();
1730 trackerActive = true;1727 trackerActive = true;
1731 1728
1732 } else if (_visage.isActive()) {1729 } else if (_visage.isActive()) {
1733 eyePitch = _visage.getEstimatedEyePitch();1730 eyePitch = _visage.getEstimatedEyePitch();
1734 eyeYaw = _visage.getEstimatedEyeYaw();1731 eyeYaw = _visage.getEstimatedEyeYaw();
@@ -1849,15 +1846,6 @@ void Application::updateDialogs(float deltaTime) { · 114 unmodified lines
1849 }1846 }
1850}1847}
1851 1848
1852void Application::updateAudio(float deltaTime) {
1853 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
1854 PerformanceWarning warn(showWarnings, "Application::updateAudio()");
1855
1856 // Update audio stats for procedural sounds
1857 _audio.setLastAcceleration(_myAvatar->getThrust());
1858 _audio.setLastVelocity(_myAvatar->getVelocity());
1859}
1860
1861void Application::updateCursor(float deltaTime) {1849void Application::updateCursor(float deltaTime) {
1862 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);1850 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
1863 PerformanceWarning warn(showWarnings, "Application::updateCursor()");1851 PerformanceWarning warn(showWarnings, "Application::updateCursor()");
@@ -1906,14 +1894,13 @@ void Application::update(float deltaTime) { · 42 unmodified lines
1906 updateMetavoxels(deltaTime); // update metavoxels1894 updateMetavoxels(deltaTime); // update metavoxels
1907 updateCamera(deltaTime); // handle various camera tweaks like off axis projection1895 updateCamera(deltaTime); // handle various camera tweaks like off axis projection
1908 updateDialogs(deltaTime); // update various stats dialogs if present1896 updateDialogs(deltaTime); // update various stats dialogs if present
1909 updateAudio(deltaTime); // Update audio stats for procedural sounds
1910 updateCursor(deltaTime); // Handle cursor updates1897 updateCursor(deltaTime); // Handle cursor updates
1911 1898
1912 _particles.update(); // update the particles...1899 _particles.update(); // update the particles...
1913 _particleCollisionSystem.update(); // collide the particles...1900 _particleCollisionSystem.update(); // collide the particles...
1914 1901
1915 _overlays.update(deltaTime);1902 _overlays.update(deltaTime);
1916 1903
1917 // let external parties know we're updating1904 // let external parties know we're updating
1918 emit simulating(deltaTime);1905 emit simulating(deltaTime);
1919}1906}
@@ -1937,7 +1924,7 @@ void Application::updateMyAvatar(float deltaTime) { · 17 unmodified lines
1937 // actually need to calculate the view frustum planes to send these details1924 // actually need to calculate the view frustum planes to send these details
1938 // to the server.1925 // to the server.
1939 loadViewFrustum(_myCamera, _viewFrustum);1926 loadViewFrustum(_myCamera, _viewFrustum);
1940 1927
1941 // Update my voxel servers with my current voxel query...1928 // Update my voxel servers with my current voxel query...
1942 quint64 now = usecTimestampNow();1929 quint64 now = usecTimestampNow();
1943 quint64 sinceLastQuery = now - _lastQueriedTime;1930 quint64 sinceLastQuery = now - _lastQueriedTime;
@@ -2213,7 +2200,7 @@ void Application::updateShadowMap() { · 269 unmodified lines
2213 }2200 }
2214 center = inverseRotation * center;2201 center = inverseRotation * center;
2215 glm::vec3 minima(center.x - radius, center.y - radius, center.z - radius);2202 glm::vec3 minima(center.x - radius, center.y - radius, center.z - radius);
2216 glm::vec3 maxima(center.x + radius, center.y + radius, center.z + radius); 2203 glm::vec3 maxima(center.x + radius, center.y + radius, center.z + radius);
2217 2204
2218 // stretch out our extents in z so that we get all of the avatars2205 // stretch out our extents in z so that we get all of the avatars
2219 minima.z -= _viewFrustum.getFarClip() * 0.5f;2206 minima.z -= _viewFrustum.getFarClip() * 0.5f;
@@ -2234,7 +2221,7 @@ void Application::updateShadowMap() { · 14 unmodified lines
2234 _shadowViewFrustum.setEyeOffsetPosition(glm::vec3());2221 _shadowViewFrustum.setEyeOffsetPosition(glm::vec3());
2235 _shadowViewFrustum.setEyeOffsetOrientation(glm::quat());2222 _shadowViewFrustum.setEyeOffsetOrientation(glm::quat());
2236 _shadowViewFrustum.calculate();2223 _shadowViewFrustum.calculate();
2237 2224
2238 glMatrixMode(GL_PROJECTION);2225 glMatrixMode(GL_PROJECTION);
2239 glPushMatrix();2226 glPushMatrix();
2240 glLoadIdentity();2227 glLoadIdentity();
@@ -2289,19 +2276,19 @@ void Application::setupWorldLight() { · 48 unmodified lines
2289 2276
2290QImage Application::renderAvatarBillboard() {2277QImage Application::renderAvatarBillboard() {
2291 _textureCache.getPrimaryFramebufferObject()->bind();2278 _textureCache.getPrimaryFramebufferObject()->bind();
2292 2279
2293 glDisable(GL_BLEND);2280 glDisable(GL_BLEND);
2294 2281
2295 const int BILLBOARD_SIZE = 64;2282 const int BILLBOARD_SIZE = 64;
2296 renderRearViewMirror(QRect(0, _glWidget->height() - BILLBOARD_SIZE, BILLBOARD_SIZE, BILLBOARD_SIZE), true);2283 renderRearViewMirror(QRect(0, _glWidget->height() - BILLBOARD_SIZE, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
2297 2284
2298 QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);2285 QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
2299 glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());2286 glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
2300 2287
2301 glEnable(GL_BLEND);2288 glEnable(GL_BLEND);
2302 2289
2303 _textureCache.getPrimaryFramebufferObject()->release();2290 _textureCache.getPrimaryFramebufferObject()->release();
2304 2291
2305 return image;2292 return image;
2306}2293}
2307 2294
@@ -2402,7 +2389,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { · 94 unmodified lines
2402 "Application::displaySide() ... metavoxels...");2389 "Application::displaySide() ... metavoxels...");
2403 _metavoxels.render();2390 _metavoxels.render();
2404 }2391 }
2405 2392
2406 if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {2393 if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
2407 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),2394 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
2408 "Application::displaySide() ... bucky balls...");2395 "Application::displaySide() ... bucky balls...");
@@ -2415,7 +2402,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { · 6 unmodified lines
2415 "Application::displaySide() ... particles...");2402 "Application::displaySide() ... particles...");
2416 _particles.render();2403 _particles.render();
2417 }2404 }
2418 2405
2419 // render the ambient occlusion effect if enabled2406 // render the ambient occlusion effect if enabled
2420 if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) {2407 if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) {
2421 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),2408 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
@@ -2459,7 +2446,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { · 37 unmodified lines
2459 2446
2460 // give external parties a change to hook in2447 // give external parties a change to hook in
2461 emit renderingInWorldInterface();2448 emit renderingInWorldInterface();
2462 2449
2463 // render JS/scriptable overlays2450 // render JS/scriptable overlays
2464 _overlays.render3D();2451 _overlays.render3D();
2465 }2452 }
@@ -2509,14 +2496,111 @@ void Application::displayOverlay() { · 43 unmodified lines
2509 }2496 }
2510 }2497 }
2511 2498
2499 // Audio Scope
2500 const int AUDIO_SCOPE_Y_OFFSET = 135;
2512 if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {2501 if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
2513 _audio.renderMuteIcon(1, _glWidget->height() - 50);
2514 if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) {2502 if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) {
2515 int oscilloscopeTop = _glWidget->height() - 135;2503 int oscilloscopeTop = _glWidget->height() - AUDIO_SCOPE_Y_OFFSET;
2516 _audioScope.render(25, oscilloscopeTop);2504 _audioScope.render(MIRROR_VIEW_LEFT_PADDING, oscilloscopeTop);
2517 }2505 }
2518 }2506 }
2519 2507
2508 // Audio VU Meter and Mute Icon
2509 const int MUTE_ICON_SIZE = 24;
2510 const int AUDIO_METER_INSET = 2;
2511 const int AUDIO_METER_WIDTH = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - AUDIO_METER_INSET;
2512 const int AUDIO_METER_SCALE_WIDTH = AUDIO_METER_WIDTH - 2 * AUDIO_METER_INSET;
2513 const int AUDIO_METER_HEIGHT = 8;
2514 const int AUDIO_METER_Y_GAP = 8;
2515 const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_INSET;
2516
2517 int audioMeterY;
2518 if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
2519 audioMeterY = MIRROR_VIEW_HEIGHT + AUDIO_METER_Y_GAP;
2520 } else {
2521 audioMeterY = AUDIO_METER_Y_GAP;
2522 }
2523 _audio.renderMuteIcon(MIRROR_VIEW_LEFT_PADDING, audioMeterY);
2524
2525
2526 const float AUDIO_METER_BLUE[] = {0.0, 0.0, 1.0};
2527 const float AUDIO_METER_GREEN[] = {0.0, 1.0, 0.0};
2528 const float AUDIO_METER_RED[] = {1.0, 0.0, 0.0};
2529 const float AUDIO_GREEN_START = 0.25 * AUDIO_METER_SCALE_WIDTH;
2530 const float AUDIO_RED_START = 0.80 * AUDIO_METER_SCALE_WIDTH;
2531 const float CLIPPING_INDICATOR_TIME = 1.0f;
2532 const float AUDIO_METER_AVERAGING = 0.5;
2533 const float LOG2 = log(2.f);
2534 const float METER_LOUDNESS_SCALE = 2.8f / 5.f;
2535 const float LOG2_LOUDNESS_FLOOR = 11.f;
2536 float audioLevel = 0.f;
2537 float loudness = _audio.getLastInputLoudness() + 1.f;
2538
2539 _trailingAudioLoudness = AUDIO_METER_AVERAGING * _trailingAudioLoudness + (1.f - AUDIO_METER_AVERAGING) * loudness;
2540 float log2loudness = log(_trailingAudioLoudness) / LOG2;
2541
2542 if (log2loudness <= LOG2_LOUDNESS_FLOOR) {
2543 audioLevel = (log2loudness / LOG2_LOUDNESS_FLOOR) * METER_LOUDNESS_SCALE * AUDIO_METER_SCALE_WIDTH;
2544 } else {
2545 audioLevel = (log2loudness - (LOG2_LOUDNESS_FLOOR - 1.f)) * METER_LOUDNESS_SCALE * AUDIO_METER_SCALE_WIDTH;
2546 }
2547 if (audioLevel > AUDIO_METER_SCALE_WIDTH) {
2548 audioLevel = AUDIO_METER_SCALE_WIDTH;
2549 }
2550
2551 bool isClipping = ((_audio.getTimeSinceLastClip() > 0.f) && (_audio.getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME));
2552
2553 glBegin(GL_QUADS);
2554 if (isClipping) {
2555 glColor3f(1, 0, 0);
2556 } else {
2557 glColor3f(0, 0, 0);
2558 }
2559 // Draw audio meter background Quad
2560 glVertex2i(AUDIO_METER_X, audioMeterY);
2561 glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, audioMeterY);
2562 glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, audioMeterY + AUDIO_METER_HEIGHT);
2563 glVertex2i(AUDIO_METER_X, audioMeterY + AUDIO_METER_HEIGHT);
2564
2565 if (audioLevel > AUDIO_RED_START) {
2566 if (!isClipping) {
2567 glColor3fv(AUDIO_METER_RED);
2568 } else {
2569 glColor3f(1, 1, 1);
2570 }
2571 // Draw Red Quad
2572 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_INSET);
2573 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
2574 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
2575 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
2576 audioLevel = AUDIO_RED_START;
2577 }
2578 if (audioLevel > AUDIO_GREEN_START) {
2579 if (!isClipping) {
2580 glColor3fv(AUDIO_METER_GREEN);
2581 } else {
2582 glColor3f(1, 1, 1);
2583 }
2584 // Draw Green Quad
2585 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_INSET);
2586 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
2587 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
2588 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
2589 audioLevel = AUDIO_GREEN_START;
2590 }
2591 // Draw Blue Quad
2592 if (!isClipping) {
2593 glColor3fv(AUDIO_METER_BLUE);
2594 } else {
2595 glColor3f(1, 1, 1);
2596 }
2597 // Draw Blue (low level) quad
2598 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_INSET);
2599 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
2600 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
2601 glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
2602 glEnd();
2603
2520 if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {2604 if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {
2521 _myAvatar->renderHeadMouse();2605 _myAvatar->renderHeadMouse();
2522 }2606 }
@@ -2526,11 +2610,17 @@ void Application::displayOverlay() { · 3 unmodified lines
2526 glPointSize(1.0f);2610 glPointSize(1.0f);
2527 2611
2528 if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {2612 if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
2613 int horizontalOffset = 0;
2614 if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
2615 // mirror is enabled, let's set horizontal offset to give stats some margin
2616 horizontalOffset += MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
2617 }
2618 int voxelPacketsToProcess = _voxelProcessor.packetsToProcessCount();
2529 // Onscreen text about position, servers, etc2619 // Onscreen text about position, servers, etc
2530 displayStats();2620 Stats::getInstance()->display(WHITE_TEXT, horizontalOffset, _fps, _packetsPerSecond, _bytesPerSecond, voxelPacketsToProcess);
2531 // Bandwidth meter2621 // Bandwidth meter
2532 if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) {2622 if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) {
2533 displayStatsBackground(0x33333399, _glWidget->width() - 296, _glWidget->height() - 68, 296, 68);2623 Stats::drawBackground(0x33333399, _glWidget->width() - 296, _glWidget->height() - 68, 296, 68);
2534 _bandwidthMeter.render(_glWidget->width(), _glWidget->height());2624 _bandwidthMeter.render(_glWidget->width(), _glWidget->height());
2535 }2625 }
2536 }2626 }
@@ -2540,8 +2630,8 @@ void Application::displayOverlay() { · 3 unmodified lines
2540 char frameTimer[10];2630 char frameTimer[10];
2541 quint64 mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);2631 quint64 mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);
2542 sprintf(frameTimer, "%d\n", (int)(mSecsNow % 1000));2632 sprintf(frameTimer, "%d\n", (int)(mSecsNow % 1000));
2543 int timerBottom = 2633 int timerBottom =
2544 (Menu::getInstance()->isOptionChecked(MenuOption::Stats) && 2634 (Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
2545 Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))2635 Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))
2546 ? 80 : 20;2636 ? 80 : 20;
2547 drawText(_glWidget->width() - 100, _glWidget->height() - timerBottom, 0.30f, 1.0f, 0.f, frameTimer, WHITE_TEXT);2637 drawText(_glWidget->width() - 100, _glWidget->height() - timerBottom, 0.30f, 1.0f, 0.f, frameTimer, WHITE_TEXT);
@@ -2552,415 +2642,6 @@ void Application::displayOverlay() { · 4 unmodified lines
2552 glPopMatrix();2642 glPopMatrix();
2553}2643}
2554 2644
2555// translucent background box that makes stats more readable
2556void Application::displayStatsBackground(unsigned int rgba, int x, int y, int width, int height) {
2557 glBegin(GL_QUADS);
2558 glColor4f(((rgba >> 24) & 0xff) / 255.0f,
2559 ((rgba >> 16) & 0xff) / 255.0f,
2560 ((rgba >> 8) & 0xff) / 255.0f,
2561 (rgba & 0xff) / 255.0f);
2562 glVertex3f(x, y, 0);
2563 glVertex3f(x + width, y, 0);
2564 glVertex3f(x + width, y + height, 0);
2565 glVertex3f(x , y + height, 0);
2566 glEnd();
2567 glColor4f(1, 1, 1, 1);
2568}
2569
2570// display expanded or contracted stats
2571
2572void Application::displayStats() {
2573 unsigned int backgroundColor = 0x33333399;
2574 int verticalOffset = 0, horizontalOffset = 0, lines = 0;
2575 bool mirrorEnabled = Menu::getInstance()->isOptionChecked(MenuOption::Mirror);
2576
2577 QLocale locale(QLocale::English);
2578 std::stringstream voxelStats;
2579
2580 glPointSize(1.0f);
2581
2582 // we need to take one avatar out so we don't include ourselves
2583 int totalAvatars = _avatarManager.size() - 1;
2584 int totalServers = NodeList::getInstance()->size();
2585
2586 if (mirrorEnabled) {
2587 horizontalOffset += MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
2588 }
2589
2590 lines = _statsExpanded ? 5 : 3;
2591 displayStatsBackground(backgroundColor, horizontalOffset, 0, 165, lines * STATS_PELS_PER_LINE + 10);
2592 horizontalOffset += 5;
2593
2594 char serverNodes[30];
2595 sprintf(serverNodes, "Servers: %d", totalServers);
2596 char avatarNodes[30];
2597 sprintf(avatarNodes, "Avatars: %d", totalAvatars);
2598 char framesPerSecond[30];
2599 sprintf(framesPerSecond, "Framerate: %3.0f FPS", _fps);
2600
2601 verticalOffset += STATS_PELS_PER_LINE;
2602 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, serverNodes, WHITE_TEXT);
2603 verticalOffset += STATS_PELS_PER_LINE;
2604 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarNodes, WHITE_TEXT);
2605 verticalOffset += STATS_PELS_PER_LINE;
2606 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, framesPerSecond, WHITE_TEXT);
2607
2608 if (_statsExpanded) {
2609 char packetsPerSecond[30];
2610 sprintf(packetsPerSecond, "Pkts/sec: %d", _packetsPerSecond);
2611 char averageMegabitsPerSecond[30];
2612 sprintf(averageMegabitsPerSecond, "Mbps: %3.2f", (float)_bytesPerSecond * 8.f / 1000000.f);
2613
2614 verticalOffset += STATS_PELS_PER_LINE;
2615 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, packetsPerSecond, WHITE_TEXT);
2616 verticalOffset += STATS_PELS_PER_LINE;
2617 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, averageMegabitsPerSecond, WHITE_TEXT);
2618 }
2619
2620 verticalOffset = 0;
2621 horizontalOffset += 161;
2622
2623 if (Menu::getInstance()->isOptionChecked(MenuOption::TestPing)) {
2624 int pingAudio = 0, pingAvatar = 0, pingVoxel = 0, pingVoxelMax = 0;
2625
2626 NodeList* nodeList = NodeList::getInstance();
2627 SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
2628 SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer);
2629
2630 pingAudio = audioMixerNode ? audioMixerNode->getPingMs() : 0;
2631 pingAvatar = avatarMixerNode ? avatarMixerNode->getPingMs() : 0;
2632
2633 // Now handle voxel servers, since there could be more than one, we average their ping times
2634 unsigned long totalPingVoxel = 0;
2635 int voxelServerCount = 0;
2636
2637 foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
2638 if (node->getType() == NodeType::VoxelServer) {
2639 totalPingVoxel += node->getPingMs();
2640 voxelServerCount++;
2641 if (pingVoxelMax < node->getPingMs()) {
2642 pingVoxelMax = node->getPingMs();
2643 }
2644 }
2645 }
2646
2647 if (voxelServerCount) {
2648 pingVoxel = totalPingVoxel/voxelServerCount;
2649 }
2650
2651 lines = _statsExpanded ? 4 : 3;
2652 displayStatsBackground(backgroundColor, horizontalOffset, 0, 175, lines * STATS_PELS_PER_LINE + 10);
2653 horizontalOffset += 5;
2654
2655 char audioJitter[30];
2656 sprintf(audioJitter,
2657 "Buffer msecs %.1f",
2658 (float) (_audio.getNetworkBufferLengthSamplesPerChannel() + (float) _audio.getJitterBufferSamples()) /
2659 (float)_audio.getNetworkSampleRate() * 1000.f);
2660 drawText(30, _glWidget->height() - 22, 0.10f, 0.f, 2.f, audioJitter, WHITE_TEXT);
2661
2662
2663 char audioPing[30];
2664 sprintf(audioPing, "Audio ping: %d", pingAudio);
2665
2666
2667 char avatarPing[30];
2668 sprintf(avatarPing, "Avatar ping: %d", pingAvatar);
2669 char voxelAvgPing[30];
2670 sprintf(voxelAvgPing, "Voxel avg ping: %d", pingVoxel);
2671
2672 verticalOffset += STATS_PELS_PER_LINE;
2673 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, audioPing, WHITE_TEXT);
2674 verticalOffset += STATS_PELS_PER_LINE;
2675 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarPing, WHITE_TEXT);
2676 verticalOffset += STATS_PELS_PER_LINE;
2677 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, voxelAvgPing, WHITE_TEXT);
2678
2679 if (_statsExpanded) {
2680 char voxelMaxPing[30];
2681 sprintf(voxelMaxPing, "Voxel max ping: %d", pingVoxelMax);
2682
2683 verticalOffset += STATS_PELS_PER_LINE;
2684 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, voxelMaxPing, WHITE_TEXT);
2685 }
2686
2687 verticalOffset = 0;
2688 horizontalOffset += 171;
2689 }
2690
2691 glm::vec3 avatarPos = _myAvatar->getPosition();
2692
2693 lines = _statsExpanded ? 5 : 3;
2694 displayStatsBackground(backgroundColor, horizontalOffset, 0, _glWidget->width() - (mirrorEnabled ? 301 : 411) - horizontalOffset, lines * STATS_PELS_PER_LINE + 10);
2695 horizontalOffset += 5;
2696
2697 char avatarPosition[200];
2698 if (mirrorEnabled) {
2699 // shorthand formatting
2700 sprintf(avatarPosition, "Pos: %.0f,%.0f,%.0f", avatarPos.x, avatarPos.y, avatarPos.z);
2701 } else {
2702 // longhand way
2703 sprintf(avatarPosition, "Position: %.1f, %.1f, %.1f", avatarPos.x, avatarPos.y, avatarPos.z);
2704 }
2705 char avatarVelocity[30];
2706 sprintf(avatarVelocity, "Velocity: %.1f", glm::length(_myAvatar->getVelocity()));
2707 char avatarBodyYaw[30];
2708 sprintf(avatarBodyYaw, "Yaw: %.1f", _myAvatar->getBodyYaw());
2709 char avatarMixerStats[200];
2710
2711 verticalOffset += STATS_PELS_PER_LINE;
2712 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarPosition, WHITE_TEXT);
2713 verticalOffset += STATS_PELS_PER_LINE;
2714 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarVelocity, WHITE_TEXT);
2715 verticalOffset += STATS_PELS_PER_LINE;
2716 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarBodyYaw, WHITE_TEXT);
2717
2718 if (_statsExpanded) {
2719 SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NodeType::AvatarMixer);
2720 if (avatarMixer) {
2721 sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
2722 roundf(avatarMixer->getAverageKilobitsPerSecond()),
2723 roundf(avatarMixer->getAveragePacketsPerSecond()));
2724 } else {
2725 sprintf(avatarMixerStats, "No Avatar Mixer");
2726 }
2727
2728 verticalOffset += STATS_PELS_PER_LINE;
2729 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarMixerStats, WHITE_TEXT);
2730
2731 stringstream downloadStats;
2732 downloadStats << "Downloads: ";
2733 foreach (Resource* resource, ResourceCache::getLoadingRequests()) {
2734 const float MAXIMUM_PERCENTAGE = 100.0f;
2735 downloadStats << roundf(resource->getProgress() * MAXIMUM_PERCENTAGE) << "% ";
2736 }
2737 downloadStats << "(" << ResourceCache::getPendingRequestCount() << " pending)";
2738
2739 verticalOffset += STATS_PELS_PER_LINE;
2740 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, downloadStats.str().c_str(), WHITE_TEXT);
2741 }
2742
2743 verticalOffset = 0;
2744 horizontalOffset = _glWidget->width() - (mirrorEnabled ? 300 : 410);
2745
2746 lines = _statsExpanded ? 12 : 3;
2747 displayStatsBackground(backgroundColor, horizontalOffset, 0, _glWidget->width() - horizontalOffset, lines * STATS_PELS_PER_LINE + 10);
2748 horizontalOffset += 5;
2749
2750 if (_statsExpanded) {
2751 // Local Voxel Memory Usage
2752 voxelStats.str("");
2753 voxelStats << "Voxels Memory Nodes: " << VoxelTreeElement::getTotalMemoryUsage() / 1000000.f << "MB";
2754 verticalOffset += STATS_PELS_PER_LINE;
2755 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2756
2757 voxelStats.str("");
2758 voxelStats <<
2759 "Geometry RAM: " << _voxels.getVoxelMemoryUsageRAM() / 1000000.f << "MB / " <<
2760 "VBO: " << _voxels.getVoxelMemoryUsageVBO() / 1000000.f << "MB";
2761 if (_voxels.hasVoxelMemoryUsageGPU()) {
2762 voxelStats << " / GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB";
2763 }
2764 verticalOffset += STATS_PELS_PER_LINE;
2765 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2766
2767 // Voxel Rendering
2768 voxelStats.str("");
2769 voxelStats.precision(4);
2770 voxelStats << "Voxel Rendering Slots Max: " << _voxels.getMaxVoxels() / 1000.f << "K";
2771 verticalOffset += STATS_PELS_PER_LINE;
2772 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2773 }
2774
2775 voxelStats.str("");
2776 voxelStats.precision(4);
2777 voxelStats << "Drawn: " << _voxels.getVoxelsWritten() / 1000.f << "K " <<
2778 "Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K ";
2779 verticalOffset += STATS_PELS_PER_LINE;
2780 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2781
2782 // iterate all the current voxel stats, and list their sending modes, and total voxel counts
2783 std::stringstream sendingMode("");
2784 sendingMode << "Octree Sending Mode: [";
2785 int serverCount = 0;
2786 int movingServerCount = 0;
2787 unsigned long totalNodes = 0;
2788 unsigned long totalInternal = 0;
2789 unsigned long totalLeaves = 0;
2790 for(NodeToOctreeSceneStatsIterator i = _octreeServerSceneStats.begin(); i != _octreeServerSceneStats.end(); i++) {
2791 //const QUuid& uuid = i->first;
2792 OctreeSceneStats& stats = i->second;
2793 serverCount++;
2794 if (_statsExpanded) {
2795 if (serverCount > 1) {
2796 sendingMode << ",";
2797 }
2798 if (stats.isMoving()) {
2799 sendingMode << "M";
2800 movingServerCount++;
2801 } else {
2802 sendingMode << "S";
2803 }
2804 }
2805
2806 // calculate server node totals
2807 totalNodes += stats.getTotalElements();
2808 if (_statsExpanded) {
2809 totalInternal += stats.getTotalInternal();
2810 totalLeaves += stats.getTotalLeaves();
2811 }
2812 }
2813 if (_statsExpanded) {
2814 if (serverCount == 0) {
2815 sendingMode << "---";
2816 }
2817 sendingMode << "] " << serverCount << " servers";
2818 if (movingServerCount > 0) {
2819 sendingMode << " <SCENE NOT STABLE>";
2820 } else {
2821 sendingMode << " <SCENE STABLE>";
2822 }
2823 verticalOffset += STATS_PELS_PER_LINE;
2824 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)sendingMode.str().c_str(), WHITE_TEXT);
2825 }
2826
2827 // Incoming packets
2828 int voxelPacketsToProcess = _voxelProcessor.packetsToProcessCount();
2829 if (_statsExpanded) {
2830 voxelStats.str("");
2831 QString packetsString = locale.toString((int)voxelPacketsToProcess);
2832 QString maxString = locale.toString((int)_recentMaxPackets);
2833 voxelStats << "Voxel Packets to Process: " << qPrintable(packetsString)
2834 << " [Recent Max: " << qPrintable(maxString) << "]";
2835 verticalOffset += STATS_PELS_PER_LINE;
2836 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2837 }
2838
2839 if (_resetRecentMaxPacketsSoon && voxelPacketsToProcess > 0) {
2840 _recentMaxPackets = 0;
2841 _resetRecentMaxPacketsSoon = false;
2842 }
2843 if (voxelPacketsToProcess == 0) {
2844 _resetRecentMaxPacketsSoon = true;
2845 } else {
2846 if (voxelPacketsToProcess > _recentMaxPackets) {
2847 _recentMaxPackets = voxelPacketsToProcess;
2848 }
2849 }
2850
2851 verticalOffset += (_statsExpanded ? STATS_PELS_PER_LINE : 0);
2852
2853 QString serversTotalString = locale.toString((uint)totalNodes); // consider adding: .rightJustified(10, ' ');
2854
2855 // Server Voxels
2856 voxelStats.str("");
2857 voxelStats << "Server voxels: " << qPrintable(serversTotalString);
2858 verticalOffset += STATS_PELS_PER_LINE;
2859 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2860
2861 if (_statsExpanded) {
2862 QString serversInternalString = locale.toString((uint)totalInternal);
2863 QString serversLeavesString = locale.toString((uint)totalLeaves);
2864
2865 voxelStats.str("");
2866 voxelStats <<
2867 "Internal: " << qPrintable(serversInternalString) << " " <<
2868 "Leaves: " << qPrintable(serversLeavesString) << "";
2869 verticalOffset += STATS_PELS_PER_LINE;
2870 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2871 }
2872
2873 unsigned long localTotal = VoxelTreeElement::getNodeCount();
2874 QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
2875
2876 // Local Voxels
2877 voxelStats.str("");
2878 voxelStats << "Local voxels: " << qPrintable(localTotalString);
2879 verticalOffset += STATS_PELS_PER_LINE;
2880 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2881
2882 if (_statsExpanded) {
2883 unsigned long localInternal = VoxelTreeElement::getInternalNodeCount();
2884 unsigned long localLeaves = VoxelTreeElement::getLeafNodeCount();
2885 QString localInternalString = locale.toString((uint)localInternal);
2886 QString localLeavesString = locale.toString((uint)localLeaves);
2887
2888 voxelStats.str("");
2889 voxelStats <<
2890 "Internal: " << qPrintable(localInternalString) << " " <<
2891 "Leaves: " << qPrintable(localLeavesString) << "";
2892 verticalOffset += STATS_PELS_PER_LINE;
2893 drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2894 }
2895
2896 // LOD Details
2897 if (_statsExpanded) {
2898 voxelStats.str("");
2899 QString displayLODDetails = Menu::getInstance()->getLODFeedbackText();
2900 voxelStats << "LOD: You can see " << qPrintable(displayLODDetails.trimmed());
2901 verticalOffset += STATS_PELS_PER_LINE;
2902 drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
2903 }
2904}
2905
2906// called on mouse click release
2907// check for clicks over stats in order to expand or contract them
2908void Application::checkStatsClick() {
2909 if (0 != glm::compMax(glm::abs(glm::ivec2(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY)))) {
2910 // not worried about dragging on stats
2911 return;
2912 }
2913
2914 int statsHeight = 0, statsWidth = 0, statsX = 0, statsY = 0, lines = 0;
2915
2916 if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
2917 statsX += MIRROR_VIEW_WIDTH;
2918 }
2919
2920 // top-left stats click
2921 lines = _statsExpanded ? 5 : 3;
2922 statsHeight = lines * STATS_PELS_PER_LINE + 10;
2923 statsWidth = 165;
2924 if (_mouseX > statsX && _mouseX < statsX + statsWidth && _mouseY > statsY && _mouseY < statsY + statsHeight) {
2925 toggleStatsExpanded();
2926 return;
2927 }
2928
2929 // ping stats click
2930 lines = _statsExpanded ? 4 : 3;
2931 statsX += statsWidth;
2932 statsHeight = lines * STATS_PELS_PER_LINE + 10;
2933 statsWidth = 175;
2934 if (_mouseX > statsX && _mouseX < statsX + statsWidth && _mouseY > statsY && _mouseY < statsY + statsHeight) {
2935 toggleStatsExpanded();
2936 return;
2937 }
2938
2939 // top-center stats panel click
2940 lines = _statsExpanded ? 4 : 3;
2941 statsX += statsWidth;
2942 statsHeight = lines * STATS_PELS_PER_LINE + 10;
2943 statsWidth = _glWidget->width() - 411 - statsX;
2944 if (_mouseX > statsX && _mouseX < statsX + statsWidth && _mouseY > statsY && _mouseY < statsY + statsHeight) {
2945 toggleStatsExpanded();
2946 return;
2947 }
2948
2949 // top-right stats click
2950 lines = _statsExpanded ? 11 : 3;
2951 statsX = _glWidget->width() - 410;
2952 statsHeight = lines * STATS_PELS_PER_LINE + 10;
2953 statsWidth = _glWidget->width() - statsX;
2954 if (_mouseX > statsX && _mouseX < statsX + statsWidth && _mouseY > statsY && _mouseY < statsY + statsHeight) {
2955 toggleStatsExpanded();
2956 return;
2957 }
2958}
2959
2960void Application::toggleStatsExpanded() {
2961 _statsExpanded = !_statsExpanded;
2962}
2963
2964glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {2645glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
2965 float horizontalScale = _glWidget->width() / 2.0f;2646 float horizontalScale = _glWidget->width() / 2.0f;
2966 float verticalScale = _glWidget->height() / 2.0f;2647 float verticalScale = _glWidget->height() / 2.0f;
@@ -2993,12 +2674,12 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { · 26 unmodified lines
2993 _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees2674 _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees
2994 _mirrorCamera.setDistance(BILLBOARD_DISTANCE * _myAvatar->getScale());2675 _mirrorCamera.setDistance(BILLBOARD_DISTANCE * _myAvatar->getScale());
2995 _mirrorCamera.setTargetPosition(_myAvatar->getPosition());2676 _mirrorCamera.setTargetPosition(_myAvatar->getPosition());
2996 2677
2997 } else if (_rearMirrorTools->getZoomLevel() == BODY) {2678 } else if (_rearMirrorTools->getZoomLevel() == BODY) {
2998 _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees2679 _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees
2999 _mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());2680 _mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());
3000 _mirrorCamera.setTargetPosition(_myAvatar->getChestPosition());2681 _mirrorCamera.setTargetPosition(_myAvatar->getChestPosition());
3001 2682
3002 } else { // HEAD zoom level2683 } else { // HEAD zoom level
3003 _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees2684 _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees
3004 _mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());2685 _mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
@@ -3013,7 +2694,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { · 8 unmodified lines
3013 }2694 }
3014 }2695 }
3015 _mirrorCamera.setAspectRatio((float)region.width() / region.height());2696 _mirrorCamera.setAspectRatio((float)region.width() / region.height());
3016 2697
3017 _mirrorCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));2698 _mirrorCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));
3018 _mirrorCamera.update(1.0f/_fps);2699 _mirrorCamera.update(1.0f/_fps);
3019 2700
@@ -3058,7 +2739,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { · 38 unmodified lines
3058 if (!billboard) {2739 if (!billboard) {
3059 _rearMirrorTools->render(false);2740 _rearMirrorTools->render(false);
3060 }2741 }
3061 2742
3062 // reset Viewport and projection matrix2743 // reset Viewport and projection matrix
3063 glViewport(0, 0, _glWidget->width(), _glWidget->height());2744 glViewport(0, 0, _glWidget->width(), _glWidget->height());
3064 glDisable(GL_SCISSOR_TEST);2745 glDisable(GL_SCISSOR_TEST);
@@ -3278,14 +2959,13 @@ void Application::setMenuShortcutsEnabled(bool enabled) { · 213 unmodified lines
3278}2959}
3279 2960
3280void Application::updateWindowTitle(){2961void Application::updateWindowTitle(){
3281 2962
3282 QString buildVersion = " (build " + applicationVersion() + ")";2963 QString buildVersion = " (build " + applicationVersion() + ")";
3283 NodeList* nodeList = NodeList::getInstance();2964 NodeList* nodeList = NodeList::getInstance();
3284 2965
3285 QString username = AccountManager::getInstance().getUsername();2966 QString username = AccountManager::getInstance().getUsername();
3286 QString title = QString() + (!username.isEmpty() ? username + " " : QString()) + nodeList->getSessionUUID().toString()2967 QString title = QString() + (!username.isEmpty() ? username + " " : QString()) + nodeList->getSessionUUID().toString()
3287 + " @ " + nodeList->getDomainHandler().getHostname() + buildVersion;2968 + " @ " + nodeList->getDomainHandler().getHostname() + buildVersion;
3288
3289 qDebug("Application title set to: %s", title.toStdString().c_str());2969 qDebug("Application title set to: %s", title.toStdString().c_str());
3290 _window->setWindowTitle(title);2970 _window->setWindowTitle(title);
3291}2971}
@@ -3300,7 +2980,7 @@ void Application::domainChanged(const QString& domainHostname) { · 8 unmodified lines
3300 _voxelServerJurisdictions.clear();2980 _voxelServerJurisdictions.clear();
3301 _octreeServerSceneStats.clear();2981 _octreeServerSceneStats.clear();
3302 _particleServerJurisdictions.clear();2982 _particleServerJurisdictions.clear();
3303 2983
3304 // reset the particle renderer2984 // reset the particle renderer
3305 _particles.clear();2985 _particles.clear();
3306 2986
@@ -3310,12 +2990,12 @@ void Application::domainChanged(const QString& domainHostname) { · 3 unmodified lines
3310 2990
3311void Application::connectedToDomain(const QString& hostname) {2991void Application::connectedToDomain(const QString& hostname) {
3312 AccountManager& accountManager = AccountManager::getInstance();2992 AccountManager& accountManager = AccountManager::getInstance();
3313 2993
3314 if (accountManager.isLoggedIn()) {2994 if (accountManager.isLoggedIn()) {
3315 // update our domain-server with the data-server we're logged in with2995 // update our domain-server with the data-server we're logged in with
3316 2996
3317 QString domainPutJsonString = "{\"address\":{\"domain\":\"" + hostname + "\"}}";2997 QString domainPutJsonString = "{\"address\":{\"domain\":\"" + hostname + "\"}}";
3318 2998
3319 accountManager.authenticatedRequest("/api/v1/users/address", QNetworkAccessManager::PutOperation,2999 accountManager.authenticatedRequest("/api/v1/users/address", QNetworkAccessManager::PutOperation,
3320 JSONCallbackParameters(), domainPutJsonString.toUtf8());3000 JSONCallbackParameters(), domainPutJsonString.toUtf8());
3321 }3001 }
@@ -3480,13 +3160,13 @@ void Application::loadScripts() { · 158 unmodified lines
3480 // loads all saved scripts3160 // loads all saved scripts
3481 QSettings* settings = new QSettings(this);3161 QSettings* settings = new QSettings(this);
3482 int size = settings->beginReadArray("Settings");3162 int size = settings->beginReadArray("Settings");
3483 3163
3484 for (int i = 0; i < size; ++i){3164 for (int i = 0; i < size; ++i){
3485 settings->setArrayIndex(i);3165 settings->setArrayIndex(i);
3486 QString string = settings->value("script").toString();3166 QString string = settings->value("script").toString();
3487 loadScript(string);3167 loadScript(string);
3488 }3168 }
3489 3169
3490 settings->endArray();3170 settings->endArray();
3491}3171}
3492 3172
@@ -3501,72 +3181,98 @@ void Application::saveScripts() { · 8 unmodified lines
3501 // saves all current running scripts3181 // saves all current running scripts
3502 QSettings* settings = new QSettings(this);3182 QSettings* settings = new QSettings(this);
3503 settings->beginWriteArray("Settings");3183 settings->beginWriteArray("Settings");
3504 for (int i = 0; i < _activeScripts.size(); ++i){3184 for (int i = 0; i < getRunningScripts().size(); ++i){
3505 settings->setArrayIndex(i);3185 settings->setArrayIndex(i);
3506 settings->setValue("script", _activeScripts.at(i));3186 settings->setValue("script", getRunningScripts().at(i));
3507 }3187 }
3508 3188
3509 settings->endArray();3189 settings->endArray();
3510}3190}
3511 3191
3512void Application::stopAllScripts() {3192void Application::stopAllScripts() {
3513 // stops all current running scripts3193 // stops all current running scripts
3514 QList<QAction*> scriptActions = Menu::getInstance()->getActiveScriptsMenu()->actions();3194 for (int i = 0; i < _scriptEnginesHash.size(); ++i) {
3515 foreach (QAction* scriptAction, scriptActions) {3195 _scriptEnginesHash.values().at(i)->stop();
3516 scriptAction->activate(QAction::Trigger);3196 qDebug() << "stopping script..." << getRunningScripts().at(i);
3517 qDebug() << "stopping script..." << scriptAction->text();
3518 }3197 }
3519 _activeScripts.clear();3198 _scriptEnginesHash.clear();
3199 _runningScriptsWidget->setRunningScripts(getRunningScripts());
3200}
3201
3202void Application::stopScript(const QString &scriptName)
3203{
3204 _scriptEnginesHash.value(scriptName)->stop();
3205 qDebug() << "stopping script..." << scriptName;
3206 _scriptEnginesHash.remove(scriptName);
3207 _runningScriptsWidget->setRunningScripts(getRunningScripts());
3520}3208}
3521 3209
3522void Application::reloadAllScripts() {3210void Application::reloadAllScripts() {
3523 // remember all the current scripts so we can reload them3211 // remember all the current scripts so we can reload them
3524 QStringList reloadList = _activeScripts;3212 QStringList reloadList = getRunningScripts();
3525 // reloads all current running scripts3213 // reloads all current running scripts
3526 QList<QAction*> scriptActions = Menu::getInstance()->getActiveScriptsMenu()->actions();3214 stopAllScripts();
3527 foreach (QAction* scriptAction, scriptActions) {
3528 scriptAction->activate(QAction::Trigger);
3529 qDebug() << "stopping script..." << scriptAction->text();
3530 }
3531 3215
3532 // NOTE: we don't need to clear the _activeScripts list because that is handled on script shutdown.
3533
3534 foreach (QString scriptName, reloadList){3216 foreach (QString scriptName, reloadList){
3535 qDebug() << "reloading script..." << scriptName;3217 qDebug() << "reloading script..." << scriptName;
3536 loadScript(scriptName);3218 loadScript(scriptName);
3537 }3219 }
3538}3220}
3539 3221
3540void Application::uploadFST() {3222void Application::toggleRunningScriptsWidget()
3541 FstReader reader;3223{
3542 if (reader.zip()) {3224 if (!_runningScriptsWidget->toggleViewAction()->isChecked()) {
3543 reader.send();3225 _runningScriptsWidget->move(_window->geometry().topLeft().x(), _window->geometry().topLeft().y());
3226 _runningScriptsWidget->resize(0, _window->height());
3227 _runningScriptsWidget->toggleViewAction()->trigger();
3228 _runningScriptsWidget->grabKeyboard();
3229
3230 QPropertyAnimation* slideAnimation = new QPropertyAnimation(_runningScriptsWidget, "geometry", _runningScriptsWidget);
3231 slideAnimation->setStartValue(_runningScriptsWidget->geometry());
3232 slideAnimation->setEndValue(QRect(_window->geometry().topLeft().x(), _window->geometry().topLeft().y(),
3233 310, _runningScriptsWidget->height()));
3234 slideAnimation->setDuration(250);
3235 slideAnimation->start(QAbstractAnimation::DeleteWhenStopped);
3236 } else {
3237 _runningScriptsWidget->releaseKeyboard();
3238
3239 QPropertyAnimation* slideAnimation = new QPropertyAnimation(_runningScriptsWidget, "geometry", _runningScriptsWidget);
3240 slideAnimation->setStartValue(_runningScriptsWidget->geometry());
3241 slideAnimation->setEndValue(QRect(_window->geometry().topLeft().x(), _window->geometry().topLeft().y(),
3242 0, _runningScriptsWidget->height()));
3243 slideAnimation->setDuration(250);
3244 slideAnimation->start(QAbstractAnimation::DeleteWhenStopped);
3245
3246 QTimer::singleShot(260, _runningScriptsWidget->toggleViewAction(), SLOT(trigger()));
3247 }
3248}
3249
3250void Application::uploadFST(bool isHead) {
3251 ModelUploader* uploader = new ModelUploader(isHead);
3252 if (uploader->zip()) {
3253 uploader->send();
3544 }3254 }
3545}3255}
3546 3256
3547void Application::removeScriptName(const QString& fileNameString) {3257void Application::uploadHead() {
3548 _activeScripts.removeOne(fileNameString);3258 uploadFST(true);
3549}3259}
3550 3260
3551void Application::cleanupScriptMenuItem(const QString& scriptMenuName) {3261void Application::uploadSkeleton() {
3552 Menu::getInstance()->removeAction(Menu::getInstance()->getActiveScriptsMenu(), scriptMenuName);3262 uploadFST(false);
3553}3263}
3554 3264
3555void Application::loadScript(const QString& scriptName) {3265void Application::loadScript(const QString& scriptName) {
3556 3266
3557 // start the script on a new thread...3267 // start the script on a new thread...
3558 bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself3268 ScriptEngine* scriptEngine = new ScriptEngine(QUrl(scriptName), &_controllerScriptingInterface);
3559 ScriptEngine* scriptEngine = new ScriptEngine(QUrl(scriptName), wantMenuItems, &_controllerScriptingInterface);3269 _scriptEnginesHash.insert(scriptName, scriptEngine);
3560 3270
3561 if (!scriptEngine->hasScript()) {3271 if (!scriptEngine->hasScript()) {
3562 qDebug() << "Application::loadScript(), script failed to load...";3272 qDebug() << "Application::loadScript(), script failed to load...";
3563 return;3273 return;
3564 }3274 }
3565 _activeScripts.append(scriptName);3275 _runningScriptsWidget->setRunningScripts(getRunningScripts());
3566
3567 // add a stop menu item
3568 Menu::getInstance()->addActionToQMenuAndActionHash(Menu::getInstance()->getActiveScriptsMenu(),
3569 scriptEngine->getScriptMenuName(), 0, scriptEngine, SLOT(stop()));
3570 3276
3571 // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so3277 // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
3572 // we can use the same ones from the application.3278 // we can use the same ones from the application.
@@ -3574,7 +3280,7 @@ void Application::loadScript(const QString& scriptName) { · 1 unmodified line
3574 scriptEngine->getVoxelsScriptingInterface()->setVoxelTree(_voxels.getTree());3280 scriptEngine->getVoxelsScriptingInterface()->setVoxelTree(_voxels.getTree());
3575 scriptEngine->getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);3281 scriptEngine->getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);
3576 scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());3282 scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());
3577 3283
3578 // hook our avatar object into this script engine3284 // hook our avatar object into this script engine
3579 scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features3285 scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features
3580 3286
@@ -3599,8 +3305,6 @@ void Application::loadScript(const QString& scriptName) { · 18 unmodified lines
3599 // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue3305 // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue
3600 connect(scriptEngine, SIGNAL(finished(const QString&)), scriptEngine, SLOT(deleteLater()));3306 connect(scriptEngine, SIGNAL(finished(const QString&)), scriptEngine, SLOT(deleteLater()));
3601 connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));3307 connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
3602 connect(scriptEngine, SIGNAL(finished(const QString&)), this, SLOT(removeScriptName(const QString&)));
3603 connect(scriptEngine, SIGNAL(cleanupMenuItem(const QString&)), this, SLOT(cleanupScriptMenuItem(const QString&)));
3604 3308
3605 // when the application is about to quit, stop our script engine so it unwinds properly3309 // when the application is about to quit, stop our script engine so it unwinds properly
3606 connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop()));3310 connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop()));
@@ -3615,13 +3319,21 @@ void Application::loadScript(const QString& scriptName) { · 8 unmodified lines
3615}3319}
3616 3320
3617void Application::loadDialog() {3321void Application::loadDialog() {
3618 // shut down and stop any existing script3322 QString suggestedName;
3619 QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);3323
3620 QString suggestedName = desktopLocation.append("/script.js");3324 if (_previousScriptLocation.isEmpty()) {
3325 QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
3326 suggestedName = desktopLocation.append("/script.js");
3327 } else {
3328 suggestedName = _previousScriptLocation;
3329 }
3621 3330
3622 QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Open Script"), suggestedName, 3331 QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Open Script"), suggestedName,
3623 tr("JavaScript Files (*.js)"));3332 tr("JavaScript Files (*.js)"));
3624 3333 if (!fileNameString.isEmpty()) {
3334 _previousScriptLocation = fileNameString;
3335 }
3336
3625 loadScript(fileNameString);3337 loadScript(fileNameString);
3626}3338}
3627 3339
@@ -3632,7 +3344,7 @@ void Application::loadScriptURLDialog() { · 4 unmodified lines
3632 scriptURLDialog.setLabelText("Script:");3344 scriptURLDialog.setLabelText("Script:");
3633 scriptURLDialog.setWindowFlags(Qt::Sheet);3345 scriptURLDialog.setWindowFlags(Qt::Sheet);
3634 const float DIALOG_RATIO_OF_WINDOW = 0.30f;3346 const float DIALOG_RATIO_OF_WINDOW = 0.30f;
3635 scriptURLDialog.resize(scriptURLDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, 3347 scriptURLDialog.resize(scriptURLDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW,
3636 scriptURLDialog.size().height());3348 scriptURLDialog.size().height());
3637 3349
3638 int dialogReturn = scriptURLDialog.exec();3350 int dialogReturn = scriptURLDialog.exec();
@@ -3670,29 +3382,29 @@ void Application::checkVersion() { · 31 unmodified lines
3670}3382}
3671 3383
3672void Application::parseVersionXml() {3384void Application::parseVersionXml() {
3673 3385
3674 #ifdef Q_OS_WIN323386 #ifdef Q_OS_WIN32
3675 QString operatingSystem("win");3387 QString operatingSystem("win");
3676 #endif3388 #endif
3677 3389
3678 #ifdef Q_OS_MAC3390 #ifdef Q_OS_MAC
3679 QString operatingSystem("mac");3391 QString operatingSystem("mac");
3680 #endif3392 #endif
3681 3393
3682 #ifdef Q_OS_LINUX3394 #ifdef Q_OS_LINUX
3683 QString operatingSystem("ubuntu");3395 QString operatingSystem("ubuntu");
3684 #endif3396 #endif
3685 3397
3686 QString releaseDate;3398 QString releaseDate;
3687 QString releaseNotes;3399 QString releaseNotes;
3688 QString latestVersion;3400 QString latestVersion;
3689 QUrl downloadUrl;3401 QUrl downloadUrl;
3690 QObject* sender = QObject::sender();3402 QObject* sender = QObject::sender();
3691 3403
3692 QXmlStreamReader xml(qobject_cast<QNetworkReply*>(sender));3404 QXmlStreamReader xml(qobject_cast<QNetworkReply*>(sender));
3693 while (!xml.atEnd() && !xml.hasError()) {3405 while (!xml.atEnd() && !xml.hasError()) {
3694 QXmlStreamReader::TokenType token = xml.readNext();3406 QXmlStreamReader::TokenType token = xml.readNext();
3695 3407
3696 if (token == QXmlStreamReader::StartElement) {3408 if (token == QXmlStreamReader::StartElement) {
3697 if (xml.name() == "ReleaseDate") {3409 if (xml.name() == "ReleaseDate") {
3698 xml.readNext();3410 xml.readNext();

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t