mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge branch 'master' into 20276
This commit is contained in:
commit
7286a9c5fb
112 changed files with 3442 additions and 2151 deletions
5
BUILD.md
5
BUILD.md
|
@ -7,6 +7,7 @@
|
|||
* IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability.
|
||||
* [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3
|
||||
* [Bullet Physics Engine](https://code.google.com/p/bullet/downloads/list) ~> 2.82
|
||||
* [Gverb](https://github.com/highfidelity/gverb/archive/master.zip) (direct download to latest version)
|
||||
|
||||
### OS Specific Build Guides
|
||||
* [BUILD_WIN.md](BUILD_WIN.md) - additional instructions for Windows.
|
||||
|
@ -54,11 +55,11 @@ In the examples below the variable $NAME would be replaced by the name of the de
|
|||
|
||||
####QXmpp
|
||||
|
||||
You can find QXmpp [here](https://github.com/qxmpp-project/qxmpp). The inclusion of the QXmpp enables text chat in the Interface client.
|
||||
You can [find QXmpp here](https://github.com/qxmpp-project/qxmpp), 0.7.6 is the version you want. The inclusion of the QXmpp enables text chat in the Interface client.
|
||||
|
||||
OS X users who tap our [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) can install QXmpp via homebrew - `brew install highfidelity/formulas/qxmpp`.
|
||||
|
||||
####Devices
|
||||
|
||||
You can support external input/output devices such as Leap Motion, Faceshift, PrioVR, MIDI, Razr Hydra and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device.
|
||||
You can support external input/output devices such as Oculus Rift, Leap Motion, Faceshift, PrioVR, MIDI, Razr Hydra and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device.
|
||||
|
||||
|
|
20
BUILD_WIN.md
20
BUILD_WIN.md
|
@ -38,6 +38,8 @@ Once Qt is installed, you need to manually configure the following:
|
|||
|
||||
###External Libraries
|
||||
|
||||
As it stands, Hifi/Interface is a 32-bit application, so all libraries should also be 32-bit.
|
||||
|
||||
CMake will need to know where the headers and libraries for required external dependencies are.
|
||||
|
||||
The recommended route for CMake to find the external dependencies is to place all of the dependencies in one folder and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure:
|
||||
|
@ -75,7 +77,7 @@ As with the Qt libraries, you will need to make sure that directories containing
|
|||
|
||||
###OpenSSL
|
||||
|
||||
QT will use OpenSSL if it's available, but it doesn't install it, so you must install it separately.
|
||||
Qt will use OpenSSL if it's available, but it doesn't install it, so you must install it separately.
|
||||
|
||||
Your system may already have several versions of the OpenSSL DLL's (ssleay32.dll, libeay32.dll) lying around, but they may be the wrong version. If these DLL's are in the PATH then QT will try to use them, and if they're the wrong version then you will see the following errors in the console:
|
||||
|
||||
|
@ -89,7 +91,7 @@ Your system may already have several versions of the OpenSSL DLL's (ssleay32.dll
|
|||
|
||||
To prevent these problems, install OpenSSL yourself. Download the following binary packages [from this website](http://slproweb.com/products/Win32OpenSSL.html):
|
||||
* Visual C++ 2008 Redistributables
|
||||
* Win32 OpenSSL v1.0.1h
|
||||
* Win32 OpenSSL v1.0.1L
|
||||
|
||||
Install OpenSSL into the Windows system directory, to make sure that Qt uses the version that you've just installed, and not some other version.
|
||||
|
||||
|
@ -133,6 +135,20 @@ This package contains only headers, so there's nothing to add to the PATH.
|
|||
|
||||
Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder.
|
||||
|
||||
###Gverb
|
||||
|
||||
1. Go to https://github.com/highfidelity/gverb
|
||||
Or download the sources directly via this link:
|
||||
https://github.com/highfidelity/gverb/archive/master.zip
|
||||
|
||||
2. Extract the archive
|
||||
|
||||
3. Place the directories “include” and “src” in interface/external/gverb
|
||||
(Normally next to this readme)
|
||||
|
||||
4. Clear your build directory, run cmake, build and you should be all set.
|
||||
|
||||
|
||||
###Bullet
|
||||
|
||||
Bullet 2.82 source can be [downloaded here](https://code.google.com/p/bullet/downloads/detail?name=bullet-2.82-r2704.zip). Bullet does not come with prebuilt libraries, you need to make those yourself.
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/qsharedmemory.h>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QProcess>
|
||||
#include <QSettings>
|
||||
#include <QSharedMemory>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <AddressManager.h>
|
||||
|
|
|
@ -13,21 +13,22 @@
|
|||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/qsharedmemory.h>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QUrlQuery>
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QProcess>
|
||||
#include <QSharedMemory>
|
||||
#include <QStandardPaths>
|
||||
#include <QTimer>
|
||||
#include <QUrlQuery>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <HifiConfigVariantMap.h>
|
||||
#include <HTTPConnection.h>
|
||||
#include <LogUtils.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <Settings.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <ShutdownEventListener.h>
|
||||
#include <UUID.h>
|
||||
|
@ -1920,10 +1921,8 @@ Headers DomainServer::setupCookieHeadersFromProfileReply(QNetworkReply* profileR
|
|||
_cookieSessionHash.insert(cookieUUID, sessionData);
|
||||
|
||||
// persist the cookie to settings file so we can get it back on DS relaunch
|
||||
QSettings localSettings;
|
||||
localSettings.beginGroup(DS_SETTINGS_SESSIONS_GROUP);
|
||||
QVariant sessionVariant = QVariant::fromValue(sessionData);
|
||||
localSettings.setValue(cookieUUID.toString(), QVariant::fromValue(sessionData));
|
||||
QStringList path = QStringList() << DS_SETTINGS_SESSIONS_GROUP << cookieUUID.toString();
|
||||
SettingHandles::SettingHandle<QVariant>(path).set(QVariant::fromValue(sessionData));
|
||||
|
||||
// setup expiry for cookie to 1 month from today
|
||||
QDateTime cookieExpiry = QDateTime::currentDateTimeUtc().addMonths(1);
|
||||
|
@ -1943,11 +1942,12 @@ Headers DomainServer::setupCookieHeadersFromProfileReply(QNetworkReply* profileR
|
|||
|
||||
void DomainServer::loadExistingSessionsFromSettings() {
|
||||
// read data for existing web sessions into memory so existing sessions can be leveraged
|
||||
QSettings domainServerSettings;
|
||||
Settings domainServerSettings;
|
||||
domainServerSettings.beginGroup(DS_SETTINGS_SESSIONS_GROUP);
|
||||
|
||||
foreach(const QString& uuidKey, domainServerSettings.childKeys()) {
|
||||
_cookieSessionHash.insert(QUuid(uuidKey), domainServerSettings.value(uuidKey).value<DomainServerWebSessionData>());
|
||||
_cookieSessionHash.insert(QUuid(uuidKey),
|
||||
domainServerSettings.value(uuidKey).value<DomainServerWebSessionData>());
|
||||
qDebug() << "Pulled web session from settings - cookie UUID is" << uuidKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -669,6 +669,10 @@ function mouseClickEvent(event) {
|
|||
|
||||
print("Model selected: " + foundEntity.id);
|
||||
selectionDisplay.select(selectedEntityID, event);
|
||||
|
||||
cameraManager.focus(selectionManager.worldPosition,
|
||||
selectionManager.worldDimensions,
|
||||
Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
#include <QObject>
|
||||
#include <QWheelEvent>
|
||||
#include <QScreen>
|
||||
#include <QSettings>
|
||||
#include <QShortcut>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QTimer>
|
||||
#include <QUrl>
|
||||
#include <QWindow>
|
||||
|
@ -73,13 +73,16 @@
|
|||
#include <PhysicsEngine.h>
|
||||
#include <ProgramObject.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <Settings.h>
|
||||
#include <SoundCache.h>
|
||||
#include <TextRenderer.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Audio.h"
|
||||
#include "InterfaceVersion.h"
|
||||
#include "LODManager.h"
|
||||
#include "Menu.h"
|
||||
#include "ModelUploader.h"
|
||||
#include "Util.h"
|
||||
|
@ -100,7 +103,6 @@
|
|||
#include "gpu/Batch.h"
|
||||
#include "gpu/GLBackend.h"
|
||||
|
||||
|
||||
#include "scripting/AccountScriptingInterface.h"
|
||||
#include "scripting/AudioDeviceScriptingInterface.h"
|
||||
#include "scripting/ClipboardScriptingInterface.h"
|
||||
|
@ -112,9 +114,16 @@
|
|||
#include "scripting/WindowScriptingInterface.h"
|
||||
#include "scripting/WebWindowClass.h"
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
#include "SpeechRecognizer.h"
|
||||
#endif
|
||||
|
||||
#include "ui/DataWebDialog.h"
|
||||
#include "ui/DialogsManager.h"
|
||||
#include "ui/InfoView.h"
|
||||
#include "ui/LoginDialog.h"
|
||||
#include "ui/Snapshot.h"
|
||||
#include "ui/StandAloneJSConsole.h"
|
||||
#include "ui/Stats.h"
|
||||
|
||||
|
||||
|
@ -137,6 +146,12 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D
|
|||
|
||||
const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js";
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<bool> firstRun("firstRun", true);
|
||||
const SettingHandle<QString> lastScriptLocation("LastScriptLocation");
|
||||
const SettingHandle<QString> scriptsLocation("scriptsLocation");
|
||||
}
|
||||
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||
QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
|
||||
|
||||
|
@ -183,6 +198,12 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>();
|
||||
auto modelBlender = DependencyManager::set<ModelBlender>();
|
||||
auto audioToolBox = DependencyManager::set<AudioToolBox>();
|
||||
auto lodManager = DependencyManager::set<LODManager>();
|
||||
auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
|
||||
auto dialogsManager = DependencyManager::set<DialogsManager>();
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
auto speechRecognizer = DependencyManager::set<SpeechRecognizer>();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -276,6 +297,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
auto audioIO = DependencyManager::get<Audio>();
|
||||
audioIO->moveToThread(audioThread);
|
||||
connect(audioThread, &QThread::started, audioIO.data(), &Audio::start);
|
||||
connect(audioIO.data(), SIGNAL(muteToggled()), this, SLOT(audioMuteToggled()));
|
||||
|
||||
audioThread->start();
|
||||
|
||||
|
@ -287,7 +309,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
|
||||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(clearDomainOctreeDetails()));
|
||||
connect(&domainHandler, &DomainHandler::settingsReceived, this, &Application::domainSettingsReceived);
|
||||
connect(&domainHandler, &DomainHandler::hostnameChanged, Menu::getInstance(), &Menu::clearLoginDialogDisplayedFlag);
|
||||
connect(&domainHandler, &DomainHandler::hostnameChanged,
|
||||
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
|
||||
|
||||
// update our location every 5 seconds in the data-server, assuming that we are authenticated with one
|
||||
const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * 1000;
|
||||
|
@ -313,7 +336,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
|
||||
connect(&accountManager, &AccountManager::balanceChanged, this, &Application::updateWindowTitle);
|
||||
|
||||
connect(&accountManager, &AccountManager::authRequired, Menu::getInstance(), &Menu::loginForCurrentDomain);
|
||||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||
connect(&accountManager, &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
|
||||
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
||||
|
||||
// once we have a profile in account manager make sure we generate a new keypair
|
||||
|
@ -334,9 +358,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
|
||||
connect(addressManager.data(), &AddressManager::rootPlaceNameChanged, this, &Application::updateWindowTitle);
|
||||
|
||||
_settings = new QSettings(this);
|
||||
_numChangedSettings = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA WsaData;
|
||||
int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData);
|
||||
|
@ -377,7 +398,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
|
||||
_window->setCentralWidget(glCanvas.data());
|
||||
|
||||
restoreSizeAndPosition();
|
||||
_window->restoreGeometry();
|
||||
|
||||
_window->setVisible(true);
|
||||
glCanvas->setFocusPolicy(Qt::StrongFocus);
|
||||
|
@ -411,23 +432,31 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
|
||||
|
||||
// check first run...
|
||||
QVariant firstRunValue = _settings->value("firstRun",QVariant(true));
|
||||
if (firstRunValue.isValid() && firstRunValue.toBool()) {
|
||||
bool firstRun = SettingHandles::firstRun.get();
|
||||
if (firstRun) {
|
||||
qDebug() << "This is a first run...";
|
||||
// clear the scripts, and set out script to our default scripts
|
||||
clearScriptsBeforeRunning();
|
||||
loadScript(DEFAULT_SCRIPTS_JS_URL);
|
||||
|
||||
QMutexLocker locker(&_settingsMutex);
|
||||
_settings->setValue("firstRun",QVariant(false));
|
||||
SettingHandles::firstRun.set(false);
|
||||
} else {
|
||||
// do this as late as possible so that all required subsystems are initialized
|
||||
loadScripts();
|
||||
|
||||
QMutexLocker locker(&_settingsMutex);
|
||||
_previousScriptLocation = _settings->value("LastScriptLocation", QVariant("")).toString();
|
||||
_previousScriptLocation = SettingHandles::lastScriptLocation.get();
|
||||
}
|
||||
|
||||
|
||||
loadSettings();
|
||||
int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now
|
||||
connect(&_settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
|
||||
connect(&_settingsThread, SIGNAL(started), &_settingsTimer, SLOT(start));
|
||||
connect(&_settingsThread, &QThread::finished, &_settingsTimer, &QTimer::deleteLater);
|
||||
_settingsTimer.moveToThread(&_settingsThread);
|
||||
_settingsTimer.setSingleShot(false);
|
||||
_settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL);
|
||||
_settingsThread.start();
|
||||
|
||||
_trayIcon->show();
|
||||
|
||||
// set the local loopback interface for local sounds from audio scripts
|
||||
|
@ -448,12 +477,12 @@ void Application::aboutToQuit() {
|
|||
}
|
||||
|
||||
Application::~Application() {
|
||||
saveSettings();
|
||||
|
||||
_entities.getTree()->setSimulation(NULL);
|
||||
qInstallMessageHandler(NULL);
|
||||
|
||||
saveSettings();
|
||||
storeSizeAndPosition();
|
||||
_window->saveGeometry();
|
||||
|
||||
int DELAY_TIME = 1000;
|
||||
UserActivityLogger::getInstance().close(DELAY_TIME);
|
||||
|
@ -490,45 +519,6 @@ Application::~Application() {
|
|||
DependencyManager::destroy<GLCanvas>();
|
||||
}
|
||||
|
||||
void Application::saveSettings() {
|
||||
Menu::getInstance()->saveSettings();
|
||||
_rearMirrorTools->saveSettings(_settings);
|
||||
|
||||
_settings->sync();
|
||||
_numChangedSettings = 0;
|
||||
}
|
||||
|
||||
|
||||
void Application::restoreSizeAndPosition() {
|
||||
QRect available = desktop()->availableGeometry();
|
||||
|
||||
QMutexLocker locker(&_settingsMutex);
|
||||
_settings->beginGroup("Window");
|
||||
|
||||
int x = (int)loadSetting(_settings, "x", 0);
|
||||
int y = (int)loadSetting(_settings, "y", 0);
|
||||
_window->move(x, y);
|
||||
|
||||
int width = (int)loadSetting(_settings, "width", available.width());
|
||||
int height = (int)loadSetting(_settings, "height", available.height());
|
||||
_window->resize(width, height);
|
||||
|
||||
_settings->endGroup();
|
||||
}
|
||||
|
||||
void Application::storeSizeAndPosition() {
|
||||
QMutexLocker locker(&_settingsMutex);
|
||||
_settings->beginGroup("Window");
|
||||
|
||||
_settings->setValue("width", _window->rect().width());
|
||||
_settings->setValue("height", _window->rect().height());
|
||||
|
||||
_settings->setValue("x", _window->pos().x());
|
||||
_settings->setValue("y", _window->pos().y());
|
||||
|
||||
_settings->endGroup();
|
||||
}
|
||||
|
||||
void Application::initializeGL() {
|
||||
qDebug( "Created Display Window.");
|
||||
|
||||
|
@ -650,7 +640,7 @@ void Application::paintGL() {
|
|||
_myCamera.update(1.0f / _fps);
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
||||
if (getShadowsEnabled()) {
|
||||
updateShadowMap();
|
||||
}
|
||||
|
||||
|
@ -706,6 +696,24 @@ void Application::paintGL() {
|
|||
_frameCount++;
|
||||
}
|
||||
|
||||
void Application::runTests() {
|
||||
runTimingTests();
|
||||
}
|
||||
|
||||
void Application::audioMuteToggled() {
|
||||
QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteAudio);
|
||||
Q_CHECK_PTR(muteAction);
|
||||
muteAction->setChecked(DependencyManager::get<Audio>()->isMuted());
|
||||
}
|
||||
|
||||
void Application::aboutApp() {
|
||||
InfoView::forcedShow(INFO_HELP_PATH);
|
||||
}
|
||||
|
||||
void Application::showEditEntitiesHelp() {
|
||||
InfoView::forcedShow(INFO_EDIT_ENTITIES_PATH);
|
||||
}
|
||||
|
||||
void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) {
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::configureCamera(camera, width, height);
|
||||
|
@ -713,7 +721,7 @@ void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height)
|
|||
TV3DManager::configureCamera(camera, width, height);
|
||||
} else {
|
||||
camera.setAspectRatio((float)width / height);
|
||||
camera.setFieldOfView(Menu::getInstance()->getFieldOfView());
|
||||
camera.setFieldOfView(_viewFrustum.getFieldOfView());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1436,10 +1444,6 @@ void Application::idle() {
|
|||
|
||||
// After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
|
||||
idleTimer->start(2);
|
||||
|
||||
if (_numChangedSettings > 0) {
|
||||
saveSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1457,7 +1461,7 @@ void Application::checkBandwidthMeterClick() {
|
|||
|
||||
// The bandwidth meter is visible, the click didn't get dragged too far and
|
||||
// we actually hit the bandwidth meter
|
||||
Menu::getInstance()->bandwidthDetails();
|
||||
DependencyManager::get<DialogsManager>()->bandwidthDetails();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1595,6 +1599,20 @@ bool Application::exportEntities(const QString& filename, float x, float y, floa
|
|||
return true;
|
||||
}
|
||||
|
||||
void Application::loadSettings() {
|
||||
DependencyManager::get<Audio>()->loadSettings();
|
||||
DependencyManager::get<LODManager>()->loadSettings();
|
||||
Menu::getInstance()->loadSettings();
|
||||
_myAvatar->loadData();
|
||||
}
|
||||
|
||||
void Application::saveSettings() {
|
||||
DependencyManager::get<Audio>()->saveSettings();
|
||||
DependencyManager::get<LODManager>()->saveSettings();
|
||||
Menu::getInstance()->saveSettings();
|
||||
_myAvatar->saveData();
|
||||
}
|
||||
|
||||
bool Application::importEntities(const QString& filename) {
|
||||
_entityClipboard.eraseAllOctreeElements();
|
||||
bool success = _entityClipboard.readFromSVOFile(filename.toLocal8Bit().constData());
|
||||
|
@ -1645,8 +1663,6 @@ void Application::init() {
|
|||
|
||||
_timerStart.start();
|
||||
_lastTimeUpdated.start();
|
||||
|
||||
Menu::getInstance()->loadSettings();
|
||||
|
||||
// when --url in command line, teleport to location
|
||||
const QString HIFI_URL_COMMAND_LINE_KEY = "--url";
|
||||
|
@ -1664,11 +1680,11 @@ void Application::init() {
|
|||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseEnabled)) {
|
||||
// on OS X we only setup sixense if the user wants it on - this allows running without the hid_init crash
|
||||
// if hydra support is temporarily not required
|
||||
Menu::getInstance()->toggleSixense(true);
|
||||
SixenseManager::getInstance().toggleSixense(true);
|
||||
}
|
||||
#else
|
||||
// setup sixense
|
||||
Menu::getInstance()->toggleSixense(true);
|
||||
SixenseManager::getInstance().toggleSixense(true);
|
||||
#endif
|
||||
|
||||
// initialize our face trackers after loading the menu settings
|
||||
|
@ -1707,16 +1723,13 @@ void Application::init() {
|
|||
_metavoxels.init();
|
||||
|
||||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
_rearMirrorTools = new RearMirrorTools(glCanvas.data(), _mirrorViewRect, _settings);
|
||||
_rearMirrorTools = new RearMirrorTools(glCanvas.data(), _mirrorViewRect);
|
||||
|
||||
connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView()));
|
||||
connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView()));
|
||||
connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView()));
|
||||
connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors()));
|
||||
|
||||
// save settings when avatar changes
|
||||
connect(_myAvatar, &MyAvatar::transformChanged, this, &Application::bumpSettings);
|
||||
|
||||
// make sure our texture cache knows about window size changes
|
||||
DependencyManager::get<TextureCache>()->associateWithWidget(glCanvas.data());
|
||||
|
||||
|
@ -1758,9 +1771,9 @@ void Application::updateLOD() {
|
|||
PerformanceTimer perfTimer("LOD");
|
||||
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD) && !isThrottleRendering()) {
|
||||
Menu::getInstance()->autoAdjustLOD(_fps);
|
||||
DependencyManager::get<LODManager>()->autoAdjustLOD(_fps);
|
||||
} else {
|
||||
Menu::getInstance()->resetLODAdjust();
|
||||
DependencyManager::get<LODManager>()->resetLODAdjust();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1877,7 +1890,7 @@ void Application::updateMyAvatarLookAtPosition() {
|
|||
// deflect using Faceshift gaze data
|
||||
glm::vec3 origin = _myAvatar->getHead()->getEyePosition();
|
||||
float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f;
|
||||
float deflection = Menu::getInstance()->getFaceshiftEyeDeflection();
|
||||
float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection();
|
||||
if (isLookingAtSomeone) {
|
||||
deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT;
|
||||
}
|
||||
|
@ -1949,14 +1962,15 @@ void Application::updateDialogs(float deltaTime) {
|
|||
PerformanceTimer perfTimer("updateDialogs");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateDialogs()");
|
||||
|
||||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||
|
||||
// Update bandwidth dialog, if any
|
||||
BandwidthDialog* bandwidthDialog = Menu::getInstance()->getBandwidthDialog();
|
||||
BandwidthDialog* bandwidthDialog = dialogsManager->getBandwidthDialog();
|
||||
if (bandwidthDialog) {
|
||||
bandwidthDialog->update();
|
||||
}
|
||||
|
||||
OctreeStatsDialog* octreeStatsDialog = Menu::getInstance()->getOctreeStatsDialog();
|
||||
QPointer<OctreeStatsDialog> octreeStatsDialog = dialogsManager->getOctreeStatsDialog();
|
||||
if (octreeStatsDialog) {
|
||||
octreeStatsDialog->update();
|
||||
}
|
||||
|
@ -2227,8 +2241,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
_octreeQuery.setCameraNearClip(_viewFrustum.getNearClip());
|
||||
_octreeQuery.setCameraFarClip(_viewFrustum.getFarClip());
|
||||
_octreeQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition());
|
||||
_octreeQuery.setOctreeSizeScale(Menu::getInstance()->getOctreeSizeScale());
|
||||
_octreeQuery.setBoundaryLevelAdjust(Menu::getInstance()->getBoundaryLevelAdjust());
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
_octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
|
||||
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
|
||||
|
||||
unsigned char queryPacket[MAX_PACKET_SIZE];
|
||||
|
||||
|
@ -2280,7 +2295,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
int perServerPPS = 0;
|
||||
const int SMALL_BUDGET = 10;
|
||||
int perUnknownServer = SMALL_BUDGET;
|
||||
int totalPPS = Menu::getInstance()->getMaxOctreePacketsPerSecond();
|
||||
int totalPPS = _octreeQuery.getMaxOctreePacketsPerSecond();
|
||||
|
||||
// determine PPS based on number of servers
|
||||
if (inViewServers >= 1) {
|
||||
|
@ -2401,7 +2416,7 @@ QRect Application::getDesirableApplicationGeometry() {
|
|||
|
||||
// If our parent window is on the HMD, then don't use it's geometry, instead use
|
||||
// the "main screen" geometry.
|
||||
HMDToolsDialog* hmdTools = Menu::getInstance()->getHMDToolsDialog();
|
||||
HMDToolsDialog* hmdTools = DependencyManager::get<DialogsManager>()->getHMDToolsDialog();
|
||||
if (hmdTools && hmdTools->hasHMDScreen()) {
|
||||
QScreen* hmdScreen = hmdTools->getHMDScreen();
|
||||
QWindow* appWindow = getWindow()->windowHandle();
|
||||
|
@ -2626,15 +2641,15 @@ void Application::setupWorldLight() {
|
|||
}
|
||||
|
||||
bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) {
|
||||
return Menu::getInstance()->shouldRenderMesh(largestDimension, distanceToCamera);
|
||||
return DependencyManager::get<LODManager>()->shouldRenderMesh(largestDimension, distanceToCamera);
|
||||
}
|
||||
|
||||
float Application::getSizeScale() const {
|
||||
return Menu::getInstance()->getOctreeSizeScale();
|
||||
return DependencyManager::get<LODManager>()->getOctreeSizeScale();
|
||||
}
|
||||
|
||||
int Application::getBoundaryLevelAdjust() const {
|
||||
return Menu::getInstance()->getBoundaryLevelAdjust();
|
||||
return DependencyManager::get<LODManager>()->getBoundaryLevelAdjust();
|
||||
}
|
||||
|
||||
PickRay Application::computePickRay(float x, float y) {
|
||||
|
@ -2930,8 +2945,10 @@ void Application::computeOffAxisFrustum(float& left, float& right, float& bottom
|
|||
}
|
||||
}
|
||||
|
||||
bool Application::getShadowsEnabled() {
|
||||
return Menu::getInstance()->getShadowsEnabled();
|
||||
bool Application::getShadowsEnabled() {
|
||||
Menu* menubar = Menu::getInstance();
|
||||
return menubar->isOptionChecked(MenuOption::SimpleShadows) ||
|
||||
menubar->isOptionChecked(MenuOption::CascadedShadows);
|
||||
}
|
||||
|
||||
bool Application::getCascadeShadowsEnabled() {
|
||||
|
@ -2976,7 +2993,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
|||
_mirrorCamera.setPosition(_myAvatar->getPosition() +
|
||||
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale());
|
||||
|
||||
} else if (_rearMirrorTools->getZoomLevel() == BODY) {
|
||||
} else if (SettingHandles::rearViewZoomLevel.get() == BODY) {
|
||||
_mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees
|
||||
_mirrorCamera.setPosition(_myAvatar->getChestPosition() +
|
||||
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());
|
||||
|
@ -3373,45 +3390,45 @@ void Application::packetSent(quint64 length) {
|
|||
_bandwidthMeter.outputStream(BandwidthMeter::OCTREE).updateValue(length);
|
||||
}
|
||||
|
||||
const QString SETTINGS_KEY = "Settings";
|
||||
|
||||
void Application::loadScripts() {
|
||||
// loads all saved scripts
|
||||
int size = lockSettings()->beginReadArray("Settings");
|
||||
unlockSettings();
|
||||
Settings settings;
|
||||
int size = settings.beginReadArray(SETTINGS_KEY);
|
||||
for (int i = 0; i < size; ++i){
|
||||
lockSettings()->setArrayIndex(i);
|
||||
QString string = _settings->value("script").toString();
|
||||
unlockSettings();
|
||||
settings.setArrayIndex(i);
|
||||
QString string = settings.value("script").toString();
|
||||
if (!string.isEmpty()) {
|
||||
loadScript(string);
|
||||
}
|
||||
}
|
||||
|
||||
QMutexLocker locker(&_settingsMutex);
|
||||
_settings->endArray();
|
||||
settings.endArray();
|
||||
}
|
||||
|
||||
void Application::clearScriptsBeforeRunning() {
|
||||
// clears all scripts from the settings
|
||||
QMutexLocker locker(&_settingsMutex);
|
||||
_settings->remove("Settings");
|
||||
SettingHandles::SettingHandle<QVariant>(SETTINGS_KEY).remove();
|
||||
}
|
||||
|
||||
void Application::saveScripts() {
|
||||
// Saves all currently running user-loaded scripts
|
||||
QMutexLocker locker(&_settingsMutex);
|
||||
_settings->beginWriteArray("Settings");
|
||||
|
||||
QStringList runningScripts = getRunningScripts();
|
||||
if (runningScripts.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Saves all currently running user-loaded scripts
|
||||
Settings settings;
|
||||
settings.beginWriteArray(SETTINGS_KEY);
|
||||
int i = 0;
|
||||
for (QStringList::const_iterator it = runningScripts.begin(); it != runningScripts.end(); it += 1) {
|
||||
for (auto it = runningScripts.begin(); it != runningScripts.end(); ++it) {
|
||||
if (getScriptEngine(*it)->isUserLoaded()) {
|
||||
_settings->setArrayIndex(i);
|
||||
_settings->setValue("script", *it);
|
||||
i += 1;
|
||||
settings.setArrayIndex(i);
|
||||
settings.setValue("script", *it);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
_settings->endArray();
|
||||
settings.endArray();
|
||||
}
|
||||
|
||||
QScriptValue joystickToScriptValue(QScriptEngine *engine, Joystick* const &in) {
|
||||
|
@ -3438,7 +3455,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
scriptEngine->registerGlobalObject("Camera", &_myCamera);
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
scriptEngine->registerGlobalObject("SpeechRecognizer", Menu::getInstance()->getSpeechRecognizer());
|
||||
scriptEngine->registerGlobalObject("SpeechRecognizer", DependencyManager::get<SpeechRecognizer>().data());
|
||||
#endif
|
||||
|
||||
ClipboardScriptingInterface* clipboardScriptable = new ClipboardScriptingInterface();
|
||||
|
@ -3538,7 +3555,6 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
|
|||
if (activateMainWindow && !loadScriptFromEditor) {
|
||||
_window->activateWindow();
|
||||
}
|
||||
bumpSettings();
|
||||
|
||||
return scriptEngine;
|
||||
}
|
||||
|
@ -3566,7 +3582,6 @@ void Application::scriptFinished(const QString& scriptName) {
|
|||
_scriptEnginesHash.erase(it);
|
||||
_runningScriptsWidget->scriptStopped(scriptName);
|
||||
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
||||
bumpSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3662,7 +3677,6 @@ void Application::openUrl(const QUrl& url) {
|
|||
}
|
||||
|
||||
void Application::updateMyAvatarTransform() {
|
||||
bumpSettings();
|
||||
const float SIMULATION_OFFSET_QUANTIZATION = 16.0f; // meters
|
||||
glm::vec3 avatarPosition = _myAvatar->getPosition();
|
||||
glm::vec3 physicsWorldOffset = _physicsEngine.getOriginOffset();
|
||||
|
@ -3679,7 +3693,6 @@ void Application::updateMyAvatarTransform() {
|
|||
}
|
||||
|
||||
void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject) {
|
||||
|
||||
// from the domain-handler, figure out the satoshi cost per voxel and per meter cubed
|
||||
const QString VOXEL_SETTINGS_KEY = "voxels";
|
||||
const QString PER_VOXEL_COST_KEY = "per-voxel-credits";
|
||||
|
@ -3722,9 +3735,7 @@ QString Application::getPreviousScriptLocation() {
|
|||
|
||||
void Application::setPreviousScriptLocation(const QString& previousScriptLocation) {
|
||||
_previousScriptLocation = previousScriptLocation;
|
||||
QMutexLocker locker(&_settingsMutex);
|
||||
_settings->setValue("LastScriptLocation", _previousScriptLocation);
|
||||
bumpSettings();
|
||||
SettingHandles::lastScriptLocation.set(_previousScriptLocation);
|
||||
}
|
||||
|
||||
void Application::loadDialog() {
|
||||
|
@ -3740,7 +3751,6 @@ void Application::loadDialog() {
|
|||
}
|
||||
|
||||
void Application::loadScriptURLDialog() {
|
||||
|
||||
QInputDialog scriptURLDialog(Application::getInstance()->getWindow());
|
||||
scriptURLDialog.setWindowTitle("Open and Run Script URL");
|
||||
scriptURLDialog.setLabelText("Script:");
|
||||
|
@ -3758,11 +3768,16 @@ void Application::loadScriptURLDialog() {
|
|||
}
|
||||
loadScript(newScript);
|
||||
}
|
||||
|
||||
sendFakeEnterEvent();
|
||||
}
|
||||
|
||||
QString Application::getScriptsLocation() const {
|
||||
return SettingHandles::scriptsLocation.get();
|
||||
}
|
||||
|
||||
void Application::setScriptsLocation(const QString& scriptsLocation) {
|
||||
SettingHandles::scriptsLocation.set(scriptsLocation);
|
||||
emit scriptLocationChanged(scriptsLocation);
|
||||
}
|
||||
|
||||
void Application::toggleLogDialog() {
|
||||
if (! _logDialog) {
|
||||
|
@ -3864,7 +3879,8 @@ void Application::takeSnapshot() {
|
|||
_snapshotShareDialog->show();
|
||||
}
|
||||
|
||||
void Application::setVSyncEnabled(bool vsyncOn) {
|
||||
void Application::setVSyncEnabled() {
|
||||
bool vsyncOn = Menu::getInstance()->isOptionChecked(MenuOption::RenderTargetFramerateVSyncOn);
|
||||
#if defined(Q_OS_WIN)
|
||||
if (wglewGetExtension("WGL_EXT_swap_control")) {
|
||||
wglSwapIntervalEXT(vsyncOn);
|
||||
|
@ -3888,6 +3904,7 @@ void Application::setVSyncEnabled(bool vsyncOn) {
|
|||
#else
|
||||
qDebug("V-Sync is FORCED ON on this system\n");
|
||||
#endif
|
||||
vsyncOn = true; // Turns off unused variable warning
|
||||
}
|
||||
|
||||
bool Application::isVSyncOn() const {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <QImage>
|
||||
#include <QPointer>
|
||||
#include <QSet>
|
||||
#include <QSettings>
|
||||
#include <QStringList>
|
||||
#include <QUndoStack>
|
||||
|
||||
|
@ -34,10 +33,10 @@
|
|||
#include <PacketHeaders.h>
|
||||
#include <PhysicsEngine.h>
|
||||
#include <ScriptEngine.h>
|
||||
#include <StDev.h>
|
||||
#include <TextureCache.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "Audio.h"
|
||||
#include "Bookmarks.h"
|
||||
#include "Camera.h"
|
||||
#include "DatagramProcessor.h"
|
||||
|
@ -80,7 +79,6 @@
|
|||
class QGLWidget;
|
||||
class QKeyEvent;
|
||||
class QMouseEvent;
|
||||
class QSettings;
|
||||
class QSystemTrayIcon;
|
||||
class QTouchEvent;
|
||||
class QWheelEvent;
|
||||
|
@ -121,6 +119,12 @@ static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS
|
|||
static const QString INFO_HELP_PATH = "html/interface-welcome-allsvg.html";
|
||||
static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-entities-commands.html";
|
||||
|
||||
class Application;
|
||||
#if defined(qApp)
|
||||
#undef qApp
|
||||
#endif
|
||||
#define qApp (static_cast<Application*>(QCoreApplication::instance()))
|
||||
|
||||
class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -128,18 +132,16 @@ class Application : public QApplication, public AbstractViewStateInterface, Abst
|
|||
friend class DatagramProcessor;
|
||||
|
||||
public:
|
||||
static Application* getInstance() { return static_cast<Application*>(QCoreApplication::instance()); }
|
||||
static Application* getInstance() { return qApp; } // TODO: replace fully by qApp
|
||||
static const glm::vec3& getPositionForPath() { return getInstance()->_myAvatar->getPosition(); }
|
||||
static glm::quat getOrientationForPath() { return getInstance()->_myAvatar->getOrientation(); }
|
||||
|
||||
Application(int& argc, char** argv, QElapsedTimer &startup_time);
|
||||
~Application();
|
||||
|
||||
void restoreSizeAndPosition();
|
||||
void loadScripts();
|
||||
QString getPreviousScriptLocation();
|
||||
void setPreviousScriptLocation(const QString& previousScriptLocation);
|
||||
void storeSizeAndPosition();
|
||||
void clearScriptsBeforeRunning();
|
||||
void initializeGL();
|
||||
void paintGL();
|
||||
|
@ -180,6 +182,7 @@ public:
|
|||
PrioVR* getPrioVR() { return &_prioVR; }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
MainWindow* getWindow() { return _window; }
|
||||
OctreeQuery& getOctreeQuery() { return _octreeQuery; }
|
||||
|
||||
EntityTree* getEntityClipboard() { return &_entityClipboard; }
|
||||
EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; }
|
||||
|
@ -215,12 +218,6 @@ public:
|
|||
virtual const Transform& getViewTransform() const { return _viewTransform; }
|
||||
void setViewTransform(const Transform& view);
|
||||
|
||||
/// if you need to access the application settings, use lockSettings()/unlockSettings()
|
||||
QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
|
||||
void unlockSettings() { _settingsMutex.unlock(); }
|
||||
|
||||
void saveSettings();
|
||||
|
||||
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
|
||||
void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); }
|
||||
void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); }
|
||||
|
@ -303,6 +300,9 @@ public:
|
|||
RunningScriptsWidget* getRunningScriptsWidget() { return _runningScriptsWidget; }
|
||||
|
||||
Bookmarks* getBookmarks() const { return _bookmarks; }
|
||||
|
||||
QString getScriptsLocation() const;
|
||||
void setScriptsLocation(const QString& scriptsLocation);
|
||||
|
||||
signals:
|
||||
|
||||
|
@ -317,6 +317,8 @@ signals:
|
|||
|
||||
/// Fired when the import window is closed
|
||||
void importDone();
|
||||
|
||||
void scriptLocationChanged(const QString& newPath);
|
||||
|
||||
public slots:
|
||||
void domainChanged(const QString& domainHostname);
|
||||
|
@ -353,13 +355,17 @@ public slots:
|
|||
void openUrl(const QUrl& url);
|
||||
|
||||
void updateMyAvatarTransform();
|
||||
void bumpSettings() { ++_numChangedSettings; }
|
||||
|
||||
void domainSettingsReceived(const QJsonObject& domainSettingsObject);
|
||||
|
||||
void setVSyncEnabled(bool vsyncOn);
|
||||
void setVSyncEnabled();
|
||||
|
||||
void resetSensors();
|
||||
void aboutApp();
|
||||
void showEditEntitiesHelp();
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
private slots:
|
||||
void clearDomainOctreeDetails();
|
||||
|
@ -387,6 +393,10 @@ private slots:
|
|||
void parseVersionXml();
|
||||
|
||||
void manageRunningScriptsWidgetVisibility(bool shown);
|
||||
|
||||
void runTests();
|
||||
|
||||
void audioMuteToggled();
|
||||
|
||||
private:
|
||||
void resetCamerasOnResizeGL(Camera& camera, int width, int height);
|
||||
|
@ -443,10 +453,6 @@ private:
|
|||
QThread* _nodeThread;
|
||||
DatagramProcessor _datagramProcessor;
|
||||
|
||||
QMutex _settingsMutex;
|
||||
QSettings* _settings;
|
||||
int _numChangedSettings;
|
||||
|
||||
QUndoStack _undoStack;
|
||||
UndoStackScriptingInterface _undoStackScriptingInterface;
|
||||
|
||||
|
@ -566,6 +572,7 @@ private:
|
|||
RunningScriptsWidget* _runningScriptsWidget;
|
||||
QHash<QString, ScriptEngine*> _scriptEnginesHash;
|
||||
bool _runningScriptsWidgetWasVisible;
|
||||
QString _scriptsLocation;
|
||||
|
||||
QSystemTrayIcon* _trayIcon;
|
||||
|
||||
|
@ -579,6 +586,9 @@ private:
|
|||
bool _aboutToQuit;
|
||||
|
||||
Bookmarks* _bookmarks;
|
||||
|
||||
QThread _settingsThread;
|
||||
QTimer _settingsTimer;
|
||||
};
|
||||
|
||||
#endif // hifi_Application_h
|
||||
|
|
|
@ -10,9 +10,10 @@
|
|||
//
|
||||
|
||||
#include <cstring>
|
||||
#include <math.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <CoreAudio/AudioHardware.h>
|
||||
|
@ -28,29 +29,35 @@
|
|||
#include <VersionHelpers.h>
|
||||
#endif
|
||||
|
||||
#include <AudioConstants.h>
|
||||
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtMultimedia/QAudioInput>
|
||||
#include <QtMultimedia/QAudioOutput>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <AudioConstants.h>
|
||||
#include <AudioInjector.h>
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
|
||||
#include <PositionalAudioStream.h>
|
||||
|
||||
#include <Settings.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include "Audio.h"
|
||||
|
||||
static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100;
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<bool> audioOutputStarveDetectionEnabled("audioOutputStarveDetectionEnabled",
|
||||
DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_ENABLED);
|
||||
const SettingHandle<int> audioOutputStarveDetectionThreshold("audioOutputStarveDetectionThreshold",
|
||||
DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_THRESHOLD);
|
||||
const SettingHandle<int> audioOutputStarveDetectionPeriod("audioOutputStarveDetectionPeriod",
|
||||
DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_PERIOD);
|
||||
const SettingHandle<int> audioOutputBufferSize("audioOutputBufferSize",
|
||||
DEFAULT_MAX_FRAMES_OVER_DESIRED);
|
||||
}
|
||||
|
||||
Audio::Audio() :
|
||||
AbstractAudioInterface(),
|
||||
_audioInput(NULL),
|
||||
|
@ -1129,3 +1136,28 @@ void Audio::checkDevices() {
|
|||
emit deviceChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void Audio::loadSettings() {
|
||||
_receivedAudioStream.loadSettings();
|
||||
|
||||
setOutputStarveDetectionEnabled(SettingHandles::audioOutputStarveDetectionEnabled.get());
|
||||
setOutputStarveDetectionThreshold(SettingHandles::audioOutputStarveDetectionThreshold.get());
|
||||
setOutputStarveDetectionPeriod(SettingHandles::audioOutputStarveDetectionPeriod.get());
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setOutputBufferSize",
|
||||
Q_ARG(int, SettingHandles::audioOutputBufferSize.get()));
|
||||
} else {
|
||||
setOutputBufferSize(SettingHandles::audioOutputBufferSize.get());
|
||||
}
|
||||
}
|
||||
|
||||
void Audio::saveSettings() {
|
||||
_receivedAudioStream.saveSettings();
|
||||
|
||||
SettingHandles::audioOutputStarveDetectionEnabled.set(getOutputStarveDetectionEnabled());
|
||||
SettingHandles::audioOutputStarveDetectionThreshold.set(getOutputStarveDetectionThreshold());
|
||||
SettingHandles::audioOutputStarveDetectionPeriod.set(getOutputStarveDetectionPeriod());
|
||||
SettingHandles::audioOutputBufferSize.set(getOutputBufferSize());
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <DependencyManager.h>
|
||||
#include <StDev.h>
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
#include "audio/AudioIOStats.h"
|
||||
#include "audio/AudioNoiseGate.h"
|
||||
#include "AudioStreamStats.h"
|
||||
|
@ -96,14 +95,13 @@ public:
|
|||
};
|
||||
|
||||
const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; }
|
||||
MixedProcessedAudioStream& getReceivedAudioStream() { return _receivedAudioStream; }
|
||||
|
||||
float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _inputGate.getMeasuredFloor(), 0.0f); }
|
||||
|
||||
float getTimeSinceLastClip() const { return _timeSinceLastClip; }
|
||||
float getAudioAverageInputLoudness() const { return _lastInputLoudness; }
|
||||
|
||||
void setReceivedAudioStreamSettings(const InboundAudioStream::Settings& settings) { _receivedAudioStream.setSettings(settings); }
|
||||
|
||||
int getDesiredJitterBufferFrames() const { return _receivedAudioStream.getDesiredJitterBufferFrames(); }
|
||||
|
||||
bool isMuted() { return _muted; }
|
||||
|
@ -174,6 +172,9 @@ public slots:
|
|||
|
||||
void outputNotify();
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
signals:
|
||||
bool muteToggled();
|
||||
void inputReceived(const QByteArray& inputSamples);
|
||||
|
|
|
@ -9,10 +9,21 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QFile>
|
||||
#include <QInputDialog>
|
||||
#include <QJsonDocument>
|
||||
#include <QMessageBox>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include <AddressManager.h>
|
||||
#include <Application.h>
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "Menu.h"
|
||||
|
||||
#include "Bookmarks.h"
|
||||
|
||||
Bookmarks::Bookmarks() {
|
||||
|
@ -71,3 +82,125 @@ void Bookmarks::persistToFile() {
|
|||
QByteArray data = json.toJson();
|
||||
saveFile.write(data);
|
||||
}
|
||||
|
||||
void Bookmarks::setupMenus(Menu* menubar, QMenu* menu) {
|
||||
// Add menus/actions
|
||||
menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkLocation, 0,
|
||||
this, SLOT(bookmarkLocation()));
|
||||
_bookmarksMenu = menu->addMenu(MenuOption::Bookmarks);
|
||||
_deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteBookmark, 0,
|
||||
this, SLOT(deleteBookmark()));
|
||||
|
||||
// Enable/Disable menus as needed
|
||||
enableMenuItems(_bookmarks.count() > 0);
|
||||
|
||||
// Load bookmarks
|
||||
for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it ) {
|
||||
QString bookmarkName = it.key();
|
||||
QString bookmarkAddress = it.value().toString();
|
||||
addLocationToMenu(menubar, bookmarkName, bookmarkAddress);
|
||||
}
|
||||
}
|
||||
|
||||
void Bookmarks::bookmarkLocation() {
|
||||
QInputDialog bookmarkLocationDialog(qApp->getWindow());
|
||||
bookmarkLocationDialog.setWindowTitle("Bookmark Location");
|
||||
bookmarkLocationDialog.setLabelText("Name:");
|
||||
bookmarkLocationDialog.setInputMode(QInputDialog::TextInput);
|
||||
bookmarkLocationDialog.resize(400, 200);
|
||||
|
||||
if (bookmarkLocationDialog.exec() == QDialog::Rejected) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString bookmarkName = bookmarkLocationDialog.textValue().trimmed();
|
||||
bookmarkName = bookmarkName.replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " ");
|
||||
if (bookmarkName.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto addressManager = DependencyManager::get<AddressManager>();
|
||||
QString bookmarkAddress = addressManager->currentAddress().toString();
|
||||
|
||||
Menu* menubar = Menu::getInstance();
|
||||
if (contains(bookmarkName)) {
|
||||
QMessageBox duplicateBookmarkMessage;
|
||||
duplicateBookmarkMessage.setIcon(QMessageBox::Warning);
|
||||
duplicateBookmarkMessage.setText("The bookmark name you entered already exists in your list.");
|
||||
duplicateBookmarkMessage.setInformativeText("Would you like to overwrite it?");
|
||||
duplicateBookmarkMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
duplicateBookmarkMessage.setDefaultButton(QMessageBox::Yes);
|
||||
if (duplicateBookmarkMessage.exec() == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
removeLocationFromMenu(menubar, bookmarkName);
|
||||
}
|
||||
|
||||
addLocationToMenu(menubar, bookmarkName, bookmarkAddress);
|
||||
insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName.
|
||||
|
||||
enableMenuItems(true);
|
||||
}
|
||||
|
||||
void Bookmarks::teleportToBookmark() {
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
QString address = action->data().toString();
|
||||
DependencyManager::get<AddressManager>()->handleLookupString(address);
|
||||
}
|
||||
|
||||
void Bookmarks::deleteBookmark() {
|
||||
|
||||
QStringList bookmarkList;
|
||||
QList<QAction*> menuItems = _bookmarksMenu->actions();
|
||||
for (int i = 0; i < menuItems.count(); i += 1) {
|
||||
bookmarkList.append(menuItems[i]->text());
|
||||
}
|
||||
|
||||
QInputDialog deleteBookmarkDialog(qApp->getWindow());
|
||||
deleteBookmarkDialog.setWindowTitle("Delete Bookmark");
|
||||
deleteBookmarkDialog.setLabelText("Select the bookmark to delete");
|
||||
deleteBookmarkDialog.resize(400, 400);
|
||||
deleteBookmarkDialog.setOption(QInputDialog::UseListViewForComboBoxItems);
|
||||
deleteBookmarkDialog.setComboBoxItems(bookmarkList);
|
||||
deleteBookmarkDialog.setOkButtonText("Delete");
|
||||
|
||||
if (deleteBookmarkDialog.exec() == QDialog::Rejected) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString bookmarkName = deleteBookmarkDialog.textValue().trimmed();
|
||||
if (bookmarkName.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
removeLocationFromMenu(Menu::getInstance(), bookmarkName);
|
||||
remove(bookmarkName);
|
||||
|
||||
if (_bookmarksMenu->actions().count() == 0) {
|
||||
enableMenuItems(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Bookmarks::enableMenuItems(bool enabled) {
|
||||
if (_bookmarksMenu) {
|
||||
_bookmarksMenu->setEnabled(enabled);
|
||||
}
|
||||
if (_deleteBookmarksAction) {
|
||||
_deleteBookmarksAction->setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void Bookmarks::addLocationToMenu(Menu* menubar, QString& name, QString& address) {
|
||||
QAction* teleportAction = new QAction(_bookmarksMenu);
|
||||
teleportAction->setData(address);
|
||||
connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark()));
|
||||
|
||||
menubar->addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction,
|
||||
name, 0, QAction::NoRole);
|
||||
}
|
||||
|
||||
void Bookmarks::removeLocationFromMenu(Menu* menubar, QString& name) {
|
||||
menubar->removeAction(_bookmarksMenu, name);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,10 +12,13 @@
|
|||
#ifndef hifi_Bookmarks_h
|
||||
#define hifi_Bookmarks_h
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QDebug>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class Menu;
|
||||
|
||||
class Bookmarks: public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -23,19 +26,32 @@ class Bookmarks: public QObject {
|
|||
public:
|
||||
Bookmarks();
|
||||
|
||||
void setupMenus(Menu* menubar, QMenu* menu);
|
||||
|
||||
private slots:
|
||||
void bookmarkLocation();
|
||||
void teleportToBookmark();
|
||||
void deleteBookmark();
|
||||
|
||||
private:
|
||||
QVariantMap _bookmarks; // { name: address, ... }
|
||||
|
||||
QPointer<QMenu> _bookmarksMenu;
|
||||
QPointer<QAction> _deleteBookmarksAction;
|
||||
|
||||
const QString BOOKMARKS_FILENAME = "bookmarks.json";
|
||||
QString _bookmarksFilename;
|
||||
|
||||
void insert(const QString& name, const QString& address); // Overwrites any existing entry with same name.
|
||||
void remove(const QString& name);
|
||||
bool contains(const QString& name) const;
|
||||
|
||||
QVariantMap* getBookmarks() { return &_bookmarks; };
|
||||
|
||||
private:
|
||||
QVariantMap _bookmarks; // { name: address, ... }
|
||||
|
||||
const QString BOOKMARKS_FILENAME = "bookmarks.json";
|
||||
QString _bookmarksFilename;
|
||||
void readFromFile();
|
||||
void persistToFile();
|
||||
|
||||
void enableMenuItems(bool enabled);
|
||||
void addLocationToMenu(Menu* menubar, QString& name, QString& address);
|
||||
void removeLocationFromMenu(Menu* menubar, QString& name);
|
||||
};
|
||||
|
||||
#endif // hifi_Bookmarks_h
|
|
@ -15,6 +15,7 @@
|
|||
#include <PerfStat.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Audio.h"
|
||||
#include "Menu.h"
|
||||
|
||||
#include "DatagramProcessor.h"
|
||||
|
|
210
interface/src/LODManager.cpp
Normal file
210
interface/src/LODManager.cpp
Normal file
|
@ -0,0 +1,210 @@
|
|||
//
|
||||
// LODManager.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 1/16/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <Util.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ui/DialogsManager.h"
|
||||
|
||||
#include "LODManager.h"
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<bool> automaticAvatarLOD("automaticAvatarLOD", true);
|
||||
const SettingHandle<float> avatarLODDecreaseFPS("avatarLODDecreaseFPS", DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS);
|
||||
const SettingHandle<float> avatarLODIncreaseFPS("avatarLODIncreaseFPS", ADJUST_LOD_UP_FPS);
|
||||
const SettingHandle<float> avatarLODDistanceMultiplier("avatarLODDistanceMultiplier",
|
||||
DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER);
|
||||
const SettingHandle<int> boundaryLevelAdjust("boundaryLevelAdjust", 0);
|
||||
const SettingHandle<float> octreeSizeScale("octreeSizeScale", DEFAULT_OCTREE_SIZE_SCALE);
|
||||
}
|
||||
|
||||
void LODManager::autoAdjustLOD(float currentFPS) {
|
||||
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
|
||||
// really want to count them in our average, so we will ignore the real frame rates and stuff
|
||||
// our moving average with simulated good data
|
||||
const int IGNORE_THESE_SAMPLES = 100;
|
||||
const float ASSUMED_FPS = 60.0f;
|
||||
if (_fpsAverage.getSampleCount() < IGNORE_THESE_SAMPLES) {
|
||||
currentFPS = ASSUMED_FPS;
|
||||
}
|
||||
_fpsAverage.updateAverage(currentFPS);
|
||||
_fastFPSAverage.updateAverage(currentFPS);
|
||||
|
||||
quint64 now = usecTimestampNow();
|
||||
|
||||
const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000;
|
||||
if (_automaticAvatarLOD) {
|
||||
if (_fastFPSAverage.getAverage() < _avatarLODDecreaseFPS) {
|
||||
if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) {
|
||||
// attempt to lower the detail in proportion to the fps difference
|
||||
float targetFps = (_avatarLODDecreaseFPS + _avatarLODIncreaseFPS) * 0.5f;
|
||||
float averageFps = _fastFPSAverage.getAverage();
|
||||
const float MAXIMUM_MULTIPLIER_SCALE = 2.0f;
|
||||
_avatarLODDistanceMultiplier = qMin(MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier *
|
||||
(averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE :
|
||||
qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps)));
|
||||
_lastAvatarDetailDrop = now;
|
||||
}
|
||||
} else if (_fastFPSAverage.getAverage() > _avatarLODIncreaseFPS) {
|
||||
// let the detail level creep slowly upwards
|
||||
const float DISTANCE_DECREASE_RATE = 0.05f;
|
||||
_avatarLODDistanceMultiplier = qMax(MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER,
|
||||
_avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
|
||||
}
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
quint64 elapsed = now - _lastAdjust;
|
||||
|
||||
if (elapsed > ADJUST_LOD_DOWN_DELAY && _fpsAverage.getAverage() < ADJUST_LOD_DOWN_FPS
|
||||
&& _octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
|
||||
|
||||
_octreeSizeScale *= ADJUST_LOD_DOWN_BY;
|
||||
|
||||
if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
|
||||
_octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
|
||||
}
|
||||
changed = true;
|
||||
_lastAdjust = now;
|
||||
qDebug() << "adjusting LOD down... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
|
||||
<< "_octreeSizeScale=" << _octreeSizeScale;
|
||||
}
|
||||
|
||||
if (elapsed > ADJUST_LOD_UP_DELAY && _fpsAverage.getAverage() > ADJUST_LOD_UP_FPS
|
||||
&& _octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) {
|
||||
_octreeSizeScale *= ADJUST_LOD_UP_BY;
|
||||
if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) {
|
||||
_octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE;
|
||||
}
|
||||
changed = true;
|
||||
_lastAdjust = now;
|
||||
qDebug() << "adjusting LOD up... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
|
||||
<< "_octreeSizeScale=" << _octreeSizeScale;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
_shouldRenderTableNeedsRebuilding = true;
|
||||
auto lodToolsDialog = DependencyManager::get<DialogsManager>()->getLodToolsDialog();
|
||||
if (lodToolsDialog) {
|
||||
lodToolsDialog->reloadSliders();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LODManager::resetLODAdjust() {
|
||||
_fpsAverage.reset();
|
||||
_fastFPSAverage.reset();
|
||||
_lastAvatarDetailDrop = _lastAdjust = usecTimestampNow();
|
||||
}
|
||||
|
||||
QString LODManager::getLODFeedbackText() {
|
||||
// determine granularity feedback
|
||||
int boundaryLevelAdjust = getBoundaryLevelAdjust();
|
||||
QString granularityFeedback;
|
||||
|
||||
switch (boundaryLevelAdjust) {
|
||||
case 0: {
|
||||
granularityFeedback = QString("at standard granularity.");
|
||||
} break;
|
||||
case 1: {
|
||||
granularityFeedback = QString("at half of standard granularity.");
|
||||
} break;
|
||||
case 2: {
|
||||
granularityFeedback = QString("at a third of standard granularity.");
|
||||
} break;
|
||||
default: {
|
||||
granularityFeedback = QString("at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
|
||||
} break;
|
||||
}
|
||||
|
||||
// distance feedback
|
||||
float octreeSizeScale = getOctreeSizeScale();
|
||||
float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
|
||||
QString result;
|
||||
if (relativeToDefault > 1.01) {
|
||||
result = QString("%1 further %2").arg(relativeToDefault,8,'f',2).arg(granularityFeedback);
|
||||
} else if (relativeToDefault > 0.99) {
|
||||
result = QString("the default distance %1").arg(granularityFeedback);
|
||||
} else {
|
||||
result = QString("%1 of default %2").arg(relativeToDefault,8,'f',3).arg(granularityFeedback);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: This is essentially the same logic used to render octree cells, but since models are more detailed then octree cells
|
||||
// I've added a voxelToModelRatio that adjusts how much closer to a model you have to be to see it.
|
||||
bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera) {
|
||||
const float octreeToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it.
|
||||
float octreeSizeScale = getOctreeSizeScale();
|
||||
int boundaryLevelAdjust = getBoundaryLevelAdjust();
|
||||
float maxScale = (float)TREE_SCALE;
|
||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / octreeToMeshRatio;
|
||||
|
||||
if (_shouldRenderTableNeedsRebuilding) {
|
||||
_shouldRenderTable.clear();
|
||||
|
||||
float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small
|
||||
float scale = maxScale;
|
||||
float visibleDistanceAtScale = visibleDistanceAtMaxScale;
|
||||
|
||||
while (scale > SMALLEST_SCALE_IN_TABLE) {
|
||||
scale /= 2.0f;
|
||||
visibleDistanceAtScale /= 2.0f;
|
||||
_shouldRenderTable[scale] = visibleDistanceAtScale;
|
||||
}
|
||||
_shouldRenderTableNeedsRebuilding = false;
|
||||
}
|
||||
|
||||
float closestScale = maxScale;
|
||||
float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale;
|
||||
QMap<float, float>::const_iterator lowerBound = _shouldRenderTable.lowerBound(largestDimension);
|
||||
if (lowerBound != _shouldRenderTable.constEnd()) {
|
||||
closestScale = lowerBound.key();
|
||||
visibleDistanceAtClosestScale = lowerBound.value();
|
||||
}
|
||||
|
||||
if (closestScale < largestDimension) {
|
||||
visibleDistanceAtClosestScale *= 2.0f;
|
||||
}
|
||||
|
||||
return (distanceToCamera <= visibleDistanceAtClosestScale);
|
||||
}
|
||||
|
||||
void LODManager::setOctreeSizeScale(float sizeScale) {
|
||||
_octreeSizeScale = sizeScale;
|
||||
_shouldRenderTableNeedsRebuilding = true;
|
||||
}
|
||||
|
||||
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
|
||||
_boundaryLevelAdjust = boundaryLevelAdjust;
|
||||
_shouldRenderTableNeedsRebuilding = true;
|
||||
}
|
||||
|
||||
|
||||
void LODManager::loadSettings() {
|
||||
setAutomaticAvatarLOD(SettingHandles::automaticAvatarLOD.get());
|
||||
setAvatarLODDecreaseFPS(SettingHandles::avatarLODDecreaseFPS.get());
|
||||
setAvatarLODIncreaseFPS(SettingHandles::avatarLODIncreaseFPS.get());
|
||||
setAvatarLODDistanceMultiplier(SettingHandles::avatarLODDistanceMultiplier.get());
|
||||
setBoundaryLevelAdjust(SettingHandles::boundaryLevelAdjust.get());
|
||||
setOctreeSizeScale(SettingHandles::octreeSizeScale.get());
|
||||
}
|
||||
|
||||
void LODManager::saveSettings() {
|
||||
SettingHandles::automaticAvatarLOD.set(getAutomaticAvatarLOD());
|
||||
SettingHandles::avatarLODDecreaseFPS.set(getAvatarLODDecreaseFPS());
|
||||
SettingHandles::avatarLODIncreaseFPS.set(getAvatarLODIncreaseFPS());
|
||||
SettingHandles::avatarLODDistanceMultiplier.set(getAvatarLODDistanceMultiplier());
|
||||
SettingHandles::boundaryLevelAdjust.set(getBoundaryLevelAdjust());
|
||||
SettingHandles::octreeSizeScale.set(getOctreeSizeScale());
|
||||
}
|
||||
|
||||
|
91
interface/src/LODManager.h
Normal file
91
interface/src/LODManager.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
//
|
||||
// LODManager.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 1/16/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_LODManager_h
|
||||
#define hifi_LODManager_h
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <OctreeConstants.h>
|
||||
#include <Settings.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
|
||||
const float ADJUST_LOD_DOWN_FPS = 40.0;
|
||||
const float ADJUST_LOD_UP_FPS = 55.0;
|
||||
const float DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f;
|
||||
|
||||
const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 5;
|
||||
const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2;
|
||||
|
||||
const float ADJUST_LOD_DOWN_BY = 0.9f;
|
||||
const float ADJUST_LOD_UP_BY = 1.1f;
|
||||
|
||||
const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.25f;
|
||||
const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
|
||||
|
||||
const float MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 0.1f;
|
||||
const float MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 15.0f;
|
||||
const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;
|
||||
|
||||
const int ONE_SECOND_OF_FRAMES = 60;
|
||||
const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;
|
||||
|
||||
|
||||
class LODManager : public Dependency {
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
void setAutomaticAvatarLOD(bool automaticAvatarLOD) { _automaticAvatarLOD = automaticAvatarLOD; }
|
||||
bool getAutomaticAvatarLOD() const { return _automaticAvatarLOD; }
|
||||
void setAvatarLODDecreaseFPS(float avatarLODDecreaseFPS) { _avatarLODDecreaseFPS = avatarLODDecreaseFPS; }
|
||||
float getAvatarLODDecreaseFPS() const { return _avatarLODDecreaseFPS; }
|
||||
void setAvatarLODIncreaseFPS(float avatarLODIncreaseFPS) { _avatarLODIncreaseFPS = avatarLODIncreaseFPS; }
|
||||
float getAvatarLODIncreaseFPS() const { return _avatarLODIncreaseFPS; }
|
||||
void setAvatarLODDistanceMultiplier(float multiplier) { _avatarLODDistanceMultiplier = multiplier; }
|
||||
float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
|
||||
|
||||
// User Tweakable LOD Items
|
||||
QString getLODFeedbackText();
|
||||
void setOctreeSizeScale(float sizeScale);
|
||||
float getOctreeSizeScale() const { return _octreeSizeScale; }
|
||||
|
||||
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
|
||||
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
||||
|
||||
void autoAdjustLOD(float currentFPS);
|
||||
void resetLODAdjust();
|
||||
|
||||
bool shouldRenderMesh(float largestDimension, float distanceToCamera);
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
private:
|
||||
LODManager() {}
|
||||
|
||||
bool _automaticAvatarLOD = true;
|
||||
float _avatarLODDecreaseFPS = DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS;
|
||||
float _avatarLODIncreaseFPS = ADJUST_LOD_UP_FPS;
|
||||
float _avatarLODDistanceMultiplier = DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER;
|
||||
|
||||
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
||||
int _boundaryLevelAdjust = 0;
|
||||
|
||||
quint64 _lastAdjust = 0;
|
||||
quint64 _lastAvatarDetailDrop = 0;
|
||||
SimpleMovingAverage _fpsAverage = FIVE_SECONDS_OF_FRAMES;
|
||||
SimpleMovingAverage _fastFPSAverage = ONE_SECOND_OF_FRAMES;
|
||||
|
||||
bool _shouldRenderTableNeedsRebuilding = true;
|
||||
QMap<float, float> _shouldRenderTable;
|
||||
};
|
||||
|
||||
#endif // hifi_LODManager_h
|
|
@ -9,9 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "Menu.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QEvent>
|
||||
#include <QMoveEvent>
|
||||
#include <QResizeEvent>
|
||||
|
@ -19,8 +18,33 @@
|
|||
#include <QHideEvent>
|
||||
#include <QWindowStateChangeEvent>
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) :
|
||||
QMainWindow(parent) {
|
||||
#include <Settings.h>
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "Menu.h"
|
||||
#include "Util.h"
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QRect> windowGeometry("WindowGeometry");
|
||||
}
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
|
||||
}
|
||||
|
||||
void MainWindow::restoreGeometry() {
|
||||
// Did not use setGeometry() on purpose,
|
||||
// see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
|
||||
QRect geometry = SettingHandles::windowGeometry.get(qApp->desktop()->availableGeometry());
|
||||
move(geometry.topLeft());
|
||||
resize(geometry.size());
|
||||
}
|
||||
|
||||
void MainWindow::saveGeometry() {
|
||||
// Did not use geometry() on purpose,
|
||||
// see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
|
||||
QRect geometry(pos(), size());
|
||||
SettingHandles::windowGeometry.set(geometry);
|
||||
}
|
||||
|
||||
void MainWindow::moveEvent(QMoveEvent* event) {
|
||||
|
|
|
@ -14,12 +14,15 @@
|
|||
|
||||
#include <QMainWindow>
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(QWidget* parent = NULL);
|
||||
|
||||
|
||||
public slots:
|
||||
void restoreGeometry();
|
||||
void saveGeometry();
|
||||
|
||||
signals:
|
||||
void windowGeometryChanged(QRect geometry);
|
||||
void windowShown(bool shown);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,128 +19,23 @@
|
|||
#include <QPointer>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include <EventTypes.h>
|
||||
#include <MenuItemProperties.h>
|
||||
#include <OctreeConstants.h>
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
#include "SpeechRecognizer.h"
|
||||
#endif
|
||||
|
||||
#include "devices/Faceshift.h"
|
||||
#include "devices/SixenseManager.h"
|
||||
#include "ui/ChatWindow.h"
|
||||
#include "ui/JSConsole.h"
|
||||
#include "ui/ScriptEditorWindow.h"
|
||||
|
||||
// Make an LOD handler class and move everything overthere
|
||||
const float ADJUST_LOD_DOWN_FPS = 40.0;
|
||||
const float ADJUST_LOD_UP_FPS = 55.0;
|
||||
const float DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f;
|
||||
|
||||
const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 5;
|
||||
const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2;
|
||||
|
||||
const float ADJUST_LOD_DOWN_BY = 0.9f;
|
||||
const float ADJUST_LOD_UP_BY = 1.1f;
|
||||
|
||||
const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.25f;
|
||||
const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
|
||||
|
||||
const float MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 0.1f;
|
||||
const float MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 15.0f;
|
||||
const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;
|
||||
|
||||
const int ONE_SECOND_OF_FRAMES = 60;
|
||||
const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
const float DEFAULT_OCULUS_UI_ANGULAR_SIZE = 72.0f;
|
||||
|
||||
const QString SETTINGS_ADDRESS_KEY = "address";
|
||||
class QSettings;
|
||||
|
||||
class AddressBarDialog;
|
||||
class AnimationsDialog;
|
||||
class AttachmentsDialog;
|
||||
class CachesSizeDialog;
|
||||
class BandwidthDialog;
|
||||
class DataWebDialog;
|
||||
class HMDToolsDialog;
|
||||
class LodToolsDialog;
|
||||
class LoginDialog;
|
||||
class OctreeStatsDialog;
|
||||
class PreferencesDialog;
|
||||
class MetavoxelEditor;
|
||||
class MetavoxelNetworkSimulator;
|
||||
class ChatWindow;
|
||||
class MenuItemProperties;
|
||||
class Settings;
|
||||
|
||||
class Menu : public QMenuBar {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static Menu* getInstance();
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
QMenu* getMenu(const QString& menuName);
|
||||
|
||||
void triggerOption(const QString& menuOption);
|
||||
QAction* getActionForOption(const QString& menuOption);
|
||||
|
||||
const InboundAudioStream::Settings& getReceivedAudioStreamSettings() const { return _receivedAudioStreamSettings; }
|
||||
void setReceivedAudioStreamSettings(const InboundAudioStream::Settings& receivedAudioStreamSettings) { _receivedAudioStreamSettings = receivedAudioStreamSettings; }
|
||||
float getFieldOfView() const { return _fieldOfView; }
|
||||
void setFieldOfView(float fieldOfView) { _fieldOfView = fieldOfView; bumpSettings(); }
|
||||
float getRealWorldFieldOfView() const { return _realWorldFieldOfView; }
|
||||
void setRealWorldFieldOfView(float realWorldFieldOfView) { _realWorldFieldOfView = realWorldFieldOfView; bumpSettings(); }
|
||||
float getOculusUIAngularSize() const { return _oculusUIAngularSize; }
|
||||
void setOculusUIAngularSize(float oculusUIAngularSize) { _oculusUIAngularSize = oculusUIAngularSize; bumpSettings(); }
|
||||
float getSixenseReticleMoveSpeed() const { return _sixenseReticleMoveSpeed; }
|
||||
void setSixenseReticleMoveSpeed(float sixenseReticleMoveSpeed) { _sixenseReticleMoveSpeed = sixenseReticleMoveSpeed; bumpSettings(); }
|
||||
bool getInvertSixenseButtons() const { return _invertSixenseButtons; }
|
||||
void setInvertSixenseButtons(bool invertSixenseButtons) { _invertSixenseButtons = invertSixenseButtons; bumpSettings(); }
|
||||
|
||||
float getFaceshiftEyeDeflection() const { return _faceshiftEyeDeflection; }
|
||||
void setFaceshiftEyeDeflection(float faceshiftEyeDeflection) { _faceshiftEyeDeflection = faceshiftEyeDeflection; bumpSettings(); }
|
||||
const QString& getFaceshiftHostname() const { return _faceshiftHostname; }
|
||||
void setFaceshiftHostname(const QString& hostname) { _faceshiftHostname = hostname; bumpSettings(); }
|
||||
QString getSnapshotsLocation() const;
|
||||
void setSnapshotsLocation(QString snapshotsLocation) { _snapshotsLocation = snapshotsLocation; bumpSettings(); }
|
||||
|
||||
const QString& getScriptsLocation() const { return _scriptsLocation; }
|
||||
void setScriptsLocation(const QString& scriptsLocation);
|
||||
|
||||
BandwidthDialog* getBandwidthDialog() const { return _bandwidthDialog; }
|
||||
OctreeStatsDialog* getOctreeStatsDialog() const { return _octreeStatsDialog; }
|
||||
LodToolsDialog* getLodToolsDialog() const { return _lodToolsDialog; }
|
||||
HMDToolsDialog* getHMDToolsDialog() const { return _hmdToolsDialog; }
|
||||
|
||||
bool getShadowsEnabled() const;
|
||||
|
||||
// User Tweakable LOD Items
|
||||
QString getLODFeedbackText();
|
||||
void autoAdjustLOD(float currentFPS);
|
||||
void resetLODAdjust();
|
||||
void setOctreeSizeScale(float sizeScale);
|
||||
float getOctreeSizeScale() const { return _octreeSizeScale; }
|
||||
void setAutomaticAvatarLOD(bool automaticAvatarLOD) { _automaticAvatarLOD = automaticAvatarLOD; bumpSettings(); }
|
||||
bool getAutomaticAvatarLOD() const { return _automaticAvatarLOD; }
|
||||
void setAvatarLODDecreaseFPS(float avatarLODDecreaseFPS) { _avatarLODDecreaseFPS = avatarLODDecreaseFPS; bumpSettings(); }
|
||||
float getAvatarLODDecreaseFPS() const { return _avatarLODDecreaseFPS; }
|
||||
void setAvatarLODIncreaseFPS(float avatarLODIncreaseFPS) { _avatarLODIncreaseFPS = avatarLODIncreaseFPS; bumpSettings(); }
|
||||
float getAvatarLODIncreaseFPS() const { return _avatarLODIncreaseFPS; }
|
||||
void setAvatarLODDistanceMultiplier(float multiplier) { _avatarLODDistanceMultiplier = multiplier; bumpSettings(); }
|
||||
float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
|
||||
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
|
||||
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
||||
|
||||
bool shouldRenderMesh(float largestDimension, float distanceToCamera);
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
SpeechRecognizer* getSpeechRecognizer() { return &_speechRecognizer; }
|
||||
#endif
|
||||
|
||||
// User Tweakable PPS from Voxel Server
|
||||
int getMaxOctreePacketsPerSecond() const { return _maxOctreePacketsPerSecond; }
|
||||
void setMaxOctreePacketsPerSecond(int value) { _maxOctreePacketsPerSecond = value; bumpSettings(); }
|
||||
|
||||
|
||||
QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||
const QString& actionName,
|
||||
const QKeySequence& shortcut = 0,
|
||||
|
@ -154,35 +49,10 @@ public:
|
|||
const QKeySequence& shortcut = 0,
|
||||
QAction::MenuRole role = QAction::NoRole,
|
||||
int menuItemLocation = UNSPECIFIED_POSITION);
|
||||
|
||||
|
||||
void removeAction(QMenu* menu, const QString& actionName);
|
||||
|
||||
const QByteArray& getWalletPrivateKey() const { return _walletPrivateKey; }
|
||||
|
||||
signals:
|
||||
void scriptLocationChanged(const QString& newPath);
|
||||
|
||||
public slots:
|
||||
|
||||
void clearLoginDialogDisplayedFlag();
|
||||
void loginForCurrentDomain();
|
||||
void showLoginForCurrentDomain();
|
||||
void bandwidthDetails();
|
||||
void octreeStatsDetails();
|
||||
void cachesSizeDialog();
|
||||
void lodTools();
|
||||
void hmdTools(bool showTools);
|
||||
void loadSettings(QSettings* settings = NULL);
|
||||
void saveSettings(QSettings* settings = NULL);
|
||||
void importSettings();
|
||||
void exportSettings();
|
||||
void toggleAddressBar();
|
||||
void copyAddress();
|
||||
void copyPath();
|
||||
|
||||
void toggleLoginMenuItem();
|
||||
void toggleSixense(bool shouldEnable);
|
||||
|
||||
QMenu* addMenu(const QString& menuName);
|
||||
void removeMenu(const QString& menuName);
|
||||
bool menuExists(const QString& menuName);
|
||||
|
@ -193,47 +63,21 @@ public slots:
|
|||
bool menuItemExists(const QString& menuName, const QString& menuitem);
|
||||
bool isOptionChecked(const QString& menuOption) const;
|
||||
void setIsOptionChecked(const QString& menuOption, bool isChecked);
|
||||
|
||||
private slots:
|
||||
void aboutApp();
|
||||
void showEditEntitiesHelp();
|
||||
void bumpSettings();
|
||||
void editPreferences();
|
||||
void editAttachments();
|
||||
void editAnimations();
|
||||
void changePrivateKey();
|
||||
void bookmarkLocation();
|
||||
void teleportToBookmark();
|
||||
void deleteBookmark();
|
||||
void hmdToolsClosed();
|
||||
void runTests();
|
||||
void showMetavoxelEditor();
|
||||
void showMetavoxelNetworkSimulator();
|
||||
void showScriptEditor();
|
||||
void showChat();
|
||||
void toggleConsole();
|
||||
void toggleToolWindow();
|
||||
void toggleChat();
|
||||
void audioMuteToggled();
|
||||
void displayNameLocationResponse(const QString& errorString);
|
||||
void changeVSync();
|
||||
void loadRSSDKFile();
|
||||
|
||||
|
||||
private:
|
||||
static Menu* _instance;
|
||||
|
||||
Menu();
|
||||
|
||||
typedef void(*settingsAction)(QSettings*, QAction*);
|
||||
static void loadAction(QSettings* set, QAction* action);
|
||||
static void saveAction(QSettings* set, QAction* action);
|
||||
void scanMenuBar(settingsAction modifySetting, QSettings* set);
|
||||
void scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set);
|
||||
|
||||
|
||||
typedef void(*settingsAction)(Settings&, QAction&);
|
||||
static void loadAction(Settings& settings, QAction& action);
|
||||
static void saveAction(Settings& settings, QAction& action);
|
||||
void scanMenuBar(settingsAction modifySetting);
|
||||
void scanMenu(QMenu& menu, settingsAction modifySetting, Settings& settings);
|
||||
|
||||
/// helper method to have separators with labels that are also compatible with OS X
|
||||
void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName,
|
||||
int menuItemLocation = UNSPECIFIED_POSITION);
|
||||
|
||||
int menuItemLocation = UNSPECIFIED_POSITION);
|
||||
|
||||
QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||
const QString& actionName,
|
||||
const QKeySequence& shortcut = 0,
|
||||
|
@ -241,78 +85,17 @@ private:
|
|||
const QObject* receiver = NULL,
|
||||
const char* member = NULL,
|
||||
int menuItemLocation = UNSPECIFIED_POSITION);
|
||||
|
||||
|
||||
QAction* getActionFromName(const QString& menuName, QMenu* menu);
|
||||
QMenu* getSubMenuFromName(const QString& menuName, QMenu* menu);
|
||||
QMenu* getMenuParent(const QString& menuName, QString& finalMenuPart);
|
||||
|
||||
|
||||
QAction* getMenuAction(const QString& menuName);
|
||||
int findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem);
|
||||
int positionBeforeSeparatorIfNeeded(QMenu* menu, int requestedPosition);
|
||||
QMenu* getMenu(const QString& menuName);
|
||||
|
||||
|
||||
|
||||
|
||||
QHash<QString, QAction*> _actionHash;
|
||||
InboundAudioStream::Settings _receivedAudioStreamSettings;
|
||||
// in Degrees, doesn't apply to HMD like Oculus
|
||||
float _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES;
|
||||
// The actual FOV set by the user's monitor size and view distance
|
||||
float _realWorldFieldOfView = DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES;
|
||||
float _faceshiftEyeDeflection = DEFAULT_FACESHIFT_EYE_DEFLECTION;
|
||||
QString _faceshiftHostname = DEFAULT_FACESHIFT_HOSTNAME;
|
||||
|
||||
QDialog* _jsConsole = nullptr;
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
SpeechRecognizer _speechRecognizer;
|
||||
#endif
|
||||
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
||||
float _oculusUIAngularSize = DEFAULT_OCULUS_UI_ANGULAR_SIZE;
|
||||
float _sixenseReticleMoveSpeed = DEFAULT_SIXENSE_RETICLE_MOVE_SPEED;
|
||||
bool _invertSixenseButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;
|
||||
bool _hasLoginDialogDisplayed = false;
|
||||
|
||||
bool _automaticAvatarLOD = true;
|
||||
float _avatarLODDecreaseFPS = DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS;
|
||||
float _avatarLODIncreaseFPS = ADJUST_LOD_UP_FPS;
|
||||
float _avatarLODDistanceMultiplier = DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER;
|
||||
|
||||
int _boundaryLevelAdjust = 0;
|
||||
int _maxOctreePacketsPerSecond = DEFAULT_MAX_OCTREE_PPS;
|
||||
|
||||
quint64 _lastAdjust;
|
||||
quint64 _lastAvatarDetailDrop;
|
||||
|
||||
SimpleMovingAverage _fpsAverage = FIVE_SECONDS_OF_FRAMES;
|
||||
SimpleMovingAverage _fastFPSAverage = ONE_SECOND_OF_FRAMES;
|
||||
|
||||
QPointer<AddressBarDialog> _addressBarDialog;
|
||||
QPointer<AnimationsDialog> _animationsDialog;
|
||||
QPointer<AttachmentsDialog> _attachmentsDialog;
|
||||
QPointer<BandwidthDialog> _bandwidthDialog;
|
||||
QPointer<CachesSizeDialog> _cachesSizeDialog;
|
||||
QPointer<HMDToolsDialog> _hmdToolsDialog;
|
||||
QPointer<LodToolsDialog> _lodToolsDialog;
|
||||
QPointer<LoginDialog> _loginDialog;
|
||||
QPointer<OctreeStatsDialog> _octreeStatsDialog;
|
||||
QPointer<PreferencesDialog> _preferencesDialog;
|
||||
|
||||
QPointer<MetavoxelEditor> _MetavoxelEditor;
|
||||
QPointer<MetavoxelNetworkSimulator> _metavoxelNetworkSimulator;
|
||||
QPointer<ScriptEditorWindow> _ScriptEditor;
|
||||
QPointer<ChatWindow> _chatWindow;
|
||||
|
||||
QAction* _loginAction = nullptr;
|
||||
QAction* _chatAction = nullptr;
|
||||
QString _snapshotsLocation;
|
||||
QString _scriptsLocation;
|
||||
QByteArray _walletPrivateKey;
|
||||
|
||||
bool _shouldRenderTableNeedsRebuilding = true;
|
||||
QMap<float, float> _shouldRenderTable;
|
||||
|
||||
void loadBookmarks();
|
||||
QMenu* _bookmarksMenu;
|
||||
QAction* _deleteBookmarksMenu;
|
||||
};
|
||||
|
||||
namespace MenuOption {
|
||||
|
@ -402,7 +185,6 @@ namespace MenuOption {
|
|||
const QString LodTools = "LOD Tools";
|
||||
const QString Login = "Login";
|
||||
const QString Log = "Log";
|
||||
const QString Logout = "Logout";
|
||||
const QString LowVelocityFilter = "Low Velocity Filter";
|
||||
const QString MetavoxelEditor = "Metavoxel Editor...";
|
||||
const QString Metavoxels = "Metavoxels";
|
||||
|
@ -484,10 +266,7 @@ namespace MenuOption {
|
|||
const QString UploadSkeleton = "Upload Skeleton Model";
|
||||
const QString UserInterface = "User Interface";
|
||||
const QString Visage = "Visage";
|
||||
const QString WalletPrivateKey = "Wallet Private Key...";
|
||||
const QString Wireframe = "Wireframe";
|
||||
}
|
||||
|
||||
void sendFakeEnterEvent();
|
||||
|
||||
#endif // hifi_Menu_h
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
|
@ -21,6 +22,7 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QHttpMultiPart>
|
||||
#include <QImage>
|
||||
#include <QJsonDocument>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressBar>
|
||||
|
@ -28,12 +30,17 @@
|
|||
#include <QStandardPaths>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTextStream>
|
||||
#include <QThread>
|
||||
#include <QVBoxLayout>
|
||||
#include <QVariant>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <Settings.h>
|
||||
#include <TextureCache.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ModelUploader.h"
|
||||
|
||||
|
||||
|
@ -53,8 +60,6 @@ static const QString BLENDSHAPE_FIELD = "bs";
|
|||
static const QString S3_URL = "http://public.highfidelity.io";
|
||||
static const QString MODEL_URL = "/api/v1/models";
|
||||
|
||||
static const QString SETTING_NAME = "LastModelUploadLocation";
|
||||
|
||||
static const unsigned long long MAX_SIZE = 50 * 1024 * BYTES_PER_MEGABYTES; // 50 GB (Virtually remove limit)
|
||||
static const int MAX_TEXTURE_SIZE = 1024;
|
||||
static const int TIMEOUT = 1000;
|
||||
|
@ -63,6 +68,11 @@ static const int MAX_CHECK = 30;
|
|||
static const int QCOMPRESS_HEADER_POSITION = 0;
|
||||
static const int QCOMPRESS_HEADER_SIZE = 4;
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QString> lastModelUploadLocation("LastModelUploadLocation",
|
||||
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
|
||||
}
|
||||
|
||||
void ModelUploader::uploadModel(ModelType modelType) {
|
||||
ModelUploader* uploader = new ModelUploader(modelType);
|
||||
QThread* thread = new QThread();
|
||||
|
@ -107,8 +117,7 @@ ModelUploader::~ModelUploader() {
|
|||
|
||||
bool ModelUploader::zip() {
|
||||
// File Dialog
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
QString lastLocation = settings->value(SETTING_NAME).toString();
|
||||
QString lastLocation = SettingHandles::lastModelUploadLocation.get();
|
||||
|
||||
if (lastLocation.isEmpty()) {
|
||||
lastLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
|
||||
|
@ -123,11 +132,9 @@ bool ModelUploader::zip() {
|
|||
lastLocation, "Model files (*.fst *.fbx)");
|
||||
if (filename == "") {
|
||||
// If the user canceled we return.
|
||||
Application::getInstance()->unlockSettings();
|
||||
return false;
|
||||
}
|
||||
settings->setValue(SETTING_NAME, filename);
|
||||
Application::getInstance()->unlockSettings();
|
||||
SettingHandles::lastModelUploadLocation.set(filename);
|
||||
|
||||
// First we check the FST file (if any)
|
||||
QFile* fst;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <NetworkAccessManager.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Menu.h"
|
||||
|
||||
#include "ScriptsModel.h"
|
||||
|
@ -33,8 +34,8 @@ static const QString KEY_NAME = "Key";
|
|||
|
||||
TreeNodeBase::TreeNodeBase(TreeNodeFolder* parent, const QString& name, TreeNodeType type) :
|
||||
_parent(parent),
|
||||
_name(name),
|
||||
_type(type) {
|
||||
_type(type),
|
||||
_name(name) {
|
||||
};
|
||||
|
||||
TreeNodeScript::TreeNodeScript(const QString& localPath, const QString& fullPath, ScriptOrigin origin) :
|
||||
|
@ -58,10 +59,10 @@ ScriptsModel::ScriptsModel(QObject* parent) :
|
|||
_localDirectory.setFilter(QDir::Files | QDir::Readable);
|
||||
_localDirectory.setNameFilters(QStringList("*.js"));
|
||||
|
||||
updateScriptsLocation(Menu::getInstance()->getScriptsLocation());
|
||||
updateScriptsLocation(qApp->getScriptsLocation());
|
||||
|
||||
connect(&_fsWatcher, &QFileSystemWatcher::directoryChanged, this, &ScriptsModel::reloadLocalFiles);
|
||||
connect(Menu::getInstance(), &Menu::scriptLocationChanged, this, &ScriptsModel::updateScriptsLocation);
|
||||
connect(qApp, &Application::scriptLocationChanged, this, &ScriptsModel::updateScriptsLocation);
|
||||
|
||||
reloadLocalFiles();
|
||||
reloadRemoteFiles();
|
||||
|
|
|
@ -20,12 +20,13 @@
|
|||
#include <QWinEventNotifier>
|
||||
#endif
|
||||
|
||||
class SpeechRecognizer : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SpeechRecognizer();
|
||||
~SpeechRecognizer();
|
||||
#include <DependencyManager.h>
|
||||
|
||||
class SpeechRecognizer : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
void handleCommandRecognized(const char* command);
|
||||
bool getEnabled() const { return _enabled; }
|
||||
|
||||
|
@ -42,6 +43,9 @@ protected:
|
|||
void reloadCommands();
|
||||
|
||||
private:
|
||||
SpeechRecognizer();
|
||||
virtual ~SpeechRecognizer();
|
||||
|
||||
bool _enabled;
|
||||
QSet<QString> _commands;
|
||||
#if defined(Q_OS_MAC)
|
||||
|
|
|
@ -238,14 +238,6 @@ void runTimingTests() {
|
|||
qDebug("vec3 assign and dot() usecs: %f, last result:%f", elapsedUsecs / (float) numTests, result);
|
||||
}
|
||||
|
||||
float loadSetting(QSettings* settings, const char* name, float defaultValue) {
|
||||
float value = settings->value(name, defaultValue).toFloat();
|
||||
if (glm::isnan(value)) {
|
||||
value = defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection,
|
||||
const glm::vec3& sphereCenter, float sphereRadius, float& distance) {
|
||||
glm::vec3 relativeOrigin = rayStarting - sphereCenter;
|
||||
|
|
|
@ -31,8 +31,6 @@ void renderBevelCornersRect(int x, int y, int width, int height, int bevelDistan
|
|||
|
||||
void runTimingTests();
|
||||
|
||||
float loadSetting(QSettings* settings, const char* name, float defaultValue);
|
||||
|
||||
bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection,
|
||||
const glm::vec3& sphereCenter, float sphereRadius, float& distance);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <DeferredLightingEffect.h>
|
||||
#include <GeometryUtil.h>
|
||||
#include <GlowEffect.h>
|
||||
#include <LODManager.h>
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <PathUtils.h>
|
||||
|
@ -114,8 +115,8 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
|
|||
}
|
||||
|
||||
float Avatar::getLODDistance() const {
|
||||
return Menu::getInstance()->getAvatarLODDistanceMultiplier() *
|
||||
glm::distance(Application::getInstance()->getCamera()->getPosition(), _position) / _scale;
|
||||
return DependencyManager::get<LODManager>()->getAvatarLODDistanceMultiplier() *
|
||||
glm::distance(qApp->getCamera()->getPosition(), _position) / _scale;
|
||||
}
|
||||
|
||||
void Avatar::simulate(float deltaTime) {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <PerfStat.h>
|
||||
#include <Settings.h>
|
||||
#include <ShapeCollider.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <TextRenderer.h>
|
||||
|
@ -338,7 +339,8 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
|||
head->setDeltaPitch(estimatedRotation.x);
|
||||
head->setDeltaYaw(estimatedRotation.y);
|
||||
} else {
|
||||
float magnifyFieldOfView = Menu::getInstance()->getFieldOfView() / Menu::getInstance()->getRealWorldFieldOfView();
|
||||
float magnifyFieldOfView = qApp->getViewFrustum()->getFieldOfView() /
|
||||
qApp->getViewFrustum()->getRealWorldFieldOfView();
|
||||
head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView);
|
||||
head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView);
|
||||
}
|
||||
|
@ -677,60 +679,70 @@ AnimationDetails MyAvatar::getAnimationDetails(const QString& url) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void MyAvatar::saveData(QSettings* settings) {
|
||||
settings->beginGroup("Avatar");
|
||||
void MyAvatar::saveData() {
|
||||
Settings settings;
|
||||
settings.beginGroup("Avatar");
|
||||
|
||||
settings->setValue("headPitch", getHead()->getBasePitch());
|
||||
settings.setValue("headPitch", getHead()->getBasePitch());
|
||||
|
||||
settings->setValue("pupilDilation", getHead()->getPupilDilation());
|
||||
settings.setValue("pupilDilation", getHead()->getPupilDilation());
|
||||
|
||||
settings->setValue("leanScale", _leanScale);
|
||||
settings->setValue("scale", _targetScale);
|
||||
settings.setValue("leanScale", _leanScale);
|
||||
settings.setValue("scale", _targetScale);
|
||||
|
||||
settings->setValue("faceModelURL", _faceModelURL);
|
||||
settings->setValue("skeletonModelURL", _skeletonModelURL);
|
||||
settings.setValue("faceModelURL", _faceModelURL);
|
||||
settings.setValue("skeletonModelURL", _skeletonModelURL);
|
||||
|
||||
settings->beginWriteArray("attachmentData");
|
||||
settings.beginWriteArray("attachmentData");
|
||||
for (int i = 0; i < _attachmentData.size(); i++) {
|
||||
settings->setArrayIndex(i);
|
||||
settings.setArrayIndex(i);
|
||||
const AttachmentData& attachment = _attachmentData.at(i);
|
||||
settings->setValue("modelURL", attachment.modelURL);
|
||||
settings->setValue("jointName", attachment.jointName);
|
||||
settings->setValue("translation_x", attachment.translation.x);
|
||||
settings->setValue("translation_y", attachment.translation.y);
|
||||
settings->setValue("translation_z", attachment.translation.z);
|
||||
settings.setValue("modelURL", attachment.modelURL);
|
||||
settings.setValue("jointName", attachment.jointName);
|
||||
settings.setValue("translation_x", attachment.translation.x);
|
||||
settings.setValue("translation_y", attachment.translation.y);
|
||||
settings.setValue("translation_z", attachment.translation.z);
|
||||
glm::vec3 eulers = safeEulerAngles(attachment.rotation);
|
||||
settings->setValue("rotation_x", eulers.x);
|
||||
settings->setValue("rotation_y", eulers.y);
|
||||
settings->setValue("rotation_z", eulers.z);
|
||||
settings->setValue("scale", attachment.scale);
|
||||
settings.setValue("rotation_x", eulers.x);
|
||||
settings.setValue("rotation_y", eulers.y);
|
||||
settings.setValue("rotation_z", eulers.z);
|
||||
settings.setValue("scale", attachment.scale);
|
||||
}
|
||||
settings->endArray();
|
||||
settings.endArray();
|
||||
|
||||
settings->beginWriteArray("animationHandles");
|
||||
settings.beginWriteArray("animationHandles");
|
||||
for (int i = 0; i < _animationHandles.size(); i++) {
|
||||
settings->setArrayIndex(i);
|
||||
settings.setArrayIndex(i);
|
||||
const AnimationHandlePointer& pointer = _animationHandles.at(i);
|
||||
settings->setValue("role", pointer->getRole());
|
||||
settings->setValue("url", pointer->getURL());
|
||||
settings->setValue("fps", pointer->getFPS());
|
||||
settings->setValue("priority", pointer->getPriority());
|
||||
settings->setValue("loop", pointer->getLoop());
|
||||
settings->setValue("hold", pointer->getHold());
|
||||
settings->setValue("startAutomatically", pointer->getStartAutomatically());
|
||||
settings->setValue("firstFrame", pointer->getFirstFrame());
|
||||
settings->setValue("lastFrame", pointer->getLastFrame());
|
||||
settings->setValue("maskedJoints", pointer->getMaskedJoints());
|
||||
settings.setValue("role", pointer->getRole());
|
||||
settings.setValue("url", pointer->getURL());
|
||||
settings.setValue("fps", pointer->getFPS());
|
||||
settings.setValue("priority", pointer->getPriority());
|
||||
settings.setValue("loop", pointer->getLoop());
|
||||
settings.setValue("hold", pointer->getHold());
|
||||
settings.setValue("startAutomatically", pointer->getStartAutomatically());
|
||||
settings.setValue("firstFrame", pointer->getFirstFrame());
|
||||
settings.setValue("lastFrame", pointer->getLastFrame());
|
||||
settings.setValue("maskedJoints", pointer->getMaskedJoints());
|
||||
}
|
||||
settings->endArray();
|
||||
settings.endArray();
|
||||
|
||||
settings->setValue("displayName", _displayName);
|
||||
settings.setValue("displayName", _displayName);
|
||||
|
||||
settings->endGroup();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void MyAvatar::loadData(QSettings* settings) {
|
||||
settings->beginGroup("Avatar");
|
||||
float loadSetting(QSettings& settings, const char* name, float defaultValue) {
|
||||
float value = settings.value(name, defaultValue).toFloat();
|
||||
if (glm::isnan(value)) {
|
||||
value = defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void MyAvatar::loadData() {
|
||||
Settings settings;
|
||||
settings.beginGroup("Avatar");
|
||||
|
||||
getHead()->setBasePitch(loadSetting(settings, "headPitch", 0.0f));
|
||||
|
||||
|
@ -741,16 +753,16 @@ void MyAvatar::loadData(QSettings* settings) {
|
|||
setScale(_scale);
|
||||
Application::getInstance()->getCamera()->setScale(_scale);
|
||||
|
||||
setFaceModelURL(settings->value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl());
|
||||
setSkeletonModelURL(settings->value("skeletonModelURL").toUrl());
|
||||
setFaceModelURL(settings.value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl());
|
||||
setSkeletonModelURL(settings.value("skeletonModelURL").toUrl());
|
||||
|
||||
QVector<AttachmentData> attachmentData;
|
||||
int attachmentCount = settings->beginReadArray("attachmentData");
|
||||
int attachmentCount = settings.beginReadArray("attachmentData");
|
||||
for (int i = 0; i < attachmentCount; i++) {
|
||||
settings->setArrayIndex(i);
|
||||
settings.setArrayIndex(i);
|
||||
AttachmentData attachment;
|
||||
attachment.modelURL = settings->value("modelURL").toUrl();
|
||||
attachment.jointName = settings->value("jointName").toString();
|
||||
attachment.modelURL = settings.value("modelURL").toUrl();
|
||||
attachment.jointName = settings.value("jointName").toString();
|
||||
attachment.translation.x = loadSetting(settings, "translation_x", 0.0f);
|
||||
attachment.translation.y = loadSetting(settings, "translation_y", 0.0f);
|
||||
attachment.translation.z = loadSetting(settings, "translation_z", 0.0f);
|
||||
|
@ -762,10 +774,10 @@ void MyAvatar::loadData(QSettings* settings) {
|
|||
attachment.scale = loadSetting(settings, "scale", 1.0f);
|
||||
attachmentData.append(attachment);
|
||||
}
|
||||
settings->endArray();
|
||||
settings.endArray();
|
||||
setAttachmentData(attachmentData);
|
||||
|
||||
int animationCount = settings->beginReadArray("animationHandles");
|
||||
int animationCount = settings.beginReadArray("animationHandles");
|
||||
while (_animationHandles.size() > animationCount) {
|
||||
_animationHandles.takeLast()->stop();
|
||||
}
|
||||
|
@ -773,65 +785,64 @@ void MyAvatar::loadData(QSettings* settings) {
|
|||
addAnimationHandle();
|
||||
}
|
||||
for (int i = 0; i < animationCount; i++) {
|
||||
settings->setArrayIndex(i);
|
||||
settings.setArrayIndex(i);
|
||||
const AnimationHandlePointer& handle = _animationHandles.at(i);
|
||||
handle->setRole(settings->value("role", "idle").toString());
|
||||
handle->setURL(settings->value("url").toUrl());
|
||||
handle->setRole(settings.value("role", "idle").toString());
|
||||
handle->setURL(settings.value("url").toUrl());
|
||||
handle->setFPS(loadSetting(settings, "fps", 30.0f));
|
||||
handle->setPriority(loadSetting(settings, "priority", 1.0f));
|
||||
handle->setLoop(settings->value("loop", true).toBool());
|
||||
handle->setHold(settings->value("hold", false).toBool());
|
||||
handle->setStartAutomatically(settings->value("startAutomatically", true).toBool());
|
||||
handle->setFirstFrame(settings->value("firstFrame", 0.0f).toFloat());
|
||||
handle->setLastFrame(settings->value("lastFrame", INT_MAX).toFloat());
|
||||
handle->setMaskedJoints(settings->value("maskedJoints").toStringList());
|
||||
handle->setLoop(settings.value("loop", true).toBool());
|
||||
handle->setHold(settings.value("hold", false).toBool());
|
||||
handle->setStartAutomatically(settings.value("startAutomatically", true).toBool());
|
||||
handle->setFirstFrame(settings.value("firstFrame", 0.0f).toFloat());
|
||||
handle->setLastFrame(settings.value("lastFrame", INT_MAX).toFloat());
|
||||
handle->setMaskedJoints(settings.value("maskedJoints").toStringList());
|
||||
}
|
||||
settings->endArray();
|
||||
settings.endArray();
|
||||
|
||||
setDisplayName(settings->value("displayName").toString());
|
||||
setDisplayName(settings.value("displayName").toString());
|
||||
|
||||
settings->endGroup();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void MyAvatar::saveAttachmentData(const AttachmentData& attachment) const {
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
settings->beginGroup("savedAttachmentData");
|
||||
settings->beginGroup(_skeletonModel.getURL().toString());
|
||||
settings->beginGroup(attachment.modelURL.toString());
|
||||
settings->setValue("jointName", attachment.jointName);
|
||||
Settings settings;
|
||||
settings.beginGroup("savedAttachmentData");
|
||||
settings.beginGroup(_skeletonModel.getURL().toString());
|
||||
settings.beginGroup(attachment.modelURL.toString());
|
||||
settings.setValue("jointName", attachment.jointName);
|
||||
|
||||
settings->beginGroup(attachment.jointName);
|
||||
settings->setValue("translation_x", attachment.translation.x);
|
||||
settings->setValue("translation_y", attachment.translation.y);
|
||||
settings->setValue("translation_z", attachment.translation.z);
|
||||
settings.beginGroup(attachment.jointName);
|
||||
settings.setValue("translation_x", attachment.translation.x);
|
||||
settings.setValue("translation_y", attachment.translation.y);
|
||||
settings.setValue("translation_z", attachment.translation.z);
|
||||
glm::vec3 eulers = safeEulerAngles(attachment.rotation);
|
||||
settings->setValue("rotation_x", eulers.x);
|
||||
settings->setValue("rotation_y", eulers.y);
|
||||
settings->setValue("rotation_z", eulers.z);
|
||||
settings->setValue("scale", attachment.scale);
|
||||
settings.setValue("rotation_x", eulers.x);
|
||||
settings.setValue("rotation_y", eulers.y);
|
||||
settings.setValue("rotation_z", eulers.z);
|
||||
settings.setValue("scale", attachment.scale);
|
||||
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
Application::getInstance()->unlockSettings();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString& jointName) const {
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
settings->beginGroup("savedAttachmentData");
|
||||
settings->beginGroup(_skeletonModel.getURL().toString());
|
||||
settings->beginGroup(modelURL.toString());
|
||||
Settings settings;
|
||||
settings.beginGroup("savedAttachmentData");
|
||||
settings.beginGroup(_skeletonModel.getURL().toString());
|
||||
settings.beginGroup(modelURL.toString());
|
||||
|
||||
AttachmentData attachment;
|
||||
attachment.modelURL = modelURL;
|
||||
if (jointName.isEmpty()) {
|
||||
attachment.jointName = settings->value("jointName").toString();
|
||||
attachment.jointName = settings.value("jointName").toString();
|
||||
} else {
|
||||
attachment.jointName = jointName;
|
||||
}
|
||||
settings->beginGroup(attachment.jointName);
|
||||
if (settings->contains("translation_x")) {
|
||||
settings.beginGroup(attachment.jointName);
|
||||
if (settings.contains("translation_x")) {
|
||||
attachment.translation.x = loadSetting(settings, "translation_x", 0.0f);
|
||||
attachment.translation.y = loadSetting(settings, "translation_y", 0.0f);
|
||||
attachment.translation.z = loadSetting(settings, "translation_z", 0.0f);
|
||||
|
@ -845,11 +856,10 @@ AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString&
|
|||
attachment = AttachmentData();
|
||||
}
|
||||
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
Application::getInstance()->unlockSettings();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
|
||||
return attachment;
|
||||
}
|
||||
|
|
|
@ -78,8 +78,8 @@ public:
|
|||
Q_INVOKABLE AnimationDetails getAnimationDetails(const QString& url);
|
||||
|
||||
// get/set avatar data
|
||||
void saveData(QSettings* settings);
|
||||
void loadData(QSettings* settings);
|
||||
void saveData();
|
||||
void loadData();
|
||||
|
||||
void saveAttachmentData(const AttachmentData& attachment) const;
|
||||
AttachmentData loadAttachmentData(const QUrl& modelURL, const QString& jointName = QString()) const;
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
|
||||
#include <QTimer>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <PerfStat.h>
|
||||
#include <Settings.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "Faceshift.h"
|
||||
|
@ -27,6 +29,11 @@ using namespace std;
|
|||
const quint16 FACESHIFT_PORT = 33433;
|
||||
float STARTING_FACESHIFT_FRAME_TIME = 0.033f;
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<float> faceshiftEyeDeflection("faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION);
|
||||
const SettingHandle<QString> faceshiftHostname("faceshiftHostname", DEFAULT_FACESHIFT_HOSTNAME);
|
||||
}
|
||||
|
||||
Faceshift::Faceshift() :
|
||||
_tcpEnabled(true),
|
||||
_tcpRetryCount(0),
|
||||
|
@ -66,6 +73,9 @@ Faceshift::Faceshift() :
|
|||
|
||||
_udpSocket.bind(FACESHIFT_PORT);
|
||||
#endif
|
||||
|
||||
_eyeDeflection = SettingHandles::faceshiftEyeDeflection.get();
|
||||
_hostname = SettingHandles::faceshiftHostname.get();
|
||||
}
|
||||
|
||||
void Faceshift::init() {
|
||||
|
@ -159,7 +169,7 @@ void Faceshift::connectSocket() {
|
|||
qDebug("Faceshift: Connecting...");
|
||||
}
|
||||
|
||||
_tcpSocket.connectToHost(Menu::getInstance()->getFaceshiftHostname(), FACESHIFT_PORT);
|
||||
_tcpSocket.connectToHost(_hostname, FACESHIFT_PORT);
|
||||
_tracking = false;
|
||||
}
|
||||
}
|
||||
|
@ -309,3 +319,13 @@ void Faceshift::receive(const QByteArray& buffer) {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Faceshift::setEyeDeflection(float faceshiftEyeDeflection) {
|
||||
_eyeDeflection = faceshiftEyeDeflection;
|
||||
SettingHandles::faceshiftEyeDeflection.set(_eyeDeflection);
|
||||
}
|
||||
|
||||
void Faceshift::setHostname(const QString& hostname) {
|
||||
_hostname = hostname;
|
||||
SettingHandles::faceshiftHostname.set(_hostname);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,12 @@ public:
|
|||
float getMouthSize() const { return getBlendshapeCoefficient(_jawOpenIndex); }
|
||||
float getMouthSmileLeft() const { return getBlendshapeCoefficient(_mouthSmileLeftIndex); }
|
||||
float getMouthSmileRight() const { return getBlendshapeCoefficient(_mouthSmileRightIndex); }
|
||||
|
||||
float getEyeDeflection() const { return _eyeDeflection; }
|
||||
void setEyeDeflection(float faceshiftEyeDeflection);
|
||||
|
||||
const QString& getHostname() const { return _hostname; }
|
||||
void setHostname(const QString& hostname);
|
||||
|
||||
void update();
|
||||
void reset();
|
||||
|
@ -145,6 +151,9 @@ private:
|
|||
float _longTermAverageEyeYaw;
|
||||
bool _longTermAverageInitialized;
|
||||
|
||||
float _eyeDeflection = DEFAULT_FACESHIFT_EYE_DEFLECTION;
|
||||
QString _hostname = DEFAULT_FACESHIFT_HOSTNAME;
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_Faceshift_h
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include "RealSense.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Menu.h"
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
|
||||
virtual void update();
|
||||
|
||||
public slots:
|
||||
void loadRSSDKFile();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -301,7 +301,16 @@ const float RANGE_MULT = (MAX_PIXEL_RANGE_MULT - MIN_PIXEL_RANGE_MULT) * 0.01;
|
|||
//Returns a multiplier to be applied to the cursor range for the controllers
|
||||
float SixenseManager::getCursorPixelRangeMult() const {
|
||||
//scales (0,100) to (MINIMUM_PIXEL_RANGE_MULT, MAXIMUM_PIXEL_RANGE_MULT)
|
||||
return Menu::getInstance()->getSixenseReticleMoveSpeed() * RANGE_MULT + MIN_PIXEL_RANGE_MULT;
|
||||
return _reticleMoveSpeed * RANGE_MULT + MIN_PIXEL_RANGE_MULT;
|
||||
}
|
||||
|
||||
void SixenseManager::toggleSixense(bool shouldEnable) {
|
||||
if (shouldEnable && !isInitialized()) {
|
||||
initialize();
|
||||
setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
|
||||
setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter));
|
||||
}
|
||||
setIsEnabled(shouldEnable);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIXENSE
|
||||
|
@ -459,7 +468,7 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
|||
|
||||
unsigned int deviceID = index == 0 ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
|
||||
|
||||
if (Menu::getInstance()->getInvertSixenseButtons()) {
|
||||
if (_invertButtons) {
|
||||
bumperButton = Qt::LeftButton;
|
||||
triggerButton = Qt::RightButton;
|
||||
} else {
|
||||
|
|
|
@ -55,8 +55,13 @@ public:
|
|||
void update(float deltaTime);
|
||||
float getCursorPixelRangeMult() const;
|
||||
|
||||
public slots:
|
||||
float getReticleMoveSpeed() const { return _reticleMoveSpeed; }
|
||||
void setReticleMoveSpeed(float sixenseReticleMoveSpeed) { _reticleMoveSpeed = sixenseReticleMoveSpeed; }
|
||||
bool getInvertButtons() const { return _invertButtons; }
|
||||
void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; }
|
||||
|
||||
public slots:
|
||||
void toggleSixense(bool shouldEnable);
|
||||
void setFilter(bool filter);
|
||||
void setLowVelocityFilter(bool lowVelocityFilter) { _lowVelocityFilter = lowVelocityFilter; };
|
||||
|
||||
|
@ -102,6 +107,9 @@ private:
|
|||
|
||||
bool _lowVelocityFilter;
|
||||
bool _controllersAtBase;
|
||||
|
||||
float _reticleMoveSpeed = DEFAULT_SIXENSE_RETICLE_MOVE_SPEED;
|
||||
bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;
|
||||
};
|
||||
|
||||
#endif // hifi_SixenseManager_h
|
||||
|
|
|
@ -8,13 +8,15 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <QTranslator>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
QElapsedTimer startupTime;
|
||||
startupTime.start();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include "Audio.h"
|
||||
#include "AudioDeviceScriptingInterface.h"
|
||||
|
||||
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
#ifndef hifi_AudioDeviceScriptingInterface_h
|
||||
#define hifi_AudioDeviceScriptingInterface_h
|
||||
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include "Application.h"
|
||||
class AudioEffectOptions;
|
||||
|
||||
class AudioDeviceScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include <Settings.h>
|
||||
|
||||
#include "SettingsScriptingInterface.h"
|
||||
|
||||
|
||||
|
@ -19,9 +20,7 @@ SettingsScriptingInterface* SettingsScriptingInterface::getInstance() {
|
|||
}
|
||||
|
||||
QVariant SettingsScriptingInterface::getValue(const QString& setting) {
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
QVariant value = settings->value(setting);
|
||||
Application::getInstance()->unlockSettings();
|
||||
QVariant value = SettingHandles::SettingHandle<QVariant>(setting).get();
|
||||
if (!value.isValid()) {
|
||||
value = "";
|
||||
}
|
||||
|
@ -29,9 +28,7 @@ QVariant SettingsScriptingInterface::getValue(const QString& setting) {
|
|||
}
|
||||
|
||||
QVariant SettingsScriptingInterface::getValue(const QString& setting, const QVariant& defaultValue) {
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
QVariant value = settings->value(setting, defaultValue);
|
||||
Application::getInstance()->unlockSettings();
|
||||
QVariant value = SettingHandles::SettingHandle<QVariant>(setting, defaultValue).get();
|
||||
if (!value.isValid()) {
|
||||
value = "";
|
||||
}
|
||||
|
@ -39,7 +36,5 @@ QVariant SettingsScriptingInterface::getValue(const QString& setting, const QVar
|
|||
}
|
||||
|
||||
void SettingsScriptingInterface::setValue(const QString& setting, const QVariant& value) {
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
settings->setValue(setting, value);
|
||||
Application::getInstance()->unlockSettings();
|
||||
SettingHandles::SettingHandle<QVariant>(setting).set(value);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QScriptValue>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include "Application.h"
|
||||
#include "MainWindow.h"
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
const QString ADDRESSBAR_GO_BUTTON_ICON = "images/address-bar-submit.svg";
|
||||
const QString ADDRESSBAR_GO_BUTTON_ACTIVE_ICON = "images/address-bar-submit-active.svg";
|
||||
|
||||
AddressBarDialog::AddressBarDialog() :
|
||||
FramelessDialog(Application::getInstance()->getWindow(), 0, FramelessDialog::POSITION_TOP)
|
||||
AddressBarDialog::AddressBarDialog(QWidget* parent) :
|
||||
FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
setupUI();
|
||||
|
|
|
@ -23,7 +23,7 @@ class AddressBarDialog : public FramelessDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AddressBarDialog();
|
||||
AddressBarDialog(QWidget* parent);
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
|
|
|
@ -20,12 +20,18 @@
|
|||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <Settings.h>
|
||||
|
||||
#include "AnimationsDialog.h"
|
||||
#include "Application.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
AnimationsDialog::AnimationsDialog() :
|
||||
QDialog(Application::getInstance()->getWindow()) {
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QString> animationDirectory("animation_directory", QString());
|
||||
}
|
||||
|
||||
AnimationsDialog::AnimationsDialog(QWidget* parent) :
|
||||
QDialog(parent) {
|
||||
|
||||
setWindowTitle("Edit Animations");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
@ -157,14 +163,12 @@ AnimationPanel::AnimationPanel(AnimationsDialog* dialog, const AnimationHandlePo
|
|||
}
|
||||
|
||||
void AnimationPanel::chooseURL() {
|
||||
QString directory = Application::getInstance()->lockSettings()->value("animation_directory").toString();
|
||||
Application::getInstance()->unlockSettings();
|
||||
QString directory = SettingHandles::animationDirectory.get();
|
||||
QString filename = QFileDialog::getOpenFileName(this, "Choose Animation", directory, "Animation files (*.fbx)");
|
||||
if (filename.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Application::getInstance()->lockSettings()->setValue("animation_directory", QFileInfo(filename).path());
|
||||
Application::getInstance()->unlockSettings();
|
||||
SettingHandles::animationDirectory.set(QFileInfo(filename).path());
|
||||
_url->setText(QUrl::fromLocalFile(filename).toString());
|
||||
emit _url->returnPressed();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define hifi_AnimationsDialog_h
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QFrame>
|
||||
|
||||
#include "avatar/MyAvatar.h"
|
||||
|
@ -30,7 +31,7 @@ class AnimationsDialog : public QDialog {
|
|||
|
||||
public:
|
||||
|
||||
AnimationsDialog();
|
||||
AnimationsDialog(QWidget* parent = nullptr);
|
||||
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <PathUtils.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "Audio.h"
|
||||
#include "audio/AudioIOStatsRenderer.h"
|
||||
#include "audio/AudioScope.h"
|
||||
#include "audio/AudioToolBox.h"
|
||||
|
@ -164,7 +165,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
Overlays& overlays = application->getOverlays();
|
||||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
|
||||
_textureFov = glm::radians(Menu::getInstance()->getOculusUIAngularSize());
|
||||
_textureFov = glm::radians(_oculusUIAngularSize);
|
||||
_textureAspectRatio = (float)glCanvas->getDeviceWidth() / (float)glCanvas->getDeviceHeight();
|
||||
|
||||
//Handle fading and deactivation/activation of UI
|
||||
|
|
|
@ -20,6 +20,8 @@ const float MAGNIFY_WIDTH = 220.0f;
|
|||
const float MAGNIFY_HEIGHT = 100.0f;
|
||||
const float MAGNIFY_MULT = 2.0f;
|
||||
|
||||
const float DEFAULT_OCULUS_UI_ANGULAR_SIZE = 72.0f;
|
||||
|
||||
// Handles the drawing of the overlays to the screen
|
||||
class ApplicationOverlay {
|
||||
public:
|
||||
|
@ -35,6 +37,9 @@ public:
|
|||
QPoint getPalmClickLocation(const PalmData *palm) const;
|
||||
bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const;
|
||||
|
||||
float getOculusUIAngularSize() const { return _oculusUIAngularSize; }
|
||||
void setOculusUIAngularSize(float oculusUIAngularSize) { _oculusUIAngularSize = oculusUIAngularSize; }
|
||||
|
||||
// Converter from one frame of reference to another.
|
||||
// Frame of reference:
|
||||
// Screen: Position on the screen (x,y)
|
||||
|
@ -80,6 +85,8 @@ private:
|
|||
VerticesIndices _vbo;
|
||||
};
|
||||
|
||||
float _oculusUIAngularSize = DEFAULT_OCULUS_UI_ANGULAR_SIZE;
|
||||
|
||||
void renderReticle(glm::quat orientation, float alpha);
|
||||
void renderPointers();;
|
||||
void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder);
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
#include "AttachmentsDialog.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
AttachmentsDialog::AttachmentsDialog() :
|
||||
QDialog(Application::getInstance()->getWindow()) {
|
||||
AttachmentsDialog::AttachmentsDialog(QWidget* parent) :
|
||||
QDialog(parent) {
|
||||
|
||||
setWindowTitle("Edit Attachments");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
|
|
@ -27,8 +27,7 @@ class AttachmentsDialog : public QDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
AttachmentsDialog();
|
||||
AttachmentsDialog(QWidget* parent = nullptr);
|
||||
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <AddressManager.h>
|
||||
#include <AccountManager.h>
|
||||
#include <PathUtils.h>
|
||||
#include <Settings.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ChatMessageArea.h"
|
||||
|
@ -41,6 +42,10 @@ const QRegularExpression regexHifiLinks("([#@]\\S+)");
|
|||
const QString mentionSoundsPath("/mention-sounds/");
|
||||
const QString mentionRegex("@(\\b%1\\b)");
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QDateTime> usernameMentionTimestamp("MentionTimestamp", QDateTime());
|
||||
}
|
||||
|
||||
ChatWindow::ChatWindow(QWidget* parent) :
|
||||
QWidget(parent, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint |
|
||||
Qt::WindowCloseButtonHint),
|
||||
|
@ -377,12 +382,10 @@ void ChatWindow::messageReceived(const QXmppMessage& message) {
|
|||
if (message.body().contains(usernameMention)) {
|
||||
|
||||
// Don't show messages already seen in icon tray at start-up.
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
bool showMessage = settings->value("usernameMentionTimestamp").toDateTime() < _lastMessageStamp;
|
||||
bool showMessage = SettingHandles::usernameMentionTimestamp.get() < _lastMessageStamp;
|
||||
if (showMessage) {
|
||||
settings->setValue("usernameMentionTimestamp", _lastMessageStamp);
|
||||
SettingHandles::usernameMentionTimestamp.set(_lastMessageStamp);
|
||||
}
|
||||
Application::getInstance()->unlockSettings();
|
||||
|
||||
if (isHidden() && showMessage) {
|
||||
|
||||
|
|
215
interface/src/ui/DialogsManager.cpp
Normal file
215
interface/src/ui/DialogsManager.cpp
Normal file
|
@ -0,0 +1,215 @@
|
|||
//
|
||||
// DialogsManager.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 1/18/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <MainWindow.h>
|
||||
#include <PathUtils.h>
|
||||
#include <XmppClient.h>
|
||||
|
||||
#include "AddressBarDialog.h"
|
||||
#include "AnimationsDialog.h"
|
||||
#include "AttachmentsDialog.h"
|
||||
#include "BandwidthDialog.h"
|
||||
#include "CachesSizeDialog.h"
|
||||
#include "ChatWindow.h"
|
||||
#include "HMDToolsDialog.h"
|
||||
#include "LodToolsDialog.h"
|
||||
#include "LoginDialog.h"
|
||||
#include "MetavoxelEditor.h"
|
||||
#include "MetavoxelNetworkSimulator.h"
|
||||
#include "OctreeStatsDialog.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "ScriptEditorWindow.h"
|
||||
|
||||
#include "DialogsManager.h"
|
||||
|
||||
void DialogsManager::toggleAddressBar() {
|
||||
maybeCreateDialog(_addressBarDialog);
|
||||
|
||||
if (!_addressBarDialog->isVisible()) {
|
||||
_addressBarDialog->show();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsManager::toggleLoginDialog() {
|
||||
maybeCreateDialog(_loginDialog);
|
||||
_loginDialog->toggleQAction();
|
||||
}
|
||||
|
||||
void DialogsManager::showLoginDialog() {
|
||||
maybeCreateDialog(_loginDialog);
|
||||
_loginDialog->showLoginForCurrentDomain();
|
||||
}
|
||||
|
||||
void DialogsManager::octreeStatsDetails() {
|
||||
if (!_octreeStatsDialog) {
|
||||
_octreeStatsDialog = new OctreeStatsDialog(qApp->getWindow(), qApp->getOcteeSceneStats());
|
||||
|
||||
if (_hmdToolsDialog) {
|
||||
_hmdToolsDialog->watchWindow(_octreeStatsDialog->windowHandle());
|
||||
}
|
||||
connect(_octreeStatsDialog, SIGNAL(closed()), _octreeStatsDialog, SLOT(deleteLater()));
|
||||
_octreeStatsDialog->show();
|
||||
}
|
||||
_octreeStatsDialog->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::cachesSizeDialog() {
|
||||
qDebug() << "Caches size:" << _cachesSizeDialog.isNull();
|
||||
if (!_cachesSizeDialog) {
|
||||
maybeCreateDialog(_cachesSizeDialog);
|
||||
|
||||
connect(_cachesSizeDialog, SIGNAL(closed()), _cachesSizeDialog, SLOT(deleteLater()));
|
||||
_cachesSizeDialog->show();
|
||||
}
|
||||
_cachesSizeDialog->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::editPreferences() {
|
||||
if (!_preferencesDialog) {
|
||||
maybeCreateDialog(_preferencesDialog);
|
||||
_preferencesDialog->show();
|
||||
} else {
|
||||
_preferencesDialog->close();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsManager::editAttachments() {
|
||||
if (!_attachmentsDialog) {
|
||||
maybeCreateDialog(_attachmentsDialog);
|
||||
_attachmentsDialog->show();
|
||||
} else {
|
||||
_attachmentsDialog->close();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsManager::editAnimations() {
|
||||
if (!_animationsDialog) {
|
||||
maybeCreateDialog(_animationsDialog);
|
||||
_animationsDialog->show();
|
||||
} else {
|
||||
_animationsDialog->close();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsManager::bandwidthDetails() {
|
||||
if (! _bandwidthDialog) {
|
||||
_bandwidthDialog = new BandwidthDialog(qApp->getWindow(), qApp->getBandwidthMeter());
|
||||
connect(_bandwidthDialog, SIGNAL(closed()), _bandwidthDialog, SLOT(deleteLater()));
|
||||
|
||||
if (_hmdToolsDialog) {
|
||||
_hmdToolsDialog->watchWindow(_bandwidthDialog->windowHandle());
|
||||
}
|
||||
|
||||
_bandwidthDialog->show();
|
||||
}
|
||||
_bandwidthDialog->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::lodTools() {
|
||||
if (!_lodToolsDialog) {
|
||||
maybeCreateDialog(_lodToolsDialog);
|
||||
|
||||
connect(_lodToolsDialog, SIGNAL(closed()), _lodToolsDialog, SLOT(deleteLater()));
|
||||
_lodToolsDialog->show();
|
||||
}
|
||||
_lodToolsDialog->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::toggleToolWindow() {
|
||||
QMainWindow* toolWindow = qApp->getToolWindow();
|
||||
toolWindow->setVisible(!toolWindow->isVisible());
|
||||
}
|
||||
|
||||
void DialogsManager::hmdTools(bool showTools) {
|
||||
if (showTools) {
|
||||
if (!_hmdToolsDialog) {
|
||||
maybeCreateDialog(_hmdToolsDialog);
|
||||
connect(_hmdToolsDialog, SIGNAL(closed()), SLOT(hmdToolsClosed()));
|
||||
}
|
||||
_hmdToolsDialog->show();
|
||||
_hmdToolsDialog->raise();
|
||||
} else {
|
||||
hmdToolsClosed();
|
||||
}
|
||||
qApp->getWindow()->activateWindow();
|
||||
}
|
||||
|
||||
void DialogsManager::hmdToolsClosed() {
|
||||
Menu::getInstance()->getActionForOption(MenuOption::HMDTools)->setChecked(false);
|
||||
_hmdToolsDialog->hide();
|
||||
}
|
||||
|
||||
void DialogsManager::showMetavoxelEditor() {
|
||||
maybeCreateDialog(_metavoxelEditor);
|
||||
_metavoxelEditor->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::showMetavoxelNetworkSimulator() {
|
||||
maybeCreateDialog(_metavoxelNetworkSimulator);
|
||||
_metavoxelNetworkSimulator->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::showScriptEditor() {
|
||||
maybeCreateDialog(_scriptEditor);
|
||||
_scriptEditor->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::setupChat() {
|
||||
#ifdef HAVE_QXMPP
|
||||
const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient();
|
||||
connect(&xmppClient, &QXmppClient::connected, this, &DialogsManager::toggleChat);
|
||||
connect(&xmppClient, &QXmppClient::disconnected, this, &DialogsManager::toggleChat);
|
||||
|
||||
QDir::setCurrent(PathUtils::resourcesPath());
|
||||
// init chat window to listen chat
|
||||
maybeCreateDialog(_chatWindow);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DialogsManager::showChat() {
|
||||
if (AccountManager::getInstance().isLoggedIn()) {
|
||||
maybeCreateDialog(_chatWindow);
|
||||
|
||||
if (_chatWindow->isHidden()) {
|
||||
_chatWindow->show();
|
||||
}
|
||||
_chatWindow->raise();
|
||||
_chatWindow->activateWindow();
|
||||
_chatWindow->setFocus();
|
||||
} else {
|
||||
qApp->getTrayIcon()->showMessage("Interface",
|
||||
"You need to login to be able to chat with others on this domain.");
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsManager::toggleChat() {
|
||||
#ifdef HAVE_QXMPP
|
||||
QAction* chatAction = Menu::getInstance()->getActionForOption(MenuOption::Login);
|
||||
Q_CHECK_PTR(chatAction);
|
||||
|
||||
chatAction->setEnabled(XmppClient::getInstance().getXMPPClient().isConnected());
|
||||
if (!chatAction->isEnabled() && _chatWindow && AccountManager::getInstance().isLoggedIn()) {
|
||||
if (_chatWindow->isHidden()) {
|
||||
_chatWindow->show();
|
||||
_chatWindow->raise();
|
||||
_chatWindow->activateWindow();
|
||||
_chatWindow->setFocus();
|
||||
} else {
|
||||
_chatWindow->hide();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
105
interface/src/ui/DialogsManager.h
Normal file
105
interface/src/ui/DialogsManager.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
//
|
||||
// DialogsManager.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 1/18/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_DialogsManager_h
|
||||
#define hifi_DialogsManager_h
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
#include <Application.h>
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include "HMDToolsDialog.h"
|
||||
|
||||
class QAction;
|
||||
|
||||
class AddressBarDialog;
|
||||
class AnimationsDialog;
|
||||
class AttachmentsDialog;
|
||||
class CachesSizeDialog;
|
||||
class ChatWindow;
|
||||
class BandwidthDialog;
|
||||
class LodToolsDialog;
|
||||
class LoginDialog;
|
||||
class MetavoxelEditor;
|
||||
class MetavoxelNetworkSimulator;
|
||||
class OctreeStatsDialog;
|
||||
class PreferencesDialog;
|
||||
class ScriptEditorWindow;
|
||||
|
||||
class DialogsManager : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
QPointer<BandwidthDialog> getBandwidthDialog() const { return _bandwidthDialog; }
|
||||
QPointer<HMDToolsDialog> getHMDToolsDialog() const { return _hmdToolsDialog; }
|
||||
QPointer<LodToolsDialog> getLodToolsDialog() const { return _lodToolsDialog; }
|
||||
QPointer<OctreeStatsDialog> getOctreeStatsDialog() const { return _octreeStatsDialog; }
|
||||
|
||||
void setupChat();
|
||||
|
||||
public slots:
|
||||
void toggleAddressBar();
|
||||
void toggleLoginDialog();
|
||||
void showLoginDialog();
|
||||
void octreeStatsDetails();
|
||||
void cachesSizeDialog();
|
||||
void editPreferences();
|
||||
void editAttachments();
|
||||
void editAnimations();
|
||||
void bandwidthDetails();
|
||||
void lodTools();
|
||||
void hmdTools(bool showTools);
|
||||
void showMetavoxelEditor();
|
||||
void showMetavoxelNetworkSimulator();
|
||||
void showScriptEditor();
|
||||
void showChat();
|
||||
|
||||
private slots:
|
||||
void toggleToolWindow();
|
||||
void hmdToolsClosed();
|
||||
void toggleChat();
|
||||
|
||||
private:
|
||||
DialogsManager() {}
|
||||
|
||||
template<typename T>
|
||||
void maybeCreateDialog(QPointer<T>& member) {
|
||||
if (!member) {
|
||||
MainWindow* parent = qApp->getWindow();
|
||||
Q_CHECK_PTR(parent);
|
||||
member = new T(parent);
|
||||
Q_CHECK_PTR(member);
|
||||
|
||||
if (_hmdToolsDialog) {
|
||||
_hmdToolsDialog->watchWindow(member->windowHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPointer<AddressBarDialog> _addressBarDialog;
|
||||
QPointer<AnimationsDialog> _animationsDialog;
|
||||
QPointer<AttachmentsDialog> _attachmentsDialog;
|
||||
QPointer<BandwidthDialog> _bandwidthDialog;
|
||||
QPointer<CachesSizeDialog> _cachesSizeDialog;
|
||||
QPointer<ChatWindow> _chatWindow;
|
||||
QPointer<HMDToolsDialog> _hmdToolsDialog;
|
||||
QPointer<LodToolsDialog> _lodToolsDialog;
|
||||
QPointer<LoginDialog> _loginDialog;
|
||||
QPointer<MetavoxelEditor> _metavoxelEditor;
|
||||
QPointer<MetavoxelNetworkSimulator> _metavoxelNetworkSimulator;
|
||||
QPointer<OctreeStatsDialog> _octreeStatsDialog;
|
||||
QPointer<PreferencesDialog> _preferencesDialog;
|
||||
QPointer<ScriptEditorWindow> _scriptEditor;
|
||||
};
|
||||
|
||||
#endif // hifi_DialogsManager_h
|
|
@ -19,11 +19,13 @@
|
|||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "Menu.h"
|
||||
#include "devices/OculusManager.h"
|
||||
#include "ui/DialogsManager.h"
|
||||
#include "ui/HMDToolsDialog.h"
|
||||
|
||||
#include "devices/OculusManager.h"
|
||||
|
||||
HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
|
||||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) ,
|
||||
|
@ -67,20 +69,21 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
|
|||
// watch for our dialog window moving screens. If it does we want to enforce our rules about
|
||||
// what screens we're allowed on
|
||||
watchWindow(windowHandle());
|
||||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||
if (Application::getInstance()->getRunningScriptsWidget()) {
|
||||
watchWindow(Application::getInstance()->getRunningScriptsWidget()->windowHandle());
|
||||
}
|
||||
if (Application::getInstance()->getToolWindow()) {
|
||||
watchWindow(Application::getInstance()->getToolWindow()->windowHandle());
|
||||
}
|
||||
if (Menu::getInstance()->getBandwidthDialog()) {
|
||||
watchWindow(Menu::getInstance()->getBandwidthDialog()->windowHandle());
|
||||
if (dialogsManager->getBandwidthDialog()) {
|
||||
watchWindow(dialogsManager->getBandwidthDialog()->windowHandle());
|
||||
}
|
||||
if (Menu::getInstance()->getOctreeStatsDialog()) {
|
||||
watchWindow(Menu::getInstance()->getOctreeStatsDialog()->windowHandle());
|
||||
if (dialogsManager->getOctreeStatsDialog()) {
|
||||
watchWindow(dialogsManager->getOctreeStatsDialog()->windowHandle());
|
||||
}
|
||||
if (Menu::getInstance()->getLodToolsDialog()) {
|
||||
watchWindow(Menu::getInstance()->getLodToolsDialog()->windowHandle());
|
||||
if (dialogsManager->getLodToolsDialog()) {
|
||||
watchWindow(dialogsManager->getLodToolsDialog()->windowHandle());
|
||||
}
|
||||
|
||||
// when the application is about to quit, leave HDM mode
|
||||
|
|
|
@ -10,18 +10,21 @@
|
|||
//
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include <QDesktopWidget>
|
||||
#include <QFileInfo>
|
||||
#include <QtWebKitWidgets/QWebFrame>
|
||||
#include <QtWebKit/QWebElement>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <Settings.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "InfoView.h"
|
||||
|
||||
#define SETTINGS_VERSION_KEY "info-version"
|
||||
#define MAX_DIALOG_HEIGHT_RATIO 0.9
|
||||
static const float MAX_DIALOG_HEIGHT_RATIO = 0.9f;
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QString> infoVersion("info-version", QString());
|
||||
}
|
||||
|
||||
InfoView::InfoView(bool forced, QString path) :
|
||||
_forced(forced)
|
||||
|
@ -49,20 +52,17 @@ bool InfoView::shouldShow() {
|
|||
return true;
|
||||
}
|
||||
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
|
||||
QString lastVersion = settings->value(SETTINGS_VERSION_KEY).toString();
|
||||
QString lastVersion = SettingHandles::infoVersion.get();
|
||||
|
||||
QWebElement versionTag = page()->mainFrame()->findFirstElement("#version");
|
||||
QString version = versionTag.attribute("value");
|
||||
|
||||
if (version != QString::null && (lastVersion == QString::null || lastVersion != version)) {
|
||||
settings->setValue(SETTINGS_VERSION_KEY, version);
|
||||
SettingHandles::infoVersion.set(version);
|
||||
shouldShow = true;
|
||||
} else {
|
||||
shouldShow = false;
|
||||
}
|
||||
Application::getInstance()->unlockSettings();
|
||||
return shouldShow;
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ void InfoView::loaded(bool ok) {
|
|||
return;
|
||||
}
|
||||
|
||||
QDesktopWidget* desktop = Application::getInstance()->desktop();
|
||||
QDesktopWidget* desktop = qApp->desktop();
|
||||
QWebFrame* mainFrame = page()->mainFrame();
|
||||
|
||||
int height = mainFrame->contentsSize().height() > desktop->height() ?
|
||||
|
|
|
@ -9,17 +9,19 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QFormLayout>
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
#include <QPalette>
|
||||
#include <QCheckBox>
|
||||
#include <QColor>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QSlider>
|
||||
#include <QFormLayout>
|
||||
#include <QLabel>
|
||||
#include <QPalette>
|
||||
#include <QPushButton>
|
||||
#include <QSlider>
|
||||
#include <QString>
|
||||
|
||||
#include <LODManager.h>
|
||||
|
||||
#include "Menu.h"
|
||||
#include "ui/LodToolsDialog.h"
|
||||
|
||||
|
@ -28,6 +30,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint)
|
||||
{
|
||||
this->setWindowTitle("LOD Tools");
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
|
||||
// Create layouter
|
||||
QFormLayout* form = new QFormLayout(this);
|
||||
|
@ -45,7 +48,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
_lodSize->setTickPosition(QSlider::TicksBelow);
|
||||
_lodSize->setFixedWidth(SLIDER_WIDTH);
|
||||
_lodSize->setPageStep(PAGE_STEP_LOD_SIZE);
|
||||
int sliderValue = Menu::getInstance()->getOctreeSizeScale() / TREE_SCALE;
|
||||
int sliderValue = lodManager->getOctreeSizeScale() / TREE_SCALE;
|
||||
_lodSize->setValue(sliderValue);
|
||||
form->addRow("LOD Size Scale:", _lodSize);
|
||||
connect(_lodSize,SIGNAL(valueChanged(int)),this,SLOT(sizeScaleValueChanged(int)));
|
||||
|
@ -60,7 +63,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
_boundaryLevelAdjust->setTickInterval(STEP_ADJUST);
|
||||
_boundaryLevelAdjust->setTickPosition(QSlider::TicksBelow);
|
||||
_boundaryLevelAdjust->setFixedWidth(SLIDER_WIDTH);
|
||||
sliderValue = Menu::getInstance()->getBoundaryLevelAdjust();
|
||||
sliderValue = lodManager->getBoundaryLevelAdjust();
|
||||
_boundaryLevelAdjust->setValue(sliderValue);
|
||||
form->addRow("Boundary Level Adjust:", _boundaryLevelAdjust);
|
||||
connect(_boundaryLevelAdjust,SIGNAL(valueChanged(int)),this,SLOT(boundaryLevelValueChanged(int)));
|
||||
|
@ -71,22 +74,22 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
const unsigned redish = 0xfff00000;
|
||||
palette.setColor(QPalette::WindowText, QColor::fromRgb(redish));
|
||||
_feedback->setPalette(palette);
|
||||
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
|
||||
_feedback->setText(lodManager->getLODFeedbackText());
|
||||
const int FEEDBACK_WIDTH = 350;
|
||||
_feedback->setFixedWidth(FEEDBACK_WIDTH);
|
||||
form->addRow("You can see... ", _feedback);
|
||||
|
||||
|
||||
form->addRow("Automatic Avatar LOD Adjustment:", _automaticAvatarLOD = new QCheckBox(this));
|
||||
_automaticAvatarLOD->setChecked(Menu::getInstance()->getAutomaticAvatarLOD());
|
||||
_automaticAvatarLOD->setChecked(lodManager->getAutomaticAvatarLOD());
|
||||
connect(_automaticAvatarLOD, SIGNAL(toggled(bool)), SLOT(updateAvatarLODControls()));
|
||||
|
||||
form->addRow("Decrease Avatar LOD Below FPS:", _avatarLODDecreaseFPS = new QDoubleSpinBox(this));
|
||||
_avatarLODDecreaseFPS->setValue(Menu::getInstance()->getAvatarLODDecreaseFPS());
|
||||
_avatarLODDecreaseFPS->setValue(lodManager->getAvatarLODDecreaseFPS());
|
||||
_avatarLODDecreaseFPS->setDecimals(0);
|
||||
connect(_avatarLODDecreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
|
||||
|
||||
form->addRow("Increase Avatar LOD Above FPS:", _avatarLODIncreaseFPS = new QDoubleSpinBox(this));
|
||||
_avatarLODIncreaseFPS->setValue(Menu::getInstance()->getAvatarLODIncreaseFPS());
|
||||
_avatarLODIncreaseFPS->setValue(lodManager->getAvatarLODIncreaseFPS());
|
||||
_avatarLODIncreaseFPS->setDecimals(0);
|
||||
connect(_avatarLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
|
||||
|
||||
|
@ -94,7 +97,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
_avatarLOD->setDecimals(3);
|
||||
_avatarLOD->setRange(1.0 / MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, 1.0 / MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER);
|
||||
_avatarLOD->setSingleStep(0.001);
|
||||
_avatarLOD->setValue(1.0 / Menu::getInstance()->getAvatarLODDistanceMultiplier());
|
||||
_avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier());
|
||||
connect(_avatarLOD, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
|
||||
|
||||
// Add a button to reset
|
||||
|
@ -108,15 +111,17 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
}
|
||||
|
||||
void LodToolsDialog::reloadSliders() {
|
||||
_lodSize->setValue(Menu::getInstance()->getOctreeSizeScale() / TREE_SCALE);
|
||||
_boundaryLevelAdjust->setValue(Menu::getInstance()->getBoundaryLevelAdjust());
|
||||
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
_lodSize->setValue(lodManager->getOctreeSizeScale() / TREE_SCALE);
|
||||
_boundaryLevelAdjust->setValue(lodManager->getBoundaryLevelAdjust());
|
||||
_feedback->setText(lodManager->getLODFeedbackText());
|
||||
}
|
||||
|
||||
void LodToolsDialog::updateAvatarLODControls() {
|
||||
QFormLayout* form = static_cast<QFormLayout*>(layout());
|
||||
|
||||
Menu::getInstance()->setAutomaticAvatarLOD(_automaticAvatarLOD->isChecked());
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
lodManager->setAutomaticAvatarLOD(_automaticAvatarLOD->isChecked());
|
||||
|
||||
_avatarLODDecreaseFPS->setVisible(_automaticAvatarLOD->isChecked());
|
||||
form->labelForField(_avatarLODDecreaseFPS)->setVisible(_automaticAvatarLOD->isChecked());
|
||||
|
@ -128,7 +133,7 @@ void LodToolsDialog::updateAvatarLODControls() {
|
|||
form->labelForField(_avatarLOD)->setVisible(!_automaticAvatarLOD->isChecked());
|
||||
|
||||
if (!_automaticAvatarLOD->isChecked()) {
|
||||
_avatarLOD->setValue(1.0 / Menu::getInstance()->getAvatarLODDistanceMultiplier());
|
||||
_avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier());
|
||||
}
|
||||
|
||||
if (isVisible()) {
|
||||
|
@ -137,25 +142,28 @@ void LodToolsDialog::updateAvatarLODControls() {
|
|||
}
|
||||
|
||||
void LodToolsDialog::updateAvatarLODValues() {
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
if (_automaticAvatarLOD->isChecked()) {
|
||||
Menu::getInstance()->setAvatarLODDecreaseFPS(_avatarLODDecreaseFPS->value());
|
||||
Menu::getInstance()->setAvatarLODIncreaseFPS(_avatarLODIncreaseFPS->value());
|
||||
lodManager->setAvatarLODDecreaseFPS(_avatarLODDecreaseFPS->value());
|
||||
lodManager->setAvatarLODIncreaseFPS(_avatarLODIncreaseFPS->value());
|
||||
|
||||
} else {
|
||||
Menu::getInstance()->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value());
|
||||
lodManager->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value());
|
||||
}
|
||||
}
|
||||
|
||||
void LodToolsDialog::sizeScaleValueChanged(int value) {
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
float realValue = value * TREE_SCALE;
|
||||
Menu::getInstance()->setOctreeSizeScale(realValue);
|
||||
lodManager->setOctreeSizeScale(realValue);
|
||||
|
||||
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
|
||||
_feedback->setText(lodManager->getLODFeedbackText());
|
||||
}
|
||||
|
||||
void LodToolsDialog::boundaryLevelValueChanged(int value) {
|
||||
Menu::getInstance()->setBoundaryLevelAdjust(value);
|
||||
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
lodManager->setBoundaryLevelAdjust(value);
|
||||
_feedback->setText(lodManager->getLODFeedbackText());
|
||||
}
|
||||
|
||||
void LodToolsDialog::resetClicked(bool checked) {
|
||||
|
|
|
@ -29,12 +29,9 @@ LoginDialog::LoginDialog(QWidget* parent) :
|
|||
_ui(new Ui::LoginDialog) {
|
||||
|
||||
_ui->setupUi(this);
|
||||
_ui->errorLabel->hide();
|
||||
_ui->emailLineEdit->setFocus();
|
||||
_ui->logoLabel->setPixmap(QPixmap(PathUtils::resourcesPath() + "images/hifi-logo.svg"));
|
||||
_ui->loginButton->setIcon(QIcon(PathUtils::resourcesPath() + "images/login.svg"));
|
||||
_ui->infoLabel->setVisible(false);
|
||||
_ui->errorLabel->setVisible(false);
|
||||
reset();
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
|
||||
connect(&AccountManager::getInstance(), &AccountManager::loginComplete,
|
||||
this, &LoginDialog::handleLoginCompleted);
|
||||
|
@ -50,9 +47,21 @@ LoginDialog::~LoginDialog() {
|
|||
delete _ui;
|
||||
};
|
||||
|
||||
void LoginDialog::handleLoginCompleted(const QUrl& authURL) {
|
||||
void LoginDialog::reset() {
|
||||
_ui->errorLabel->hide();
|
||||
_ui->emailLineEdit->setFocus();
|
||||
_ui->logoLabel->setPixmap(QPixmap(PathUtils::resourcesPath() + "images/hifi-logo.svg"));
|
||||
_ui->loginButton->setIcon(QIcon(PathUtils::resourcesPath() + "images/login.svg"));
|
||||
_ui->infoLabel->setVisible(false);
|
||||
_ui->errorLabel->setVisible(false);
|
||||
|
||||
_ui->emailLineEdit->setText("");
|
||||
_ui->passwordLineEdit->setText("");
|
||||
_ui->loginArea->setDisabled(false);
|
||||
}
|
||||
|
||||
void LoginDialog::handleLoginCompleted(const QUrl& authURL) {
|
||||
reset();
|
||||
close();
|
||||
};
|
||||
|
||||
|
@ -87,3 +96,27 @@ void LoginDialog::moveEvent(QMoveEvent* event) {
|
|||
// Modal dialogs seemed to get repositioned automatically. Combat this by moving the window if needed.
|
||||
resizeAndPosition();
|
||||
};
|
||||
|
||||
|
||||
void LoginDialog::toggleQAction() {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
QAction* loginAction = Menu::getInstance()->getActionForOption(MenuOption::Login);
|
||||
Q_CHECK_PTR(loginAction);
|
||||
|
||||
disconnect(loginAction, 0, 0, 0);
|
||||
|
||||
if (accountManager.isLoggedIn()) {
|
||||
// change the menu item to logout
|
||||
loginAction->setText("Logout " + accountManager.getAccountInfo().getUsername());
|
||||
connect(loginAction, &QAction::triggered, &accountManager, &AccountManager::logout);
|
||||
} else {
|
||||
// change the menu item to login
|
||||
loginAction->setText("Login");
|
||||
connect(loginAction, &QAction::triggered, this, &LoginDialog::showLoginForCurrentDomain);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginDialog::showLoginForCurrentDomain() {
|
||||
show();
|
||||
resizeAndPosition(false);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,11 @@ public:
|
|||
~LoginDialog();
|
||||
|
||||
public slots:
|
||||
void toggleQAction();
|
||||
void showLoginForCurrentDomain();
|
||||
|
||||
protected slots:
|
||||
void reset();
|
||||
void handleLoginClicked();
|
||||
void handleLoginCompleted(const QUrl& authURL);
|
||||
void handleLoginFailed();
|
||||
|
@ -35,8 +40,7 @@ protected:
|
|||
void moveEvent(QMoveEvent* event);
|
||||
|
||||
private:
|
||||
Ui::LoginDialog* _ui;
|
||||
|
||||
Ui::LoginDialog* _ui = nullptr;
|
||||
};
|
||||
|
||||
#endif // hifi_LoginDialog_h
|
||||
|
|
|
@ -50,8 +50,8 @@ enum GridPlane {
|
|||
|
||||
const glm::vec2 INVALID_VECTOR(FLT_MAX, FLT_MAX);
|
||||
|
||||
MetavoxelEditor::MetavoxelEditor() :
|
||||
QWidget(Application::getInstance()->getWindow(), Qt::Tool) {
|
||||
MetavoxelEditor::MetavoxelEditor(QWidget* parent) :
|
||||
QWidget(parent, Qt::Tool) {
|
||||
|
||||
setWindowTitle("Metavoxel Editor");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef hifi_MetavoxelEditor_h
|
||||
#define hifi_MetavoxelEditor_h
|
||||
|
||||
#include <QFormLayout>
|
||||
#include <QList>
|
||||
#include <QWidget>
|
||||
|
||||
|
@ -38,7 +39,7 @@ class MetavoxelEditor : public QWidget {
|
|||
|
||||
public:
|
||||
|
||||
MetavoxelEditor();
|
||||
MetavoxelEditor(QWidget* parent = nullptr);
|
||||
|
||||
QString getSelectedAttribute() const;
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
const int BYTES_PER_KILOBYTE = 1024;
|
||||
|
||||
MetavoxelNetworkSimulator::MetavoxelNetworkSimulator() :
|
||||
QWidget(DependencyManager::get<GLCanvas>().data(), Qt::Dialog) {
|
||||
MetavoxelNetworkSimulator::MetavoxelNetworkSimulator(QWidget* parent) :
|
||||
QWidget(parent, Qt::Dialog) {
|
||||
|
||||
setWindowTitle("Metavoxel Network Simulator");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
|
|
@ -23,7 +23,7 @@ class MetavoxelNetworkSimulator : public QWidget {
|
|||
|
||||
public:
|
||||
|
||||
MetavoxelNetworkSimulator();
|
||||
MetavoxelNetworkSimulator(QWidget* parent = nullptr);
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
|
@ -11,18 +11,22 @@
|
|||
|
||||
#include <QFileDialog>
|
||||
|
||||
#include <devices/Faceshift.h>
|
||||
#include <devices/SixenseManager.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Audio.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Menu.h"
|
||||
#include "ModelsBrowser.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "Snapshot.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
const int PREFERENCES_HEIGHT_PADDING = 20;
|
||||
|
||||
PreferencesDialog::PreferencesDialog() :
|
||||
QDialog(Application::getInstance()->getWindow()) {
|
||||
PreferencesDialog::PreferencesDialog(QWidget* parent) :
|
||||
QDialog(parent) {
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
|
@ -117,51 +121,53 @@ void PreferencesDialog::loadPreferences() {
|
|||
|
||||
ui.sendDataCheckBox->setChecked(!menuInstance->isOptionChecked(MenuOption::DisableActivityLogger));
|
||||
|
||||
ui.snapshotLocationEdit->setText(menuInstance->getSnapshotsLocation());
|
||||
ui.snapshotLocationEdit->setText(SettingHandles::snapshotsLocation.get());
|
||||
|
||||
ui.scriptsLocationEdit->setText(menuInstance->getScriptsLocation());
|
||||
ui.scriptsLocationEdit->setText(qApp->getScriptsLocation());
|
||||
|
||||
ui.pupilDilationSlider->setValue(myAvatar->getHead()->getPupilDilation() *
|
||||
ui.pupilDilationSlider->maximum());
|
||||
|
||||
ui.faceshiftEyeDeflectionSider->setValue(menuInstance->getFaceshiftEyeDeflection() *
|
||||
auto faceshift = DependencyManager::get<Faceshift>();
|
||||
ui.faceshiftEyeDeflectionSider->setValue(faceshift->getEyeDeflection() *
|
||||
ui.faceshiftEyeDeflectionSider->maximum());
|
||||
|
||||
ui.faceshiftHostnameEdit->setText(menuInstance->getFaceshiftHostname());
|
||||
ui.faceshiftHostnameEdit->setText(faceshift->getHostname());
|
||||
|
||||
const InboundAudioStream::Settings& streamSettings = menuInstance->getReceivedAudioStreamSettings();
|
||||
|
||||
ui.dynamicJitterBuffersCheckBox->setChecked(streamSettings._dynamicJitterBuffers);
|
||||
ui.staticDesiredJitterBufferFramesSpin->setValue(streamSettings._staticDesiredJitterBufferFrames);
|
||||
ui.maxFramesOverDesiredSpin->setValue(streamSettings._maxFramesOverDesired);
|
||||
ui.useStdevForJitterCalcCheckBox->setChecked(streamSettings._useStDevForJitterCalc);
|
||||
ui.windowStarveThresholdSpin->setValue(streamSettings._windowStarveThreshold);
|
||||
ui.windowSecondsForDesiredCalcOnTooManyStarvesSpin->setValue(streamSettings._windowSecondsForDesiredCalcOnTooManyStarves);
|
||||
ui.windowSecondsForDesiredReductionSpin->setValue(streamSettings._windowSecondsForDesiredReduction);
|
||||
ui.repetitionWithFadeCheckBox->setChecked(streamSettings._repetitionWithFade);
|
||||
|
||||
auto audio = DependencyManager::get<Audio>();
|
||||
MixedProcessedAudioStream& stream = audio->getReceivedAudioStream();
|
||||
|
||||
ui.dynamicJitterBuffersCheckBox->setChecked(stream.getDynamicJitterBuffers());
|
||||
ui.staticDesiredJitterBufferFramesSpin->setValue(stream.getDesiredJitterBufferFrames());
|
||||
ui.maxFramesOverDesiredSpin->setValue(stream.getMaxFramesOverDesired());
|
||||
ui.useStdevForJitterCalcCheckBox->setChecked(stream.getUseStDevForJitterCalc());
|
||||
ui.windowStarveThresholdSpin->setValue(stream.getWindowStarveThreshold());
|
||||
ui.windowSecondsForDesiredCalcOnTooManyStarvesSpin->setValue(
|
||||
stream.getWindowSecondsForDesiredCalcOnTooManyStarves());
|
||||
ui.windowSecondsForDesiredReductionSpin->setValue(stream.getWindowSecondsForDesiredReduction());
|
||||
ui.repetitionWithFadeCheckBox->setChecked(stream.getRepetitionWithFade());
|
||||
|
||||
ui.outputBufferSizeSpinner->setValue(audio->getOutputBufferSize());
|
||||
|
||||
ui.outputStarveDetectionCheckBox->setChecked(audio->getOutputStarveDetectionEnabled());
|
||||
ui.outputStarveDetectionThresholdSpinner->setValue(audio->getOutputStarveDetectionThreshold());
|
||||
ui.outputStarveDetectionPeriodSpinner->setValue(audio->getOutputStarveDetectionPeriod());
|
||||
|
||||
ui.realWorldFieldOfViewSpin->setValue(menuInstance->getRealWorldFieldOfView());
|
||||
ui.realWorldFieldOfViewSpin->setValue(qApp->getViewFrustum()->getRealWorldFieldOfView());
|
||||
|
||||
ui.fieldOfViewSpin->setValue(menuInstance->getFieldOfView());
|
||||
ui.fieldOfViewSpin->setValue(qApp->getViewFrustum()->getFieldOfView());
|
||||
|
||||
ui.leanScaleSpin->setValue(myAvatar->getLeanScale());
|
||||
|
||||
ui.avatarScaleSpin->setValue(myAvatar->getScale());
|
||||
|
||||
ui.maxOctreePPSSpin->setValue(menuInstance->getMaxOctreePacketsPerSecond());
|
||||
ui.maxOctreePPSSpin->setValue(qApp->getOctreeQuery().getMaxOctreePacketsPerSecond());
|
||||
|
||||
ui.oculusUIAngularSizeSpin->setValue(menuInstance->getOculusUIAngularSize());
|
||||
ui.oculusUIAngularSizeSpin->setValue(qApp->getApplicationOverlay().getOculusUIAngularSize());
|
||||
|
||||
ui.sixenseReticleMoveSpeedSpin->setValue(menuInstance->getSixenseReticleMoveSpeed());
|
||||
|
||||
ui.invertSixenseButtonsCheckBox->setChecked(menuInstance->getInvertSixenseButtons());
|
||||
SixenseManager& sixense = SixenseManager::getInstance();
|
||||
ui.sixenseReticleMoveSpeedSpin->setValue(sixense.getReticleMoveSpeed());
|
||||
ui.invertSixenseButtonsCheckBox->setChecked(sixense.getInvertButtons());
|
||||
|
||||
}
|
||||
|
||||
|
@ -213,11 +219,11 @@ void PreferencesDialog::savePreferences() {
|
|||
}
|
||||
|
||||
if (!ui.snapshotLocationEdit->text().isEmpty() && QDir(ui.snapshotLocationEdit->text()).exists()) {
|
||||
Menu::getInstance()->setSnapshotsLocation(ui.snapshotLocationEdit->text());
|
||||
SettingHandles::snapshotsLocation.set(ui.snapshotLocationEdit->text());
|
||||
}
|
||||
|
||||
if (!ui.scriptsLocationEdit->text().isEmpty() && QDir(ui.scriptsLocationEdit->text()).exists()) {
|
||||
Menu::getInstance()->setScriptsLocation(ui.scriptsLocationEdit->text());
|
||||
qApp->setScriptsLocation(ui.scriptsLocationEdit->text());
|
||||
}
|
||||
|
||||
myAvatar->getHead()->setPupilDilation(ui.pupilDilationSlider->value() / (float)ui.pupilDilationSlider->maximum());
|
||||
|
@ -227,36 +233,35 @@ void PreferencesDialog::savePreferences() {
|
|||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height());
|
||||
|
||||
Menu::getInstance()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value());
|
||||
qApp->getViewFrustum()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value());
|
||||
|
||||
Menu::getInstance()->setFieldOfView(ui.fieldOfViewSpin->value());
|
||||
|
||||
Menu::getInstance()->setFaceshiftEyeDeflection(ui.faceshiftEyeDeflectionSider->value() /
|
||||
(float)ui.faceshiftEyeDeflectionSider->maximum());
|
||||
qApp->getViewFrustum()->setFieldOfView(ui.fieldOfViewSpin->value());
|
||||
|
||||
Menu::getInstance()->setFaceshiftHostname(ui.faceshiftHostnameEdit->text());
|
||||
auto faceshift = DependencyManager::get<Faceshift>();
|
||||
faceshift->setEyeDeflection(ui.faceshiftEyeDeflectionSider->value() /
|
||||
(float)ui.faceshiftEyeDeflectionSider->maximum());
|
||||
|
||||
Menu::getInstance()->setMaxOctreePacketsPerSecond(ui.maxOctreePPSSpin->value());
|
||||
faceshift->setHostname(ui.faceshiftHostnameEdit->text());
|
||||
|
||||
qApp->getOctreeQuery().setMaxOctreePacketsPerSecond(ui.maxOctreePPSSpin->value());
|
||||
|
||||
Menu::getInstance()->setOculusUIAngularSize(ui.oculusUIAngularSizeSpin->value());
|
||||
|
||||
Menu::getInstance()->setSixenseReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value());
|
||||
|
||||
Menu::getInstance()->setInvertSixenseButtons(ui.invertSixenseButtonsCheckBox->isChecked());
|
||||
|
||||
InboundAudioStream::Settings streamSettings;
|
||||
streamSettings._dynamicJitterBuffers = ui.dynamicJitterBuffersCheckBox->isChecked();
|
||||
streamSettings._staticDesiredJitterBufferFrames = ui.staticDesiredJitterBufferFramesSpin->value();
|
||||
streamSettings._maxFramesOverDesired = ui.maxFramesOverDesiredSpin->value();
|
||||
streamSettings._useStDevForJitterCalc = ui.useStdevForJitterCalcCheckBox->isChecked();
|
||||
streamSettings._windowStarveThreshold = ui.windowStarveThresholdSpin->value();
|
||||
streamSettings._windowSecondsForDesiredCalcOnTooManyStarves = ui.windowSecondsForDesiredCalcOnTooManyStarvesSpin->value();
|
||||
streamSettings._windowSecondsForDesiredReduction = ui.windowSecondsForDesiredReductionSpin->value();
|
||||
streamSettings._repetitionWithFade = ui.repetitionWithFadeCheckBox->isChecked();
|
||||
|
||||
Menu::getInstance()->setReceivedAudioStreamSettings(streamSettings);
|
||||
qApp->getApplicationOverlay().setOculusUIAngularSize(ui.oculusUIAngularSizeSpin->value());
|
||||
|
||||
SixenseManager& sixense = SixenseManager::getInstance();
|
||||
sixense.setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value());
|
||||
sixense.setInvertButtons(ui.invertSixenseButtonsCheckBox->isChecked());
|
||||
|
||||
auto audio = DependencyManager::get<Audio>();
|
||||
MixedProcessedAudioStream& stream = audio->getReceivedAudioStream();
|
||||
|
||||
stream.setDynamicJitterBuffers(ui.dynamicJitterBuffersCheckBox->isChecked());
|
||||
stream.setStaticDesiredJitterBufferFrames(ui.staticDesiredJitterBufferFramesSpin->value());
|
||||
stream.setMaxFramesOverDesired(ui.maxFramesOverDesiredSpin->value());
|
||||
stream.setUseStDevForJitterCalc(ui.useStdevForJitterCalcCheckBox->isChecked());
|
||||
stream.setWindowStarveThreshold(ui.windowStarveThresholdSpin->value());
|
||||
stream.setWindowSecondsForDesiredCalcOnTooManyStarves(ui.windowSecondsForDesiredCalcOnTooManyStarvesSpin->value());
|
||||
stream.setWindowSecondsForDesiredReduction(ui.windowSecondsForDesiredReductionSpin->value());
|
||||
stream.setRepetitionWithFade(ui.repetitionWithFadeCheckBox->isChecked());
|
||||
|
||||
QMetaObject::invokeMethod(audio.data(), "setOutputBufferSize", Q_ARG(int, ui.outputBufferSizeSpinner->value()));
|
||||
|
||||
|
@ -265,6 +270,4 @@ void PreferencesDialog::savePreferences() {
|
|||
audio->setOutputStarveDetectionPeriod(ui.outputStarveDetectionPeriodSpinner->value());
|
||||
|
||||
Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height());
|
||||
|
||||
Application::getInstance()->bumpSettings();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ class PreferencesDialog : public QDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PreferencesDialog();
|
||||
PreferencesDialog(QWidget* parent = nullptr);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* resizeEvent);
|
||||
|
|
|
@ -20,24 +20,17 @@
|
|||
#include "RearMirrorTools.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
const char SETTINGS_GROUP_NAME[] = "Rear View Tools";
|
||||
const char ZOOM_LEVEL_SETTINGS[] = "ZoomLevel";
|
||||
const int ICON_SIZE = 24;
|
||||
const int ICON_PADDING = 5;
|
||||
|
||||
RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds, QSettings* settings) :
|
||||
RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds) :
|
||||
_parent(parent),
|
||||
_bounds(bounds),
|
||||
_windowed(false),
|
||||
_fullScreen(false)
|
||||
{
|
||||
_zoomLevel = HEAD;
|
||||
_closeTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/close.svg"));
|
||||
|
||||
// Disabled for now https://worklist.net/19548
|
||||
// _resetTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/reset.png"));
|
||||
|
||||
_zoomHeadTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/plus.svg"));
|
||||
_zoomBodyTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/minus.svg"));
|
||||
|
||||
|
@ -46,11 +39,7 @@ RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds, QSettings* se
|
|||
_resetIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.top() + ICON_PADDING, ICON_SIZE, ICON_SIZE);
|
||||
_bodyZoomIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE);
|
||||
_headZoomIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE);
|
||||
|
||||
settings->beginGroup(SETTINGS_GROUP_NAME);
|
||||
_zoomLevel = loadSetting(settings, ZOOM_LEVEL_SETTINGS, 0) == HEAD ? HEAD : BODY;
|
||||
settings->endGroup();
|
||||
};
|
||||
}
|
||||
|
||||
void RearMirrorTools::render(bool fullScreen) {
|
||||
if (fullScreen) {
|
||||
|
@ -63,11 +52,9 @@ void RearMirrorTools::render(bool fullScreen) {
|
|||
if (_windowed) {
|
||||
displayIcon(_bounds, _closeIconRect, _closeTextureId);
|
||||
|
||||
// Disabled for now https://worklist.net/19548
|
||||
// displayIcon(_bounds, _resetIconRect, _resetTextureId);
|
||||
|
||||
displayIcon(_bounds, _headZoomIconRect, _zoomHeadTextureId, _zoomLevel == HEAD);
|
||||
displayIcon(_bounds, _bodyZoomIconRect, _zoomBodyTextureId, _zoomLevel == BODY);
|
||||
ZoomLevel zoomLevel = (ZoomLevel)SettingHandles::rearViewZoomLevel.get();
|
||||
displayIcon(_bounds, _headZoomIconRect, _zoomHeadTextureId, zoomLevel == HEAD);
|
||||
displayIcon(_bounds, _bodyZoomIconRect, _zoomBodyTextureId, zoomLevel == BODY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,23 +66,14 @@ bool RearMirrorTools::mousePressEvent(int x, int y) {
|
|||
emit closeView();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Disabled for now https://worklist.net/19548
|
||||
if (_resetIconRect.contains(x, y)) {
|
||||
emit resetView();
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
if (_headZoomIconRect.contains(x, y)) {
|
||||
_zoomLevel = HEAD;
|
||||
Application::getInstance()->bumpSettings();
|
||||
SettingHandles::rearViewZoomLevel.set(HEAD);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_bodyZoomIconRect.contains(x, y)) {
|
||||
_zoomLevel = BODY;
|
||||
Application::getInstance()->bumpSettings();
|
||||
SettingHandles::rearViewZoomLevel.set(BODY);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -116,12 +94,6 @@ bool RearMirrorTools::mousePressEvent(int x, int y) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void RearMirrorTools::saveSettings(QSettings* settings) {
|
||||
settings->beginGroup(SETTINGS_GROUP_NAME);
|
||||
settings->setValue(ZOOM_LEVEL_SETTINGS, _zoomLevel);
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, GLuint textureId, bool selected) {
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
|
|
@ -15,21 +15,27 @@
|
|||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QSettings>
|
||||
|
||||
#include <Settings.h>
|
||||
|
||||
enum ZoomLevel {
|
||||
HEAD,
|
||||
BODY
|
||||
HEAD = 0,
|
||||
BODY = 1
|
||||
};
|
||||
|
||||
namespace SettingHandles {
|
||||
const char SETTINGS_GROUP_NAME[] = "Rear View Tools";
|
||||
const char ZOOM_LEVEL_SETTINGS[] = "ZoomLevel";
|
||||
const SettingHandle<int> rearViewZoomLevel(QStringList() << SETTINGS_GROUP_NAME << ZOOM_LEVEL_SETTINGS,
|
||||
ZoomLevel::HEAD);
|
||||
}
|
||||
|
||||
class RearMirrorTools : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RearMirrorTools(QGLWidget* parent, QRect& bounds, QSettings* settings);
|
||||
RearMirrorTools(QGLWidget* parent, QRect& bounds);
|
||||
void render(bool fullScreen);
|
||||
bool mousePressEvent(int x, int y);
|
||||
ZoomLevel getZoomLevel() { return _zoomLevel; }
|
||||
void saveSettings(QSettings* settings);
|
||||
|
||||
signals:
|
||||
void closeView();
|
||||
|
@ -44,7 +50,6 @@ private:
|
|||
GLuint _resetTextureId;
|
||||
GLuint _zoomBodyTextureId;
|
||||
GLuint _zoomHeadTextureId;
|
||||
ZoomLevel _zoomLevel;
|
||||
|
||||
QRect _closeIconRect;
|
||||
QRect _resetIconRect;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "ui_scriptEditorWidget.h"
|
||||
#include "ScriptEditorWidget.h"
|
||||
#include "ScriptEditorWindow.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QFileDialog>
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
#include "FlowLayout.h"
|
||||
#include "JSConsole.h"
|
||||
|
||||
ScriptEditorWindow::ScriptEditorWindow() :
|
||||
ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) :
|
||||
QWidget(parent),
|
||||
_ScriptEditorWindowUI(new Ui::ScriptEditorWindow),
|
||||
_loadMenu(new QMenu),
|
||||
_saveMenu(new QMenu)
|
||||
|
|
|
@ -22,7 +22,7 @@ class ScriptEditorWindow : public QWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScriptEditorWindow();
|
||||
ScriptEditorWindow(QWidget* parent = nullptr);
|
||||
~ScriptEditorWindow();
|
||||
|
||||
void terminateCurrentTab();
|
||||
|
|
|
@ -10,13 +10,17 @@
|
|||
//
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QImage>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <Application.h>
|
||||
#include <FileUtils.h>
|
||||
|
||||
#include "Snapshot.h"
|
||||
#include "Menu.h"
|
||||
|
||||
// filename format: hifi-snap-by-%username%-on-%date%_%time%_@-%location%.jpg
|
||||
// %1 <= username, %2 <= date and time, %3 <= current location
|
||||
|
@ -86,7 +90,7 @@ QFile* Snapshot::savedFileForSnapshot(bool isTemporary) {
|
|||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
QImage shot = glCanvas->grabFrameBuffer();
|
||||
|
||||
Avatar* avatar = Application::getInstance()->getAvatar();
|
||||
Avatar* avatar = qApp->getAvatar();
|
||||
|
||||
glm::vec3 location = avatar->getPosition();
|
||||
glm::quat orientation = avatar->getHead()->getOrientation();
|
||||
|
@ -118,7 +122,7 @@ QFile* Snapshot::savedFileForSnapshot(bool isTemporary) {
|
|||
const int IMAGE_QUALITY = 100;
|
||||
|
||||
if (!isTemporary) {
|
||||
QString snapshotFullPath = Menu::getInstance()->getSnapshotsLocation();
|
||||
QString snapshotFullPath = SettingHandles::snapshotsLocation.get();
|
||||
|
||||
if (!snapshotFullPath.endsWith(QDir::separator())) {
|
||||
snapshotFullPath.append(QDir::separator());
|
||||
|
|
|
@ -12,15 +12,19 @@
|
|||
#ifndef hifi_Snapshot_h
|
||||
#define hifi_Snapshot_h
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <qimage.h>
|
||||
#include <qfile.h>
|
||||
#include <qtemporaryfile.h>
|
||||
#include <QGLWidget>
|
||||
#include <qstring.h>
|
||||
#include <QString>
|
||||
|
||||
#include "avatar/Avatar.h"
|
||||
#include <Settings.h>
|
||||
|
||||
class QFile;
|
||||
class QTemporaryFile;
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QString> snapshotsLocation("snapshotsLocation",
|
||||
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
|
||||
}
|
||||
|
||||
class SnapshotMetaData {
|
||||
public:
|
||||
|
@ -41,7 +45,6 @@ private:
|
|||
};
|
||||
|
||||
class Snapshot {
|
||||
|
||||
public:
|
||||
static QString saveSnapshot();
|
||||
static QTemporaryFile* saveTempSnapshot();
|
||||
|
|
39
interface/src/ui/StandAloneJSConsole.cpp
Normal file
39
interface/src/ui/StandAloneJSConsole.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// StandAloneJSConsole.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 1/17/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <Application.h>
|
||||
#include <MainWindow.h>
|
||||
|
||||
#include "StandAloneJSConsole.h"
|
||||
|
||||
void StandAloneJSConsole::toggleConsole() {
|
||||
QMainWindow* mainWindow = qApp->getWindow();
|
||||
if (!_jsConsole) {
|
||||
QDialog* dialog = new QDialog(mainWindow, Qt::WindowStaysOnTopHint);
|
||||
QVBoxLayout* layout = new QVBoxLayout(dialog);
|
||||
dialog->setLayout(layout);
|
||||
|
||||
dialog->resize(QSize(CONSOLE_WIDTH, CONSOLE_HEIGHT));
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(0);
|
||||
layout->addWidget(new JSConsole(dialog));
|
||||
dialog->setWindowOpacity(CONSOLE_WINDOW_OPACITY);
|
||||
dialog->setWindowTitle(CONSOLE_TITLE);
|
||||
|
||||
_jsConsole = dialog;
|
||||
}
|
||||
_jsConsole->setVisible(!_jsConsole->isVisible());
|
||||
}
|
||||
|
35
interface/src/ui/StandAloneJSConsole.h
Normal file
35
interface/src/ui/StandAloneJSConsole.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// StandAloneJSConsole.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 1/17/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_StandAloneJSConsole_h
|
||||
#define hifi_StandAloneJSConsole_h
|
||||
|
||||
#include <QPointer>
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include "JSConsole.h"
|
||||
|
||||
class QDialog;
|
||||
|
||||
class StandAloneJSConsole : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public slots:
|
||||
void toggleConsole();
|
||||
|
||||
private:
|
||||
StandAloneJSConsole() {}
|
||||
|
||||
QPointer<QDialog> _jsConsole;
|
||||
};
|
||||
|
||||
#endif // hifi_StandAloneJSConsole_h
|
|
@ -18,6 +18,10 @@
|
|||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
#include <Application.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <GLCanvas.h>
|
||||
#include <LODManager.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "Stats.h"
|
||||
|
@ -623,7 +627,7 @@ void Stats::display(
|
|||
// LOD Details
|
||||
if (_expanded) {
|
||||
octreeStats.str("");
|
||||
QString displayLODDetails = Menu::getInstance()->getLODFeedbackText();
|
||||
QString displayLODDetails = DependencyManager::get<LODManager>()->getLODFeedbackText();
|
||||
octreeStats << "LOD: You can see " << qPrintable(displayLODDetails.trimmed());
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QScriptValueIterator>
|
||||
|
||||
#include <limits>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <Application.h>
|
||||
#include <devices/OculusManager.h>
|
||||
#include <Menu.h>
|
||||
#include <QScriptValueIterator>
|
||||
#include <LODManager.h>
|
||||
|
||||
#include "BillboardOverlay.h"
|
||||
#include "Circle3DOverlay.h"
|
||||
|
@ -83,10 +85,13 @@ void Overlays::update(float deltatime) {
|
|||
|
||||
void Overlays::renderHUD() {
|
||||
QReadLocker lock(&_lock);
|
||||
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(),
|
||||
Menu::getInstance()->getOctreeSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(),
|
||||
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
foreach(Overlay* thisOverlay, _overlaysHUD) {
|
||||
if (thisOverlay->is3D()) {
|
||||
|
@ -116,9 +121,12 @@ void Overlays::renderWorld(bool drawFront, RenderArgs::RenderMode renderMode, Re
|
|||
glm::vec3 axis(0.0f, 1.0f, 0.0f);
|
||||
float myAvatarScale = 1.0f;
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(),
|
||||
Menu::getInstance()->getOctreeSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
foreach(Overlay* thisOverlay, _overlaysWorld) {
|
||||
|
|
|
@ -11,11 +11,27 @@
|
|||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <Settings.h>
|
||||
|
||||
#include "InboundAudioStream.h"
|
||||
#include "PacketHeaders.h"
|
||||
|
||||
const int STARVE_HISTORY_CAPACITY = 50;
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<bool> dynamicJitterBuffers("dynamicJitterBuffers", DEFAULT_DYNAMIC_JITTER_BUFFERS);
|
||||
const SettingHandle<int> maxFramesOverDesired("maxFramesOverDesired", DEFAULT_MAX_FRAMES_OVER_DESIRED);
|
||||
const SettingHandle<int> staticDesiredJitterBufferFrames("staticDesiredJitterBufferFrames",
|
||||
DEFAULT_STATIC_DESIRED_JITTER_BUFFER_FRAMES);
|
||||
const SettingHandle<bool> useStDevForJitterCalc("useStDevForJitterCalc", DEFAULT_USE_STDEV_FOR_JITTER_CALC);
|
||||
const SettingHandle<int> windowStarveThreshold("windowStarveThreshold", DEFAULT_WINDOW_STARVE_THRESHOLD);
|
||||
const SettingHandle<int> windowSecondsForDesiredCalcOnTooManyStarves("windowSecondsForDesiredCalcOnTooManyStarves",
|
||||
DEFAULT_WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES);
|
||||
const SettingHandle<int> windowSecondsForDesiredReduction("windowSecondsForDesiredReduction",
|
||||
DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION);
|
||||
const SettingHandle<bool> repetitionWithFade("repetitionWithFade", DEFAULT_REPETITION_WITH_FADE);
|
||||
}
|
||||
|
||||
InboundAudioStream::InboundAudioStream(int numFrameSamples, int numFramesCapacity, const Settings& settings) :
|
||||
_ringBuffer(numFrameSamples, false, numFramesCapacity),
|
||||
_lastPopSucceeded(false),
|
||||
|
@ -500,3 +516,28 @@ float calculateRepeatedFrameFadeFactor(int indexOfRepeat) {
|
|||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void InboundAudioStream::loadSettings() {
|
||||
setDynamicJitterBuffers(SettingHandles::dynamicJitterBuffers.get());
|
||||
setMaxFramesOverDesired(SettingHandles::maxFramesOverDesired.get());
|
||||
setStaticDesiredJitterBufferFrames(SettingHandles::staticDesiredJitterBufferFrames.get());
|
||||
setUseStDevForJitterCalc(SettingHandles::useStDevForJitterCalc.get());
|
||||
setWindowStarveThreshold(SettingHandles::windowStarveThreshold.get());
|
||||
setWindowSecondsForDesiredCalcOnTooManyStarves(SettingHandles::windowSecondsForDesiredCalcOnTooManyStarves.get());
|
||||
setWindowSecondsForDesiredReduction(SettingHandles::windowSecondsForDesiredReduction.get());
|
||||
setRepetitionWithFade(SettingHandles::repetitionWithFade.get());
|
||||
}
|
||||
|
||||
void InboundAudioStream::saveSettings() {
|
||||
SettingHandles::dynamicJitterBuffers.set(getDynamicJitterBuffers());
|
||||
SettingHandles::maxFramesOverDesired.set(getMaxFramesOverDesired());
|
||||
SettingHandles::staticDesiredJitterBufferFrames.set(getDesiredJitterBufferFrames());
|
||||
SettingHandles::useStDevForJitterCalc.set(getUseStDevForJitterCalc());
|
||||
SettingHandles::windowStarveThreshold.set(getWindowStarveThreshold());
|
||||
SettingHandles::windowSecondsForDesiredCalcOnTooManyStarves.set(getWindowSecondsForDesiredCalcOnTooManyStarves());
|
||||
SettingHandles::windowSecondsForDesiredReduction.set(getWindowSecondsForDesiredReduction());
|
||||
SettingHandles::repetitionWithFade.set(getRepetitionWithFade());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -126,6 +126,8 @@ public:
|
|||
void setWindowSecondsForDesiredReduction(int windowSecondsForDesiredReduction);
|
||||
void setRepetitionWithFade(bool repetitionWithFade) { _repetitionWithFade = repetitionWithFade; }
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
virtual AudioStreamStats getAudioStreamStats() const;
|
||||
|
||||
|
@ -138,7 +140,15 @@ public:
|
|||
|
||||
/// returns the desired number of jitter buffer frames using Freddy's method
|
||||
int getCalculatedJitterBufferFramesUsingMaxGap() const { return _calculatedJitterBufferFramesUsingMaxGap; }
|
||||
|
||||
|
||||
int getWindowSecondsForDesiredReduction() const {
|
||||
return _timeGapStatsForDesiredReduction.getWindowIntervals(); }
|
||||
int getWindowSecondsForDesiredCalcOnTooManyStarves() const {
|
||||
return _timeGapStatsForDesiredCalcOnTooManyStarves.getWindowIntervals(); }
|
||||
bool getDynamicJitterBuffers() const { return _dynamicJitterBuffers; }
|
||||
bool getRepetitionWithFade() const { return _repetitionWithFade;}
|
||||
int getWindowStarveThreshold() const { return _starveThreshold;}
|
||||
bool getUseStDevForJitterCalc() const { return _useStDevForJitterCalc; }
|
||||
int getDesiredJitterBufferFrames() const { return _desiredJitterBufferFrames; }
|
||||
int getMaxFramesOverDesired() const { return _maxFramesOverDesired; }
|
||||
int getNumFrameSamples() const { return _ringBuffer.getNumFrameSamples(); }
|
||||
|
@ -204,7 +214,7 @@ protected:
|
|||
|
||||
bool _lastPopSucceeded;
|
||||
AudioRingBuffer::ConstIterator _lastPopOutput;
|
||||
|
||||
|
||||
bool _dynamicJitterBuffers; // if false, _desiredJitterBufferFrames is locked at 1 (old behavior)
|
||||
int _staticDesiredJitterBufferFrames;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <ByteCountCoding.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <Octree.h>
|
||||
#include <PhysicsHelpers.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <SharedUtil.h> // usecTimestampNow()
|
||||
|
||||
|
@ -711,10 +712,22 @@ void EntityItem::simulateKinematicMotion(float timeElapsed) {
|
|||
} else {
|
||||
// NOTE: angularSpeed is currently in degrees/sec!!!
|
||||
// TODO: Andrew to convert to radians/sec
|
||||
float angle = timeElapsed * glm::radians(angularSpeed);
|
||||
glm::vec3 axis = _angularVelocity / angularSpeed;
|
||||
glm::quat dQ = glm::angleAxis(angle, axis);
|
||||
glm::quat rotation = glm::normalize(dQ * getRotation());
|
||||
glm::vec3 angularVelocity = glm::radians(_angularVelocity);
|
||||
// for improved agreement with the way Bullet integrates rotations we use an approximation
|
||||
// and break the integration into bullet-sized substeps
|
||||
glm::quat rotation = getRotation();
|
||||
float dt = timeElapsed;
|
||||
while (dt > PHYSICS_ENGINE_FIXED_SUBSTEP) {
|
||||
glm::quat dQ = computeBulletRotationStep(angularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP);
|
||||
rotation = glm::normalize(dQ * rotation);
|
||||
dt -= PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||
}
|
||||
// NOTE: this final partial substep can drift away from a real Bullet simulation however
|
||||
// it only becomes significant for rapidly rotating objects
|
||||
// (e.g. around PI/4 radians per substep, or 7.5 rotations/sec at 60 substeps/sec).
|
||||
glm::quat dQ = computeBulletRotationStep(angularVelocity, dt);
|
||||
rotation = glm::normalize(dQ * rotation);
|
||||
|
||||
setRotation(rotation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ Batch::Batch() :
|
|||
_resources(),
|
||||
_data(),
|
||||
_buffers(),
|
||||
_textures(),
|
||||
_streamFormats(),
|
||||
_transforms()
|
||||
{
|
||||
|
@ -38,6 +39,7 @@ void Batch::clear() {
|
|||
_resources.clear();
|
||||
_data.clear();
|
||||
_buffers.clear();
|
||||
_textures.clear();
|
||||
_streamFormats.clear();
|
||||
_transforms.clear();
|
||||
}
|
||||
|
@ -171,3 +173,14 @@ void Batch::setUniformBuffer(uint32 slot, const BufferView& view) {
|
|||
}
|
||||
|
||||
|
||||
void Batch::setUniformTexture(uint32 slot, const TexturePointer& texture) {
|
||||
ADD_COMMAND(setUniformTexture);
|
||||
|
||||
_params.push_back(_textures.cache(texture));
|
||||
_params.push_back(slot);
|
||||
}
|
||||
|
||||
void Batch::setUniformTexture(uint32 slot, const TextureView& view) {
|
||||
setUniformTexture(slot, view._texture);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "Stream.h"
|
||||
#include "Texture.h"
|
||||
|
||||
#if defined(NSIGHT_FOUND)
|
||||
#include "nvToolsExt.h"
|
||||
|
@ -92,6 +93,10 @@ public:
|
|||
void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size);
|
||||
void setUniformBuffer(uint32 slot, const BufferView& view); // not a command, just a shortcut from a BufferView
|
||||
|
||||
void setUniformTexture(uint32 slot, const TexturePointer& view);
|
||||
void setUniformTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView
|
||||
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
@ -148,10 +153,6 @@ public:
|
|||
|
||||
void _glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
|
||||
void _glMaterialf(GLenum face, GLenum pname, GLfloat param);
|
||||
void _glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
|
||||
|
||||
|
||||
enum Command {
|
||||
COMMAND_draw = 0,
|
||||
COMMAND_drawIndexed,
|
||||
|
@ -167,6 +168,7 @@ public:
|
|||
COMMAND_setProjectionTransform,
|
||||
|
||||
COMMAND_setUniformBuffer,
|
||||
COMMAND_setUniformTexture,
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
|
@ -219,10 +221,7 @@ public:
|
|||
COMMAND_glEnableVertexAttribArray,
|
||||
COMMAND_glDisableVertexAttribArray,
|
||||
|
||||
COMMAND_glColor4f,
|
||||
|
||||
COMMAND_glMaterialf,
|
||||
COMMAND_glMaterialfv,
|
||||
COMMAND_glColor4f,
|
||||
|
||||
NUM_COMMANDS,
|
||||
};
|
||||
|
@ -292,6 +291,7 @@ public:
|
|||
};
|
||||
|
||||
typedef Cache<BufferPointer>::Vector BufferCaches;
|
||||
typedef Cache<TexturePointer>::Vector TextureCaches;
|
||||
typedef Cache<Stream::FormatPointer>::Vector StreamFormatCaches;
|
||||
typedef Cache<Transform>::Vector TransformCaches;
|
||||
|
||||
|
@ -330,6 +330,7 @@ public:
|
|||
Bytes _data;
|
||||
|
||||
BufferCaches _buffers;
|
||||
TextureCaches _textures;
|
||||
StreamFormatCaches _streamFormats;
|
||||
TransformCaches _transforms;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Texture.h"
|
||||
|
||||
namespace gpu {
|
||||
|
||||
|
@ -39,6 +40,17 @@ public:
|
|||
|
||||
void syncGPUObject(const Buffer& buffer);
|
||||
|
||||
template< typename T >
|
||||
static void setGPUObject(const Texture& texture, T* to) {
|
||||
texture.setGPUObject(reinterpret_cast<GPUObject*>(to));
|
||||
}
|
||||
template< typename T >
|
||||
static T* getGPUObject(const Texture& texture) {
|
||||
return reinterpret_cast<T*>(texture.getGPUObject());
|
||||
}
|
||||
|
||||
void syncGPUObject(const Texture& texture);
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
|
|
@ -93,19 +93,24 @@ static const int DIMENSION_COUNT[NUM_DIMENSIONS] = {
|
|||
// Provide information on how to use the element
|
||||
enum Semantic {
|
||||
RAW = 0, // used as RAW memory
|
||||
|
||||
RGB,
|
||||
RGBA,
|
||||
BGRA,
|
||||
XYZ,
|
||||
XYZW,
|
||||
POS_XYZ,
|
||||
POS_XYZW,
|
||||
QUAT,
|
||||
DIR_XYZ,
|
||||
UV,
|
||||
R8,
|
||||
INDEX, //used by index buffer of a mesh
|
||||
PART, // used by part buffer of a mesh
|
||||
|
||||
DEPTH, // Depth buffer
|
||||
DEPTH_STENCIL, // Depth Stencil buffer
|
||||
|
||||
SRGB,
|
||||
SRGBA,
|
||||
SBGRA,
|
||||
|
||||
NUM_SEMANTICS,
|
||||
};
|
||||
|
||||
|
@ -124,7 +129,7 @@ public:
|
|||
_dimension(SCALAR),
|
||||
_type(INT8)
|
||||
{}
|
||||
|
||||
|
||||
Semantic getSemantic() const { return (Semantic)_semantic; }
|
||||
|
||||
Dimension getDimension() const { return (Dimension)_dimension; }
|
||||
|
@ -135,13 +140,22 @@ public:
|
|||
|
||||
uint32 getSize() const { return DIMENSION_COUNT[_dimension] * TYPE_SIZE[_type]; }
|
||||
|
||||
protected:
|
||||
uint16 getRaw() const { return *((uint16*) (this)); }
|
||||
|
||||
|
||||
bool operator ==(const Element& right) const {
|
||||
return getRaw() == right.getRaw();
|
||||
}
|
||||
bool operator !=(const Element& right) const {
|
||||
return getRaw() != right.getRaw();
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8 _semantic;
|
||||
uint8 _dimension : 4;
|
||||
uint8 _type : 4;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// GLBackend.cpp
|
||||
// interface/src/gpu
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 10/27/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
|
@ -8,13 +8,7 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "GLBackend.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "Batch.h"
|
||||
|
||||
using namespace gpu;
|
||||
#include "GLBackendShared.h"
|
||||
|
||||
GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
||||
{
|
||||
|
@ -32,6 +26,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_setProjectionTransform),
|
||||
|
||||
(&::gpu::GLBackend::do_setUniformBuffer),
|
||||
(&::gpu::GLBackend::do_setUniformTexture),
|
||||
|
||||
(&::gpu::GLBackend::do_glEnable),
|
||||
(&::gpu::GLBackend::do_glDisable),
|
||||
|
@ -82,40 +77,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_glDisableVertexAttribArray),
|
||||
|
||||
(&::gpu::GLBackend::do_glColor4f),
|
||||
|
||||
(&::gpu::GLBackend::do_glMaterialf),
|
||||
(&::gpu::GLBackend::do_glMaterialfv),
|
||||
};
|
||||
|
||||
static const GLenum _primitiveToGLmode[NUM_PRIMITIVES] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
GL_LINE_STRIP,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP,
|
||||
GL_QUADS,
|
||||
};
|
||||
|
||||
static const GLenum _elementTypeToGLType[NUM_TYPES]= {
|
||||
GL_FLOAT,
|
||||
GL_INT,
|
||||
GL_UNSIGNED_INT,
|
||||
GL_HALF_FLOAT,
|
||||
GL_SHORT,
|
||||
GL_UNSIGNED_SHORT,
|
||||
GL_BYTE,
|
||||
GL_UNSIGNED_BYTE,
|
||||
GL_FLOAT,
|
||||
GL_INT,
|
||||
GL_UNSIGNED_INT,
|
||||
GL_HALF_FLOAT,
|
||||
GL_SHORT,
|
||||
GL_UNSIGNED_SHORT,
|
||||
GL_BYTE,
|
||||
GL_UNSIGNED_BYTE
|
||||
};
|
||||
|
||||
|
||||
GLBackend::GLBackend() :
|
||||
_input(),
|
||||
_transform()
|
||||
|
@ -174,9 +137,6 @@ void GLBackend::checkGLError() {
|
|||
}
|
||||
}
|
||||
|
||||
//#define CHECK_GL_ERROR() ::gpu::GLBackend::checkGLError()
|
||||
#define CHECK_GL_ERROR()
|
||||
|
||||
void GLBackend::do_draw(Batch& batch, uint32 paramOffset) {
|
||||
updateInput();
|
||||
updateTransform();
|
||||
|
@ -508,6 +468,18 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
|||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::do_setUniformTexture(Batch& batch, uint32 paramOffset) {
|
||||
GLuint slot = batch._params[paramOffset + 1]._uint;
|
||||
TexturePointer uniformTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
|
||||
|
||||
GLuint to = getTextureID(uniformTexture);
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, to);
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
@ -1077,40 +1049,6 @@ void GLBackend::do_glColor4f(Batch& batch, uint32 paramOffset) {
|
|||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glMaterialf(GLenum face, GLenum pname, GLfloat param) {
|
||||
ADD_COMMAND_GL(glMaterialf);
|
||||
|
||||
_params.push_back(param);
|
||||
_params.push_back(pname);
|
||||
_params.push_back(face);
|
||||
|
||||
DO_IT_NOW(_glMaterialf, 3);
|
||||
}
|
||||
void GLBackend::do_glMaterialf(Batch& batch, uint32 paramOffset) {
|
||||
glMaterialf(
|
||||
batch._params[paramOffset + 2]._uint,
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
batch._params[paramOffset + 0]._float);
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
||||
ADD_COMMAND_GL(glMaterialfv);
|
||||
|
||||
_params.push_back(cacheData(4 * sizeof(float), params));
|
||||
_params.push_back(pname);
|
||||
_params.push_back(face);
|
||||
|
||||
DO_IT_NOW(_glMaterialfv, 3);
|
||||
}
|
||||
void GLBackend::do_glMaterialfv(Batch& batch, uint32 paramOffset) {
|
||||
glMaterialfv(
|
||||
batch._params[paramOffset + 2]._uint,
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
GLBackend::GLBuffer::GLBuffer() :
|
||||
_stamp(0),
|
||||
_buffer(0),
|
||||
|
@ -1156,3 +1094,4 @@ GLuint GLBackend::getBufferID(const Buffer& buffer) {
|
|||
GLBackend::syncGPUObject(buffer);
|
||||
return Backend::getGPUObject<GLBackend::GLBuffer>(buffer)->_buffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// GLBackend.h
|
||||
// interface/src/gpu
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 10/27/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
class GLBuffer {
|
||||
public:
|
||||
Stamp _stamp;
|
||||
Stamp _stamp;
|
||||
GLuint _buffer;
|
||||
GLuint _size;
|
||||
|
||||
|
@ -42,9 +42,21 @@ public:
|
|||
~GLBuffer();
|
||||
};
|
||||
static void syncGPUObject(const Buffer& buffer);
|
||||
|
||||
static GLuint getBufferID(const Buffer& buffer);
|
||||
|
||||
class GLTexture {
|
||||
public:
|
||||
Stamp _storageStamp;
|
||||
Stamp _contentStamp;
|
||||
GLuint _texture;
|
||||
GLuint _size;
|
||||
|
||||
GLTexture();
|
||||
~GLTexture();
|
||||
};
|
||||
static void syncGPUObject(const Texture& texture);
|
||||
static GLuint getTextureID(const TexturePointer& texture);
|
||||
|
||||
static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS;
|
||||
static const int MAX_NUM_INPUT_BUFFERS = 16;
|
||||
|
||||
|
@ -124,6 +136,7 @@ protected:
|
|||
|
||||
// Shader Stage
|
||||
void do_setUniformBuffer(Batch& batch, uint32 paramOffset);
|
||||
void do_setUniformTexture(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void updateShader();
|
||||
struct ShaderStageState {
|
||||
|
@ -188,9 +201,6 @@ protected:
|
|||
|
||||
void do_glColor4f(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glMaterialf(Batch& batch, uint32 paramOffset);
|
||||
void do_glMaterialfv(Batch& batch, uint32 paramOffset);
|
||||
|
||||
typedef void (GLBackend::*CommandCall)(Batch&, uint32);
|
||||
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
|
||||
|
||||
|
|
53
libraries/gpu/src/gpu/GLBackendShared.h
Normal file
53
libraries/gpu/src/gpu/GLBackendShared.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// GLBackendShared.h
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 1/22/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_gpu_GLBackend_Shared_h
|
||||
#define hifi_gpu_GLBackend_Shared_h
|
||||
|
||||
#include "GLBackend.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "Batch.h"
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
static const GLenum _primitiveToGLmode[NUM_PRIMITIVES] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
GL_LINE_STRIP,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP,
|
||||
GL_QUADS,
|
||||
};
|
||||
|
||||
static const GLenum _elementTypeToGLType[NUM_TYPES]= {
|
||||
GL_FLOAT,
|
||||
GL_INT,
|
||||
GL_UNSIGNED_INT,
|
||||
GL_HALF_FLOAT,
|
||||
GL_SHORT,
|
||||
GL_UNSIGNED_SHORT,
|
||||
GL_BYTE,
|
||||
GL_UNSIGNED_BYTE,
|
||||
GL_FLOAT,
|
||||
GL_INT,
|
||||
GL_UNSIGNED_INT,
|
||||
GL_HALF_FLOAT,
|
||||
GL_SHORT,
|
||||
GL_UNSIGNED_SHORT,
|
||||
GL_BYTE,
|
||||
GL_UNSIGNED_BYTE
|
||||
};
|
||||
|
||||
#define CHECK_GL_ERROR() ::gpu::GLBackend::checkGLError()
|
||||
//#define CHECK_GL_ERROR()
|
||||
|
||||
#endif
|
331
libraries/gpu/src/gpu/GLBackendTexture.cpp
Executable file
331
libraries/gpu/src/gpu/GLBackendTexture.cpp
Executable file
|
@ -0,0 +1,331 @@
|
|||
//
|
||||
// GLBackendTexture.cpp
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 1/19/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "GLBackendShared.h"
|
||||
|
||||
|
||||
GLBackend::GLTexture::GLTexture() :
|
||||
_storageStamp(0),
|
||||
_contentStamp(0),
|
||||
_texture(0),
|
||||
_size(0)
|
||||
{}
|
||||
|
||||
GLBackend::GLTexture::~GLTexture() {
|
||||
if (_texture != 0) {
|
||||
glDeleteTextures(1, &_texture);
|
||||
}
|
||||
}
|
||||
|
||||
class GLTexelFormat {
|
||||
public:
|
||||
GLenum internalFormat;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
|
||||
static GLTexelFormat evalGLTexelFormat(const Element& dstFormat, const Element& srcFormat) {
|
||||
if (dstFormat != srcFormat) {
|
||||
GLTexelFormat texel = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
|
||||
|
||||
switch(dstFormat.getDimension()) {
|
||||
case gpu::SCALAR: {
|
||||
texel.format = GL_RED;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RED;
|
||||
break;
|
||||
case gpu::DEPTH:
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC2: {
|
||||
texel.format = GL_RG;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RG;
|
||||
break;
|
||||
case gpu::DEPTH_STENCIL:
|
||||
texel.internalFormat = GL_DEPTH_STENCIL;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC3: {
|
||||
texel.format = GL_RGB;
|
||||
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGB;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC4: {
|
||||
texel.format = GL_RGBA;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(srcFormat.getSemantic()) {
|
||||
case gpu::BGRA:
|
||||
case gpu::SBGRA:
|
||||
texel.format = GL_BGRA;
|
||||
break;
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
texel.internalFormat = GL_RGB;
|
||||
break;
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGBA;
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
texel.internalFormat = GL_SRGB;
|
||||
break;
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB_ALPHA;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
return texel;
|
||||
} else {
|
||||
GLTexelFormat texel = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
|
||||
|
||||
switch(dstFormat.getDimension()) {
|
||||
case gpu::SCALAR: {
|
||||
texel.format = GL_RED;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RED;
|
||||
break;
|
||||
case gpu::DEPTH:
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC2: {
|
||||
texel.format = GL_RG;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RG;
|
||||
break;
|
||||
case gpu::DEPTH_STENCIL:
|
||||
texel.internalFormat = GL_DEPTH_STENCIL;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC3: {
|
||||
texel.format = GL_RGB;
|
||||
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGB;
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB; // standard 2.2 gamma correction color
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC4: {
|
||||
texel.format = GL_RGBA;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
texel.internalFormat = GL_RGB;
|
||||
break;
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGBA;
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
texel.internalFormat = GL_SRGB;
|
||||
break;
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB_ALPHA; // standard 2.2 gamma correction color
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
qDebug() << "Unknown combination of texel format";
|
||||
}
|
||||
return texel;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void GLBackend::syncGPUObject(const Texture& texture) {
|
||||
GLTexture* object = Backend::getGPUObject<GLBackend::GLTexture>(texture);
|
||||
|
||||
// If GPU object already created and in sync
|
||||
bool needUpdate = false;
|
||||
if (object && (object->_storageStamp == texture.getStamp())) {
|
||||
// If gpu object info is in sync with sysmem version
|
||||
if (object->_contentStamp >= texture.getDataStamp()) {
|
||||
// Then all good, GPU object is ready to be used
|
||||
return;
|
||||
} else {
|
||||
// Need to update the content of the GPU object from the source sysmem of the texture
|
||||
needUpdate = true;
|
||||
}
|
||||
} else if (!texture.isDefined()) {
|
||||
// NO texture definition yet so let's avoid thinking
|
||||
return;
|
||||
}
|
||||
|
||||
// need to have a gpu object?
|
||||
if (!object) {
|
||||
object = new GLTexture();
|
||||
glGenTextures(1, &object->_texture);
|
||||
CHECK_GL_ERROR();
|
||||
Backend::setGPUObject(texture, object);
|
||||
}
|
||||
|
||||
// GO through the process of allocating the correct storage and/or update the content
|
||||
switch (texture.getType()) {
|
||||
case Texture::TEX_2D: {
|
||||
if (needUpdate) {
|
||||
if (texture.isStoredMipAvailable(0)) {
|
||||
GLint boundTex = -1;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex);
|
||||
|
||||
Texture::PixelsPointer mip = texture.accessStoredMip(0);
|
||||
const GLvoid* bytes = mip->_sysmem.read<Resource::Byte>();
|
||||
Element srcFormat = mip->_format;
|
||||
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, object->_texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0,
|
||||
texelFormat.format, texelFormat.type, bytes);
|
||||
|
||||
if (texture.isAutogenerateMips()) {
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, boundTex);
|
||||
object->_contentStamp = texture.getDataStamp();
|
||||
}
|
||||
} else {
|
||||
const GLvoid* bytes = 0;
|
||||
Element srcFormat = texture.getTexelFormat();
|
||||
if (texture.isStoredMipAvailable(0)) {
|
||||
Texture::PixelsPointer mip = texture.accessStoredMip(0);
|
||||
|
||||
bytes = mip->_sysmem.read<Resource::Byte>();
|
||||
srcFormat = mip->_format;
|
||||
|
||||
object->_contentStamp = texture.getDataStamp();
|
||||
}
|
||||
|
||||
GLint boundTex = -1;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex);
|
||||
glBindTexture(GL_TEXTURE_2D, object->_texture);
|
||||
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||
texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0,
|
||||
texelFormat.format, texelFormat.type, bytes);
|
||||
|
||||
if (bytes && texture.isAutogenerateMips()) {
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, boundTex);
|
||||
object->_storageStamp = texture.getStamp();
|
||||
object->_size = texture.getSize();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qDebug() << "GLBackend::syncGPUObject(const Texture&) case for Texture Type " << texture.getType() << " not supported";
|
||||
}
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLuint GLBackend::getTextureID(const TexturePointer& texture) {
|
||||
if (!texture) {
|
||||
return 0;
|
||||
}
|
||||
GLBackend::syncGPUObject(*texture);
|
||||
GLTexture* object = Backend::getGPUObject<GLBackend::GLTexture>(*texture);
|
||||
if (object) {
|
||||
return object->_texture;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Resource.cpp
|
||||
// interface/src/gpu
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 10/8/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Resource.h
|
||||
// interface/src/gpu
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 10/8/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
|
@ -79,18 +79,20 @@ protected:
|
|||
|
||||
// Access the byte array.
|
||||
// The edit version allow to map data.
|
||||
inline const Byte* readData() const { return _data; }
|
||||
inline Byte* editData() { _stamp++; return _data; }
|
||||
const Byte* readData() const { return _data; }
|
||||
Byte* editData() { _stamp++; return _data; }
|
||||
|
||||
template< typename T > const T* read() const { return reinterpret_cast< T* > ( _data ); }
|
||||
template< typename T > T* edit() { _stamp++; return reinterpret_cast< T* > ( _data ); }
|
||||
|
||||
// Access the current version of the sysmem, used to compare if copies are in sync
|
||||
inline Stamp getStamp() const { return _stamp; }
|
||||
Stamp getStamp() const { return _stamp; }
|
||||
|
||||
static Size allocateMemory(Byte** memAllocated, Size size);
|
||||
static void deallocateMemory(Byte* memDeallocated, Size size);
|
||||
|
||||
bool isAvailable() const { return (_data != 0); }
|
||||
|
||||
private:
|
||||
Stamp _stamp;
|
||||
Size _size;
|
||||
|
@ -136,9 +138,9 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
Sysmem* _sysmem;
|
||||
Sysmem* _sysmem = NULL;
|
||||
|
||||
mutable GPUObject* _gpuObject;
|
||||
mutable GPUObject* _gpuObject = NULL;
|
||||
|
||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||
|
@ -363,64 +365,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// TODO: For now TextureView works with Buffer as a place holder for the Texture.
|
||||
// The overall logic should be about the same except that the Texture will be a real GL Texture under the hood
|
||||
class TextureView {
|
||||
public:
|
||||
typedef Resource::Size Size;
|
||||
typedef int Index;
|
||||
|
||||
BufferPointer _buffer;
|
||||
Size _offset;
|
||||
Size _size;
|
||||
Element _element;
|
||||
uint16 _stride;
|
||||
|
||||
TextureView() :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(gpu::VEC3, gpu::UINT8, gpu::RGB),
|
||||
_stride(1)
|
||||
{};
|
||||
|
||||
TextureView(const Element& element) :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
|
||||
// create the BufferView and own the Buffer
|
||||
TextureView(Buffer* newBuffer, const Element& element) :
|
||||
_buffer(newBuffer),
|
||||
_offset(0),
|
||||
_size(newBuffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
TextureView(const BufferPointer& buffer, const Element& element) :
|
||||
_buffer(buffer),
|
||||
_offset(0),
|
||||
_size(buffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
TextureView(const BufferPointer& buffer, Size offset, Size size, const Element& element) :
|
||||
_buffer(buffer),
|
||||
_offset(offset),
|
||||
_size(size),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
~TextureView() {}
|
||||
TextureView(const TextureView& view) = default;
|
||||
TextureView& operator=(const TextureView& view) = default;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
327
libraries/gpu/src/gpu/Texture.cpp
Executable file
327
libraries/gpu/src/gpu/Texture.cpp
Executable file
|
@ -0,0 +1,327 @@
|
|||
//
|
||||
// Texture.cpp
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 1/17/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Texture.h"
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) :
|
||||
_sysmem(size, bytes),
|
||||
_format(format) {
|
||||
}
|
||||
|
||||
Texture::Pixels::~Pixels() {
|
||||
}
|
||||
|
||||
void Texture::Storage::assignTexture(Texture* texture) {
|
||||
_texture = texture;
|
||||
}
|
||||
|
||||
Stamp Texture::Storage::getStamp(uint16 level) const {
|
||||
PixelsPointer mip = getMip(level);
|
||||
if (mip) {
|
||||
return mip->_sysmem.getStamp();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Texture::Storage::reset() {
|
||||
_mips.clear();
|
||||
}
|
||||
|
||||
Texture::PixelsPointer Texture::Storage::editMip(uint16 level) {
|
||||
if (level < _mips.size()) {
|
||||
return _mips[level];
|
||||
}
|
||||
return PixelsPointer();
|
||||
}
|
||||
|
||||
const Texture::PixelsPointer Texture::Storage::getMip(uint16 level) const {
|
||||
if (level < _mips.size()) {
|
||||
return _mips[level];
|
||||
}
|
||||
return PixelsPointer();
|
||||
}
|
||||
|
||||
bool Texture::Storage::isMipAvailable(uint16 level) const {
|
||||
PixelsPointer mip = getMip(level);
|
||||
return (mip && mip->_sysmem.getSize());
|
||||
}
|
||||
|
||||
bool Texture::Storage::allocateMip(uint16 level) {
|
||||
bool changed = false;
|
||||
if (level >= _mips.size()) {
|
||||
_mips.resize(level+1, PixelsPointer());
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (!_mips[level]) {
|
||||
_mips[level] = PixelsPointer(new Pixels());
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool Texture::Storage::assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes) {
|
||||
// Ok we should be able to do that...
|
||||
allocateMip(level);
|
||||
_mips[level]->_format = format;
|
||||
Size allocated = _mips[level]->_sysmem.setData(size, bytes);
|
||||
return allocated == size;
|
||||
}
|
||||
|
||||
Texture* Texture::create1D(const Element& texelFormat, uint16 width) {
|
||||
return create(TEX_1D, texelFormat, width, 1, 1, 1, 1);
|
||||
}
|
||||
|
||||
Texture* Texture::create2D(const Element& texelFormat, uint16 width, uint16 height) {
|
||||
return create(TEX_2D, texelFormat, width, height, 1, 1, 1);
|
||||
}
|
||||
|
||||
Texture* Texture::create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth) {
|
||||
return create(TEX_3D, texelFormat, width, height, depth, 1, 1);
|
||||
}
|
||||
|
||||
Texture* Texture::createCube(const Element& texelFormat, uint16 width) {
|
||||
return create(TEX_CUBE, texelFormat, width, width, 1, 1, 1);
|
||||
}
|
||||
|
||||
Texture* Texture::create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices)
|
||||
{
|
||||
Texture* tex = new Texture();
|
||||
tex->_storage.reset(new Storage());
|
||||
tex->_storage->_texture = tex;
|
||||
tex->_type = type;
|
||||
tex->_maxMip = 0;
|
||||
tex->resize(type, texelFormat, width, height, depth, numSamples, numSlices);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
Texture* Texture::createFromStorage(Storage* storage) {
|
||||
Texture* tex = new Texture();
|
||||
tex->_storage.reset(storage);
|
||||
storage->assignTexture(tex);
|
||||
return tex;
|
||||
}
|
||||
|
||||
Texture::Texture():
|
||||
Resource(),
|
||||
_storage(),
|
||||
_stamp(0),
|
||||
_size(0),
|
||||
_width(1),
|
||||
_height(1),
|
||||
_depth(1),
|
||||
_numSamples(1),
|
||||
_numSlices(1),
|
||||
_maxMip(0),
|
||||
_type(TEX_1D),
|
||||
_autoGenerateMips(false),
|
||||
_defined(false)
|
||||
{
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
}
|
||||
|
||||
Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices) {
|
||||
if (width && height && depth && numSamples && numSlices) {
|
||||
bool changed = false;
|
||||
|
||||
if ( _type != type) {
|
||||
_type = type;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (_numSlices != numSlices) {
|
||||
_numSlices = numSlices;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
numSamples = evalNumSamplesUsed(numSamples);
|
||||
if ((_type >= TEX_2D) && (_numSamples != numSamples)) {
|
||||
_numSamples = numSamples;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (_width != width) {
|
||||
_width = width;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if ((_type >= TEX_2D) && (_height != height)) {
|
||||
_height = height;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
if ((_type >= TEX_3D) && (_depth != depth)) {
|
||||
_depth = depth;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Evaluate the new size with the new format
|
||||
const int DIM_SIZE[] = {1, 1, 1, 6};
|
||||
int size = DIM_SIZE[_type] *_width * _height * _depth * _numSamples * texelFormat.getSize();
|
||||
|
||||
// If size change then we need to reset
|
||||
if (changed || (size != getSize())) {
|
||||
_size = size;
|
||||
_storage->reset();
|
||||
_stamp++;
|
||||
}
|
||||
|
||||
// TexelFormat might have change, but it's mostly interpretation
|
||||
if (texelFormat != _texelFormat) {
|
||||
_texelFormat = texelFormat;
|
||||
_stamp++;
|
||||
}
|
||||
|
||||
// Here the Texture has been fully defined from the gpu point of view (size and format)
|
||||
_defined = true;
|
||||
} else {
|
||||
_stamp++;
|
||||
}
|
||||
|
||||
return _size;
|
||||
}
|
||||
|
||||
Texture::Size Texture::resize1D(uint16 width, uint16 numSamples) {
|
||||
return resize(TEX_1D, getTexelFormat(), width, 1, 1, numSamples, 1);
|
||||
}
|
||||
Texture::Size Texture::resize2D(uint16 width, uint16 height, uint16 numSamples) {
|
||||
return resize(TEX_2D, getTexelFormat(), width, height, 1, numSamples, 1);
|
||||
}
|
||||
Texture::Size Texture::resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples) {
|
||||
return resize(TEX_3D, getTexelFormat(), width, height, depth, numSamples, 1);
|
||||
}
|
||||
Texture::Size Texture::resizeCube(uint16 width, uint16 numSamples) {
|
||||
return resize(TEX_CUBE, getTexelFormat(), width, 1, 1, numSamples, 1);
|
||||
}
|
||||
|
||||
Texture::Size Texture::reformat(const Element& texelFormat) {
|
||||
return resize(_type, texelFormat, getWidth(), getHeight(), getDepth(), getNumSamples(), getNumSlices());
|
||||
}
|
||||
|
||||
bool Texture::isColorRenderTarget() const {
|
||||
return (_texelFormat.getSemantic() == gpu::RGBA);
|
||||
}
|
||||
|
||||
bool Texture::isDepthStencilRenderTarget() const {
|
||||
return (_texelFormat.getSemantic() == gpu::DEPTH) || (_texelFormat.getSemantic() == gpu::DEPTH_STENCIL);
|
||||
}
|
||||
|
||||
uint16 Texture::evalDimNumMips(uint16 size) {
|
||||
double largerDim = size;
|
||||
double val = log(largerDim)/log(2.0);
|
||||
return 1 + (uint16) val;
|
||||
}
|
||||
|
||||
// The number mips that the texture could have if all existed
|
||||
// = log2(max(width, height, depth))
|
||||
uint16 Texture::evalNumMips() const {
|
||||
double largerDim = std::max(std::max(_width, _height), _depth);
|
||||
double val = log(largerDim)/log(2.0);
|
||||
return 1 + (uint16) val;
|
||||
}
|
||||
|
||||
uint16 Texture::maxMip() const {
|
||||
return _maxMip;
|
||||
}
|
||||
|
||||
bool Texture::assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes) {
|
||||
// Check that level accessed make sense
|
||||
if (level != 0) {
|
||||
if (_autoGenerateMips) {
|
||||
return false;
|
||||
}
|
||||
if (level >= evalNumMips()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// THen check that the mem buffer passed make sense with its format
|
||||
if (size == evalStoredMipSize(level, format)) {
|
||||
_storage->assignMipData(level, format, size, bytes);
|
||||
_stamp++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 Texture::autoGenerateMips(uint16 maxMip) {
|
||||
_autoGenerateMips = true;
|
||||
_maxMip = std::min((uint16) (evalNumMips() - 1), maxMip);
|
||||
_stamp++;
|
||||
return _maxMip;
|
||||
}
|
||||
|
||||
uint16 Texture::getStoredMipWidth(uint16 level) const {
|
||||
PixelsPointer mip = accessStoredMip(level);
|
||||
if (mip && mip->_sysmem.getSize()) {
|
||||
return evalMipWidth(level);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 Texture::getStoredMipHeight(uint16 level) const {
|
||||
PixelsPointer mip = accessStoredMip(level);
|
||||
if (mip && mip->_sysmem.getSize()) {
|
||||
return evalMipHeight(level);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 Texture::getStoredMipDepth(uint16 level) const {
|
||||
PixelsPointer mip = accessStoredMip(level);
|
||||
if (mip && mip->_sysmem.getSize()) {
|
||||
return evalMipDepth(level);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Texture::getStoredMipNumTexels(uint16 level) const {
|
||||
PixelsPointer mip = accessStoredMip(level);
|
||||
if (mip && mip->_sysmem.getSize()) {
|
||||
return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Texture::getStoredMipSize(uint16 level) const {
|
||||
PixelsPointer mip = accessStoredMip(level);
|
||||
if (mip && mip->_sysmem.getSize()) {
|
||||
return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 Texture::evalNumSamplesUsed(uint16 numSamplesTried) {
|
||||
uint16 sample = numSamplesTried;
|
||||
if (numSamplesTried <= 1)
|
||||
sample = 1;
|
||||
else if (numSamplesTried < 4)
|
||||
sample = 2;
|
||||
else if (numSamplesTried < 8)
|
||||
sample = 4;
|
||||
else if (numSamplesTried < 16)
|
||||
sample = 8;
|
||||
else
|
||||
sample = 8;
|
||||
|
||||
return sample;
|
||||
}
|
255
libraries/gpu/src/gpu/Texture.h
Executable file
255
libraries/gpu/src/gpu/Texture.h
Executable file
|
@ -0,0 +1,255 @@
|
|||
//
|
||||
// Texture.h
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 1/16/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_gpu_Texture_h
|
||||
#define hifi_gpu_Texture_h
|
||||
|
||||
#include "Resource.h"
|
||||
#include <memory>
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class Texture : public Resource {
|
||||
public:
|
||||
|
||||
class Pixels {
|
||||
public:
|
||||
Pixels() {}
|
||||
Pixels(const Pixels& pixels) = default;
|
||||
Pixels(const Element& format, Size size, const Byte* bytes);
|
||||
~Pixels();
|
||||
|
||||
Sysmem _sysmem;
|
||||
Element _format;
|
||||
};
|
||||
typedef QSharedPointer< Pixels > PixelsPointer;
|
||||
|
||||
class Storage {
|
||||
public:
|
||||
Storage() {}
|
||||
virtual ~Storage() {}
|
||||
virtual void reset();
|
||||
virtual PixelsPointer editMip(uint16 level);
|
||||
virtual const PixelsPointer getMip(uint16 level) const;
|
||||
virtual Stamp getStamp(uint16 level) const;
|
||||
virtual bool allocateMip(uint16 level);
|
||||
virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||
virtual bool isMipAvailable(uint16 level) const;
|
||||
|
||||
protected:
|
||||
Texture* _texture;
|
||||
std::vector<PixelsPointer> _mips;
|
||||
|
||||
virtual void assignTexture(Texture* tex);
|
||||
|
||||
friend class Texture;
|
||||
};
|
||||
|
||||
enum Type {
|
||||
TEX_1D = 0,
|
||||
TEX_2D,
|
||||
TEX_3D,
|
||||
TEX_CUBE,
|
||||
};
|
||||
|
||||
static Texture* create1D(const Element& texelFormat, uint16 width);
|
||||
static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height);
|
||||
static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth);
|
||||
static Texture* createCube(const Element& texelFormat, uint16 width);
|
||||
|
||||
static Texture* createFromStorage(Storage* storage);
|
||||
|
||||
Texture(const Texture& buf); // deep copy of the sysmem texture
|
||||
Texture& operator=(const Texture& buf); // deep copy of the sysmem texture
|
||||
~Texture();
|
||||
|
||||
const Stamp getStamp() const { return _stamp; }
|
||||
const Stamp getDataStamp(uint16 level = 0) const { return _storage->getStamp(level); }
|
||||
|
||||
// The size in bytes of data stored in the texture
|
||||
Size getSize() const { return _size; }
|
||||
|
||||
// Resize, unless auto mips mode would destroy all the sub mips
|
||||
Size resize1D(uint16 width, uint16 numSamples);
|
||||
Size resize2D(uint16 width, uint16 height, uint16 numSamples);
|
||||
Size resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples);
|
||||
Size resizeCube(uint16 width, uint16 numSamples);
|
||||
|
||||
// Reformat, unless auto mips mode would destroy all the sub mips
|
||||
Size reformat(const Element& texelFormat);
|
||||
|
||||
// Size and format
|
||||
Type getType() const { return _type; }
|
||||
|
||||
bool isColorRenderTarget() const;
|
||||
bool isDepthStencilRenderTarget() const;
|
||||
|
||||
const Element& getTexelFormat() const { return _texelFormat; }
|
||||
bool hasBorder() const { return false; }
|
||||
|
||||
uint16 getWidth() const { return _width; }
|
||||
uint16 getHeight() const { return _height; }
|
||||
uint16 getDepth() const { return _depth; }
|
||||
|
||||
uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); }
|
||||
uint32 getNumTexels() const { return _width * _height * _depth; }
|
||||
|
||||
uint16 getNumSlices() const { return _numSlices; }
|
||||
uint16 getNumSamples() const { return _numSamples; }
|
||||
|
||||
// NumSamples can only have certain values based on the hw
|
||||
static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
|
||||
|
||||
// Mips size evaluation
|
||||
|
||||
// The number mips that a dimension could haves
|
||||
// = 1 + log2(size)
|
||||
static uint16 evalDimNumMips(uint16 size);
|
||||
|
||||
// The number mips that the texture could have if all existed
|
||||
// = 1 + log2(max(width, height, depth))
|
||||
uint16 evalNumMips() const;
|
||||
|
||||
// Eval the size that the mips level SHOULD have
|
||||
// not the one stored in the Texture
|
||||
uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); }
|
||||
uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); }
|
||||
uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); }
|
||||
uint32 evalMipNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); }
|
||||
uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); }
|
||||
uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); }
|
||||
|
||||
uint32 evalTotalSize() const {
|
||||
uint32 size = 0;
|
||||
uint16 minMipLevel = 0;
|
||||
uint16 maxMipLevel = maxMip();
|
||||
for (uint16 l = minMipLevel; l <= maxMipLevel; l++) {
|
||||
size += evalMipSize(l);
|
||||
}
|
||||
return size * getNumSlices();
|
||||
}
|
||||
|
||||
// max mip is in the range [ 1 if no sub mips, log2(max(width, height, depth))]
|
||||
// if autoGenerateMip is on => will provide the maxMIp level specified
|
||||
// else provide the deepest mip level provided through assignMip
|
||||
uint16 maxMip() const;
|
||||
|
||||
// Generate the mips automatically
|
||||
// But the sysmem version is not available
|
||||
// Only works for the standard formats
|
||||
// Specify the maximum Mip level available
|
||||
// 0 is the default one
|
||||
// 1 is the first level
|
||||
// ...
|
||||
// nbMips - 1 is the last mip level
|
||||
//
|
||||
// If -1 then all the mips are generated
|
||||
//
|
||||
// Return the totalnumber of mips that will be available
|
||||
uint16 autoGenerateMips(uint16 maxMip);
|
||||
bool isAutogenerateMips() const { return _autoGenerateMips; }
|
||||
|
||||
// Managing Storage and mips
|
||||
|
||||
// Manually allocate the mips down until the specified maxMip
|
||||
// this is just allocating the sysmem version of it
|
||||
// in case autoGen is on, this doesn't allocate
|
||||
// Explicitely assign mip data for a certain level
|
||||
// If Bytes is NULL then simply allocate the space so mip sysmem can be accessed
|
||||
bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||
|
||||
// Access the the sub mips
|
||||
bool isStoredMipAvailable(uint16 level) const { return _storage->isMipAvailable(level); }
|
||||
const PixelsPointer accessStoredMip(uint16 level) const { return _storage->getMip(level); }
|
||||
|
||||
// access sizes for the stored mips
|
||||
uint16 getStoredMipWidth(uint16 level) const;
|
||||
uint16 getStoredMipHeight(uint16 level) const;
|
||||
uint16 getStoredMipDepth(uint16 level) const;
|
||||
uint32 getStoredMipNumTexels(uint16 level) const;
|
||||
uint32 getStoredMipSize(uint16 level) const;
|
||||
|
||||
bool isDefined() const { return _defined; }
|
||||
|
||||
protected:
|
||||
std::unique_ptr< Storage > _storage;
|
||||
|
||||
Stamp _stamp;
|
||||
|
||||
uint32 _size;
|
||||
Element _texelFormat;
|
||||
|
||||
uint16 _width;
|
||||
uint16 _height;
|
||||
uint16 _depth;
|
||||
|
||||
uint16 _numSamples;
|
||||
uint16 _numSlices;
|
||||
|
||||
uint16 _maxMip;
|
||||
|
||||
Type _type;
|
||||
bool _autoGenerateMips;
|
||||
bool _defined;
|
||||
|
||||
static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices);
|
||||
Texture();
|
||||
|
||||
Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices);
|
||||
|
||||
mutable GPUObject* _gpuObject = NULL;
|
||||
|
||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||
|
||||
friend class Backend;
|
||||
};
|
||||
|
||||
typedef QSharedPointer<Texture> TexturePointer;
|
||||
typedef std::vector< TexturePointer > Textures;
|
||||
|
||||
|
||||
// TODO: For now TextureView works with Buffer as a place holder for the Texture.
|
||||
// The overall logic should be about the same except that the Texture will be a real GL Texture under the hood
|
||||
class TextureView {
|
||||
public:
|
||||
typedef Resource::Size Size;
|
||||
|
||||
TexturePointer _texture = TexturePointer(NULL);
|
||||
uint16 _subresource = 0;
|
||||
Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
|
||||
|
||||
TextureView() {};
|
||||
|
||||
TextureView(const Element& element) :
|
||||
_element(element)
|
||||
{};
|
||||
|
||||
// create the TextureView and own the Texture
|
||||
TextureView(Texture* newTexture, const Element& element) :
|
||||
_texture(newTexture),
|
||||
_subresource(0),
|
||||
_element(element)
|
||||
{};
|
||||
TextureView(const TexturePointer& texture, const Element& element) :
|
||||
_texture(texture),
|
||||
_subresource(0),
|
||||
_element(element)
|
||||
{};
|
||||
~TextureView() {}
|
||||
TextureView(const TextureView& view) = default;
|
||||
TextureView& operator=(const TextureView& view) = default;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -19,11 +19,11 @@
|
|||
#include <QMetaType>
|
||||
#include <QPushButton>
|
||||
#include <QScriptEngine>
|
||||
#include <QSettings>
|
||||
#include <QVBoxLayout>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <Settings.h>
|
||||
|
||||
#include "MetavoxelUtil.h"
|
||||
#include "ScriptCache.h"
|
||||
|
@ -485,6 +485,10 @@ void QColorEditor::selectColor() {
|
|||
}
|
||||
}
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QStringList> editorURLs("editorURLs");
|
||||
}
|
||||
|
||||
QUrlEditor::QUrlEditor(QWidget* parent) :
|
||||
QComboBox(parent) {
|
||||
|
||||
|
@ -492,7 +496,7 @@ QUrlEditor::QUrlEditor(QWidget* parent) :
|
|||
setInsertPolicy(InsertAtTop);
|
||||
|
||||
// populate initial URL list from settings
|
||||
addItems(QSettings().value("editorURLs").toStringList());
|
||||
addItems(SettingHandles::editorURLs.get());
|
||||
|
||||
connect(this, SIGNAL(activated(const QString&)), SLOT(updateURL(const QString&)));
|
||||
connect(model(), SIGNAL(rowsInserted(const QModelIndex&,int,int)), SLOT(updateSettings()));
|
||||
|
@ -512,7 +516,7 @@ void QUrlEditor::updateSettings() {
|
|||
for (int i = 0, size = qMin(MAX_STORED_URLS, count()); i < size; i++) {
|
||||
urls.append(itemText(i));
|
||||
}
|
||||
QSettings().setValue("editorURLs", urls);
|
||||
SettingHandles::editorURLs.set(urls);
|
||||
}
|
||||
|
||||
BaseVec3Editor::BaseVec3Editor(QWidget* parent) : QWidget(parent) {
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
#include <QItemEditorFactory>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
#include <QThread>
|
||||
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include <GeometryUtil.h>
|
||||
#include <Settings.h>
|
||||
|
||||
#include "MetavoxelData.h"
|
||||
#include "Spanner.h"
|
||||
|
@ -58,6 +58,10 @@ static QItemEditorCreatorBase* heightfieldColorEditorCreator = createHeightfield
|
|||
const float DEFAULT_PLACEMENT_GRANULARITY = 0.01f;
|
||||
const float DEFAULT_VOXELIZATION_GRANULARITY = powf(2.0f, -3.0f);
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QString> heightfieldDir("heightDir", QString());
|
||||
}
|
||||
|
||||
Spanner::Spanner() :
|
||||
_renderer(NULL),
|
||||
_placementGranularity(DEFAULT_PLACEMENT_GRANULARITY),
|
||||
|
@ -610,13 +614,13 @@ static int getHeightfieldSize(int size) {
|
|||
}
|
||||
|
||||
void HeightfieldHeightEditor::select() {
|
||||
QSettings settings;
|
||||
QString result = QFileDialog::getOpenFileName(this, "Select Height Image", settings.value("heightDir").toString(),
|
||||
"Images (*.png *.jpg *.bmp *.raw *.mdr)");
|
||||
QString result = QFileDialog::getOpenFileName(this, "Select Height Image",
|
||||
SettingHandles::heightfieldDir.get(),
|
||||
"Images (*.png *.jpg *.bmp *.raw *.mdr)");
|
||||
if (result.isNull()) {
|
||||
return;
|
||||
}
|
||||
settings.setValue("heightDir", QFileInfo(result).path());
|
||||
SettingHandles::heightfieldDir.set(QFileInfo(result).path());
|
||||
const quint16 CONVERSION_OFFSET = 1;
|
||||
QString lowerResult = result.toLower();
|
||||
bool isMDR = lowerResult.endsWith(".mdr");
|
||||
|
@ -880,13 +884,13 @@ void HeightfieldColorEditor::setColor(const HeightfieldColorPointer& color) {
|
|||
}
|
||||
|
||||
void HeightfieldColorEditor::select() {
|
||||
QSettings settings;
|
||||
QString result = QFileDialog::getOpenFileName(this, "Select Color Image", settings.value("heightDir").toString(),
|
||||
QString result = QFileDialog::getOpenFileName(this, "Select Color Image",
|
||||
SettingHandles::heightfieldDir.get(),
|
||||
"Images (*.png *.jpg *.bmp)");
|
||||
if (result.isNull()) {
|
||||
return;
|
||||
}
|
||||
settings.setValue("heightDir", QFileInfo(result).path());
|
||||
SettingHandles::heightfieldDir.get(QFileInfo(result).path());
|
||||
QImage image;
|
||||
if (!image.load(result)) {
|
||||
QMessageBox::warning(this, "Invalid Image", "The selected image could not be read.");
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
|
||||
#include "gpu/Resource.h"
|
||||
#include "gpu/Texture.h"
|
||||
|
||||
namespace model {
|
||||
typedef gpu::BufferView UniformBufferView;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <qthread.h>
|
||||
|
||||
#include <Settings.h>
|
||||
|
||||
#include "NodeList.h"
|
||||
#include "PacketHeaders.h"
|
||||
#include "RSAKeypairGenerator.h"
|
||||
|
@ -88,11 +90,9 @@ void AccountManager::logout() {
|
|||
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
||||
|
||||
if (_shouldPersistToSettingsFile) {
|
||||
QSettings settings;
|
||||
settings.beginGroup(ACCOUNTS_GROUP);
|
||||
|
||||
QString keyURLString(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE));
|
||||
settings.remove(keyURLString);
|
||||
QStringList path = QStringList() << ACCOUNTS_GROUP << keyURLString;
|
||||
SettingHandles::SettingHandle<DataServerAccountInfo>(path).remove();
|
||||
|
||||
qDebug() << "Removed account info for" << _authURL << "from in-memory accounts and .ini file";
|
||||
} else {
|
||||
|
@ -127,13 +127,13 @@ void AccountManager::setAuthURL(const QUrl& authURL) {
|
|||
|
||||
if (_shouldPersistToSettingsFile) {
|
||||
// check if there are existing access tokens to load from settings
|
||||
QSettings settings;
|
||||
Settings settings;
|
||||
settings.beginGroup(ACCOUNTS_GROUP);
|
||||
|
||||
foreach(const QString& key, settings.allKeys()) {
|
||||
// take a key copy to perform the double slash replacement
|
||||
QString keyCopy(key);
|
||||
QUrl keyURL(keyCopy.replace("slashslash", "//"));
|
||||
QUrl keyURL(keyCopy.replace(DOUBLE_SLASH_SUBSTITUTE, "//"));
|
||||
|
||||
if (keyURL == _authURL) {
|
||||
// pull out the stored access token and store it in memory
|
||||
|
@ -337,10 +337,9 @@ void AccountManager::passErrorToCallback(QNetworkReply* requestReply) {
|
|||
void AccountManager::persistAccountToSettings() {
|
||||
if (_shouldPersistToSettingsFile) {
|
||||
// store this access token into the local settings
|
||||
QSettings localSettings;
|
||||
localSettings.beginGroup(ACCOUNTS_GROUP);
|
||||
localSettings.setValue(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
|
||||
QVariant::fromValue(_accountInfo));
|
||||
QString keyURLString(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE));
|
||||
QStringList path = QStringList() << ACCOUNTS_GROUP << keyURLString;
|
||||
SettingHandles::SettingHandle<QVariant>(path).set(QVariant::fromValue(_accountInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,25 +9,36 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <qdebug.h>
|
||||
#include <qjsondocument.h>
|
||||
#include <qregexp.h>
|
||||
#include <qstringlist.h>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <Settings.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "NodeList.h"
|
||||
|
||||
#include "AddressManager.h"
|
||||
|
||||
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
|
||||
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<QUrl> currentAddress(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP
|
||||
<< "address",
|
||||
QUrl());
|
||||
}
|
||||
|
||||
AddressManager::AddressManager() :
|
||||
_rootPlaceName(),
|
||||
_rootPlaceID(),
|
||||
_positionGetter(NULL),
|
||||
_orientationGetter(NULL)
|
||||
{
|
||||
|
||||
connect(qApp, &QCoreApplication::aboutToQuit, this, &AddressManager::storeCurrentAddress);
|
||||
}
|
||||
|
||||
bool AddressManager::isConnected() {
|
||||
|
@ -44,25 +55,16 @@ const QUrl AddressManager::currentAddress() const {
|
|||
return hifiURL;
|
||||
}
|
||||
|
||||
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
|
||||
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
|
||||
|
||||
void AddressManager::loadSettings(const QString& lookupString) {
|
||||
if (lookupString.isEmpty()) {
|
||||
QSettings settings;
|
||||
settings.beginGroup(ADDRESS_MANAGER_SETTINGS_GROUP);
|
||||
handleLookupString(settings.value(SETTINGS_CURRENT_ADDRESS_KEY).toString());
|
||||
handleLookupString(SettingHandles::currentAddress.get().toString());
|
||||
} else {
|
||||
handleLookupString(lookupString);
|
||||
}
|
||||
}
|
||||
|
||||
void AddressManager::storeCurrentAddress() {
|
||||
QSettings settings;
|
||||
|
||||
settings.beginGroup(ADDRESS_MANAGER_SETTINGS_GROUP);
|
||||
settings.setValue(SETTINGS_CURRENT_ADDRESS_KEY, currentAddress());
|
||||
settings.endGroup();
|
||||
SettingHandles::currentAddress.set(currentAddress());
|
||||
}
|
||||
|
||||
const QString AddressManager::currentPath(bool withOrientation) const {
|
||||
|
@ -430,3 +432,11 @@ void AddressManager::goToUser(const QString& username) {
|
|||
QNetworkAccessManager::GetOperation,
|
||||
apiCallbackParameters());
|
||||
}
|
||||
|
||||
void AddressManager::copyAddress() {
|
||||
QApplication::clipboard()->setText(currentAddress().toString());
|
||||
}
|
||||
|
||||
void AddressManager::copyPath() {
|
||||
QApplication::clipboard()->setText(currentPath());
|
||||
}
|
||||
|
|
|
@ -61,6 +61,9 @@ public slots:
|
|||
|
||||
void storeCurrentAddress();
|
||||
|
||||
void copyAddress();
|
||||
void copyPath();
|
||||
|
||||
signals:
|
||||
void lookupResultsFinished();
|
||||
void lookupResultIsOffline();
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtNetwork/QHostAddress>
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QDebug>
|
||||
|
||||
#include <PacketHeaders.h>
|
||||
|
@ -209,9 +209,9 @@ JurisdictionMap::Area JurisdictionMap::isMyJurisdiction(const unsigned char* nod
|
|||
|
||||
|
||||
bool JurisdictionMap::readFromFile(const char* filename) {
|
||||
QString settingsFile(filename);
|
||||
QSettings settings(settingsFile, QSettings::IniFormat);
|
||||
QString rootCode = settings.value("root","00").toString();
|
||||
QString settingsFile(filename);
|
||||
QSettings settings(settingsFile, QSettings::IniFormat);
|
||||
QString rootCode = settings.value("root","00").toString();
|
||||
qDebug() << "rootCode=" << rootCode;
|
||||
|
||||
_rootOctalCode = hexStringToOctalCode(rootCode);
|
||||
|
|
|
@ -9,36 +9,29 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <PacketHeaders.h>
|
||||
//#include <SharedUtil.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <Settings.h>
|
||||
|
||||
#include "OctreeConstants.h"
|
||||
#include "OctreeQuery.h"
|
||||
|
||||
OctreeQuery::OctreeQuery() :
|
||||
NodeData(),
|
||||
_cameraPosition(0,0,0),
|
||||
_cameraOrientation(),
|
||||
_cameraFov(0.0f),
|
||||
_cameraAspectRatio(0.0f),
|
||||
_cameraNearClip(0.0f),
|
||||
_cameraFarClip(0.0f),
|
||||
_wantColor(true),
|
||||
_wantDelta(true),
|
||||
_wantLowResMoving(true),
|
||||
_wantOcclusionCulling(false), // disabled by default
|
||||
_wantCompression(false), // disabled by default
|
||||
_maxOctreePPS(DEFAULT_MAX_OCTREE_PPS),
|
||||
_octreeElementSizeScale(DEFAULT_OCTREE_SIZE_SCALE)
|
||||
{
|
||||
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
|
||||
}
|
||||
|
||||
OctreeQuery::~OctreeQuery() {
|
||||
// nothing to do
|
||||
OctreeQuery::OctreeQuery() {
|
||||
_maxOctreePPS = SettingHandles::maxOctreePacketsPerSecond.get();
|
||||
}
|
||||
|
||||
void OctreeQuery::setMaxOctreePacketsPerSecond(int maxOctreePPS) {
|
||||
if (maxOctreePPS != _maxOctreePPS) {
|
||||
_maxOctreePPS = maxOctreePPS;
|
||||
SettingHandles::maxOctreePacketsPerSecond.set(_maxOctreePPS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class OctreeQuery : public NodeData {
|
|||
|
||||
public:
|
||||
OctreeQuery();
|
||||
virtual ~OctreeQuery();
|
||||
virtual ~OctreeQuery() {}
|
||||
|
||||
int getBroadcastData(unsigned char* destinationBuffer);
|
||||
int parseData(const QByteArray& packet);
|
||||
|
@ -86,29 +86,29 @@ public slots:
|
|||
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
|
||||
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
|
||||
void setWantCompression(bool wantCompression) { _wantCompression = wantCompression; }
|
||||
void setMaxOctreePacketsPerSecond(int maxOctreePPS) { _maxOctreePPS = maxOctreePPS; }
|
||||
void setMaxOctreePacketsPerSecond(int maxOctreePPS);
|
||||
void setOctreeSizeScale(float octreeSizeScale) { _octreeElementSizeScale = octreeSizeScale; }
|
||||
void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _boundaryLevelAdjust = boundaryLevelAdjust; }
|
||||
|
||||
protected:
|
||||
// camera details for the avatar
|
||||
glm::vec3 _cameraPosition;
|
||||
glm::quat _cameraOrientation;
|
||||
float _cameraFov;
|
||||
float _cameraAspectRatio;
|
||||
float _cameraNearClip;
|
||||
float _cameraFarClip;
|
||||
glm::vec3 _cameraEyeOffsetPosition;
|
||||
glm::vec3 _cameraPosition = glm::vec3(0.0f);
|
||||
glm::quat _cameraOrientation = glm::quat();
|
||||
float _cameraFov = 0.0f;
|
||||
float _cameraAspectRatio = 0.0f;
|
||||
float _cameraNearClip = 0.0f;
|
||||
float _cameraFarClip = 0.0f;
|
||||
glm::vec3 _cameraEyeOffsetPosition = glm::vec3(0.0f);
|
||||
|
||||
// octree server sending items
|
||||
bool _wantColor;
|
||||
bool _wantDelta;
|
||||
bool _wantLowResMoving;
|
||||
bool _wantOcclusionCulling;
|
||||
bool _wantCompression;
|
||||
int _maxOctreePPS;
|
||||
float _octreeElementSizeScale; /// used for LOD calculations
|
||||
int _boundaryLevelAdjust; /// used for LOD calculations
|
||||
bool _wantColor = true;
|
||||
bool _wantDelta = true;
|
||||
bool _wantLowResMoving = true;
|
||||
bool _wantOcclusionCulling = false;
|
||||
bool _wantCompression = false;
|
||||
int _maxOctreePPS = DEFAULT_MAX_OCTREE_PPS;
|
||||
float _octreeElementSizeScale = DEFAULT_OCTREE_SIZE_SCALE; /// used for LOD calculations
|
||||
int _boundaryLevelAdjust = 0; /// used for LOD calculations
|
||||
|
||||
private:
|
||||
// privatize the copy constructor and assignment operator so they cannot be called
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <Settings.h>
|
||||
|
||||
#include "GeometryUtil.h"
|
||||
#include "SharedUtil.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
@ -24,38 +26,34 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
ViewFrustum::ViewFrustum() :
|
||||
_position(0,0,0),
|
||||
_positionVoxelScale(0,0,0),
|
||||
_orientation(),
|
||||
_direction(IDENTITY_FRONT),
|
||||
_up(IDENTITY_UP),
|
||||
_right(IDENTITY_RIGHT),
|
||||
_orthographic(false),
|
||||
_width(1.0f),
|
||||
_height(1.0f),
|
||||
_fieldOfView(0.0),
|
||||
_aspectRatio(1.0f),
|
||||
_nearClip(DEFAULT_NEAR_CLIP),
|
||||
_farClip(DEFAULT_FAR_CLIP),
|
||||
_focalLength(0.25f),
|
||||
_keyholeRadius(DEFAULT_KEYHOLE_RADIUS),
|
||||
_farTopLeft(0,0,0),
|
||||
_farTopRight(0,0,0),
|
||||
_farBottomLeft(0,0,0),
|
||||
_farBottomRight(0,0,0),
|
||||
_nearTopLeft(0,0,0),
|
||||
_nearTopRight(0,0,0),
|
||||
_nearBottomLeft(0,0,0),
|
||||
_nearBottomRight(0,0,0)
|
||||
{
|
||||
namespace SettingHandles {
|
||||
const SettingHandle<float> fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
|
||||
const SettingHandle<float> realWorldFieldOfView("realWorldFieldOfView", DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES);
|
||||
}
|
||||
|
||||
ViewFrustum::ViewFrustum() {
|
||||
_fieldOfView = SettingHandles::fieldOfView.get();
|
||||
_realWorldFieldOfView = SettingHandles::realWorldFieldOfView.get();
|
||||
}
|
||||
|
||||
void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) {
|
||||
_orientation = orientationAsQuaternion;
|
||||
_right = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_RIGHT, 0.0f));
|
||||
_up = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_UP, 0.0f));
|
||||
_direction = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_FRONT, 0.0f));
|
||||
_right = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_RIGHT, 0.0f));
|
||||
_up = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_UP, 0.0f));
|
||||
_direction = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_FRONT, 0.0f));
|
||||
}
|
||||
|
||||
void ViewFrustum::setFieldOfView(float f) {
|
||||
if (f != _fieldOfView) {
|
||||
_fieldOfView = f;
|
||||
SettingHandles::fieldOfView.set(f);
|
||||
}
|
||||
}
|
||||
void ViewFrustum::setRealWorldFieldOfView(float realWorldFieldOfView) {
|
||||
if (realWorldFieldOfView != _realWorldFieldOfView) {
|
||||
_realWorldFieldOfView = realWorldFieldOfView;
|
||||
SettingHandles::realWorldFieldOfView.set(realWorldFieldOfView);
|
||||
}
|
||||
}
|
||||
|
||||
// ViewFrustum::calculateViewFrustum()
|
||||
|
|
|
@ -34,6 +34,8 @@ const float DEFAULT_FAR_CLIP = TREE_SCALE;
|
|||
|
||||
class ViewFrustum {
|
||||
public:
|
||||
ViewFrustum();
|
||||
|
||||
// setters for camera attributes
|
||||
void setPosition(const glm::vec3& p) { _position = p; _positionVoxelScale = (p / (float)TREE_SCALE); }
|
||||
void setOrientation(const glm::quat& orientationAsQuaternion);
|
||||
|
@ -50,7 +52,8 @@ public:
|
|||
void setOrthographic(bool orthographic) { _orthographic = orthographic; }
|
||||
void setWidth(float width) { _width = width; }
|
||||
void setHeight(float height) { _height = height; }
|
||||
void setFieldOfView(float f) { _fieldOfView = f; }
|
||||
void setFieldOfView(float f);
|
||||
void setRealWorldFieldOfView(float realWorldFieldOfView);
|
||||
void setAspectRatio(float a) { _aspectRatio = a; }
|
||||
void setNearClip(float n) { _nearClip = n; }
|
||||
void setFarClip(float f) { _farClip = f; }
|
||||
|
@ -63,6 +66,7 @@ public:
|
|||
float getWidth() const { return _width; }
|
||||
float getHeight() const { return _height; }
|
||||
float getFieldOfView() const { return _fieldOfView; }
|
||||
float getRealWorldFieldOfView() const { return _realWorldFieldOfView; }
|
||||
float getAspectRatio() const { return _aspectRatio; }
|
||||
float getNearClip() const { return _nearClip; }
|
||||
float getFarClip() const { return _farClip; }
|
||||
|
@ -91,8 +95,6 @@ public:
|
|||
|
||||
void calculate();
|
||||
|
||||
ViewFrustum();
|
||||
|
||||
typedef enum {OUTSIDE, INTERSECT, INSIDE} location;
|
||||
|
||||
ViewFrustum::location pointInFrustum(const glm::vec3& point) const;
|
||||
|
@ -132,47 +134,52 @@ private:
|
|||
ViewFrustum::location boxInKeyhole(const AABox& box) const;
|
||||
|
||||
void calculateOrthographic();
|
||||
|
||||
|
||||
// camera location/orientation attributes
|
||||
glm::vec3 _position; // the position in TREE_SCALE
|
||||
glm::vec3 _positionVoxelScale; // the position in voxel scale
|
||||
glm::quat _orientation;
|
||||
glm::vec3 _position = glm::vec3(0.0f); // the position in TREE_SCALE
|
||||
glm::vec3 _positionVoxelScale = glm::vec3(0.0f); // the position in voxel scale
|
||||
glm::quat _orientation = glm::quat();
|
||||
|
||||
// calculated for orientation
|
||||
glm::vec3 _direction;
|
||||
glm::vec3 _up;
|
||||
glm::vec3 _right;
|
||||
glm::vec3 _direction = IDENTITY_FRONT;
|
||||
glm::vec3 _up = IDENTITY_UP;
|
||||
glm::vec3 _right = IDENTITY_RIGHT;
|
||||
|
||||
// Lens attributes
|
||||
bool _orthographic;
|
||||
float _width;
|
||||
float _height;
|
||||
float _fieldOfView; // degrees
|
||||
float _aspectRatio;
|
||||
float _nearClip;
|
||||
float _farClip;
|
||||
float _focalLength;
|
||||
glm::vec3 _eyeOffsetPosition;
|
||||
glm::quat _eyeOffsetOrientation;
|
||||
bool _orthographic = false;
|
||||
float _width = 1.0f;
|
||||
float _height = 1.0f;
|
||||
float _aspectRatio = 1.0f;
|
||||
float _nearClip = DEFAULT_NEAR_CLIP;
|
||||
float _farClip = DEFAULT_FAR_CLIP;
|
||||
float _focalLength = 0.25f;
|
||||
glm::vec3 _eyeOffsetPosition = glm::vec3(0.0f);
|
||||
glm::quat _eyeOffsetOrientation = glm::quat();
|
||||
|
||||
// in Degrees, doesn't apply to HMD like Oculus
|
||||
float _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES;
|
||||
// The actual FOV set by the user's monitor size and view distance
|
||||
float _realWorldFieldOfView = DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES;
|
||||
|
||||
|
||||
// keyhole attributes
|
||||
float _keyholeRadius;
|
||||
float _keyholeRadius = DEFAULT_KEYHOLE_RADIUS;
|
||||
AACube _keyholeBoundingCube;
|
||||
|
||||
|
||||
// Calculated values
|
||||
glm::vec3 _offsetPosition;
|
||||
glm::vec3 _offsetDirection;
|
||||
glm::vec3 _offsetUp;
|
||||
glm::vec3 _offsetRight;
|
||||
glm::vec3 _farTopLeft;
|
||||
glm::vec3 _farTopRight;
|
||||
glm::vec3 _farBottomLeft;
|
||||
glm::vec3 _farBottomRight;
|
||||
glm::vec3 _nearTopLeft;
|
||||
glm::vec3 _nearTopRight;
|
||||
glm::vec3 _nearBottomLeft;
|
||||
glm::vec3 _nearBottomRight;
|
||||
glm::vec3 _offsetPosition = glm::vec3(0.0f);
|
||||
glm::vec3 _offsetDirection = glm::vec3(0.0f);
|
||||
glm::vec3 _offsetUp = glm::vec3(0.0f);
|
||||
glm::vec3 _offsetRight = glm::vec3(0.0f);
|
||||
glm::vec3 _farTopLeft = glm::vec3(0.0f);
|
||||
glm::vec3 _farTopRight = glm::vec3(0.0f);
|
||||
glm::vec3 _farBottomLeft = glm::vec3(0.0f);
|
||||
glm::vec3 _farBottomRight = glm::vec3(0.0f);
|
||||
glm::vec3 _nearTopLeft = glm::vec3(0.0f);
|
||||
glm::vec3 _nearTopRight = glm::vec3(0.0f);
|
||||
glm::vec3 _nearBottomLeft = glm::vec3(0.0f);
|
||||
glm::vec3 _nearBottomRight = glm::vec3(0.0f);
|
||||
enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE };
|
||||
::Plane _planes[6]; // How will this be used?
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "BulletUtil.h"
|
||||
#include "EntityMotionState.h"
|
||||
#include "PhysicsEngine.h"
|
||||
#include "PhysicsHelpers.h"
|
||||
|
||||
|
||||
QSet<EntityItem*>* _outgoingEntityList;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "BulletUtil.h"
|
||||
#include "ObjectMotionState.h"
|
||||
#include "PhysicsEngine.h"
|
||||
#include "PhysicsHelpers.h"
|
||||
|
||||
const float DEFAULT_FRICTION = 0.5f;
|
||||
const float MAX_FRICTION = 10.0f;
|
||||
|
@ -107,6 +108,7 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) {
|
|||
if (_sentFrame == 0) {
|
||||
_sentPosition = bulletToGLM(_body->getWorldTransform().getOrigin());
|
||||
_sentVelocity = bulletToGLM(_body->getLinearVelocity());
|
||||
_sentRotation = bulletToGLM(_body->getWorldTransform().getRotation());
|
||||
_sentAngularVelocity = bulletToGLM(_body->getAngularVelocity());
|
||||
_sentFrame = simulationFrame;
|
||||
return false;
|
||||
|
@ -118,7 +120,8 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) {
|
|||
glm::vec3 wasAngularVelocity = _sentAngularVelocity;
|
||||
#endif
|
||||
|
||||
float dt = (float)(simulationFrame - _sentFrame) * PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||
int numFrames = simulationFrame - _sentFrame;
|
||||
float dt = (float)(numFrames) * PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||
_sentFrame = simulationFrame;
|
||||
bool isActive = _body->isActive();
|
||||
|
||||
|
@ -170,16 +173,16 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) {
|
|||
|
||||
if (glm::length2(_sentAngularVelocity) > 0.0f) {
|
||||
// compute rotation error
|
||||
_sentAngularVelocity *= powf(1.0f - _angularDamping, dt);
|
||||
|
||||
float spin = glm::length(_sentAngularVelocity);
|
||||
const float MIN_SPIN = 1.0e-4f;
|
||||
if (spin > MIN_SPIN) {
|
||||
glm::vec3 axis = _sentAngularVelocity / spin;
|
||||
_sentRotation = glm::normalize(glm::angleAxis(dt * spin, axis) * _sentRotation);
|
||||
float attenuation = powf(1.0f - _angularDamping, dt);
|
||||
_sentAngularVelocity *= attenuation;
|
||||
|
||||
// Bullet caps the effective rotation velocity inside its rotation integration step, therefore
|
||||
// we must integrate with the same algorithm and timestep in order achieve similar results.
|
||||
for (int i = 0; i < numFrames; ++i) {
|
||||
_sentRotation = glm::normalize(computeBulletRotationStep(_sentAngularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP) * _sentRotation);
|
||||
}
|
||||
}
|
||||
const float MIN_ROTATION_DOT = 0.98f;
|
||||
const float MIN_ROTATION_DOT = 0.99f; // 0.99 dot threshold coresponds to about 16 degrees of slop
|
||||
glm::quat actualRotation = bulletToGLM(worldTrans.getRotation());
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "PhysicsEngine.h"
|
||||
#include "ShapeInfoUtil.h"
|
||||
#include "PhysicsHelpers.h"
|
||||
#include "ThreadSafeDynamicsWorld.h"
|
||||
|
||||
static uint32_t _numSubsteps;
|
||||
|
@ -29,23 +30,27 @@ PhysicsEngine::~PhysicsEngine() {
|
|||
|
||||
// begin EntitySimulation overrides
|
||||
void PhysicsEngine::updateEntitiesInternal(const quint64& now) {
|
||||
// NOTE: the grand order of operations is:
|
||||
// (1) relay incoming changes
|
||||
// (2) step simulation
|
||||
// (3) synchronize outgoing motion states
|
||||
// (4) send outgoing packets
|
||||
|
||||
// this is step (4)
|
||||
QSet<ObjectMotionState*>::iterator stateItr = _outgoingPackets.begin();
|
||||
while (stateItr != _outgoingPackets.end()) {
|
||||
ObjectMotionState* state = *stateItr;
|
||||
if (state->doesNotNeedToSendUpdate()) {
|
||||
stateItr = _outgoingPackets.erase(stateItr);
|
||||
} else if (state->shouldSendUpdate(_numSubsteps)) {
|
||||
state->sendUpdate(_entityPacketSender, _numSubsteps);
|
||||
++stateItr;
|
||||
} else {
|
||||
++stateItr;
|
||||
// no need to send updates unless the physics simulation has actually stepped
|
||||
if (_lastNumSubstepsAtUpdateInternal != _numSubsteps) {
|
||||
_lastNumSubstepsAtUpdateInternal = _numSubsteps;
|
||||
// NOTE: the grand order of operations is:
|
||||
// (1) relay incoming changes
|
||||
// (2) step simulation
|
||||
// (3) synchronize outgoing motion states
|
||||
// (4) send outgoing packets
|
||||
|
||||
// this is step (4)
|
||||
QSet<ObjectMotionState*>::iterator stateItr = _outgoingPackets.begin();
|
||||
while (stateItr != _outgoingPackets.end()) {
|
||||
ObjectMotionState* state = *stateItr;
|
||||
if (state->doesNotNeedToSendUpdate()) {
|
||||
stateItr = _outgoingPackets.erase(stateItr);
|
||||
} else if (state->shouldSendUpdate(_numSubsteps)) {
|
||||
state->sendUpdate(_entityPacketSender, _numSubsteps);
|
||||
++stateItr;
|
||||
} else {
|
||||
++stateItr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue