1601 lines · 63.8 KB · C++
RawDownload
////  Menu.cpp//  interface/src////  Created by Stephen Birarda on 8/12/13.//  Copyright 2013 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 <cstdlib>  #include <QBoxLayout>#include <QColorDialog>#include <QDialogButtonBox>#include <QDoubleSpinBox>#include <QFileDialog>#include <QFormLayout>#include <QInputDialog>#include <QLineEdit>#include <QMainWindow>#include <QMenuBar>#include <QMessageBox>#include <QShortcut>#include <QSlider>#include <QUuid>#include <QHBoxLayout>#include <QDesktopServices> #include <AccountManager.h>#include <XmppClient.h>#include <UUID.h> #include "Application.h"#include "Menu.h"#include "scripting/MenuScriptingInterface.h"#include "Util.h"#include "ui/AttachmentsDialog.h"#include "ui/InfoView.h"#include "ui/MetavoxelEditor.h"#include "ui/ModelsBrowser.h"#include "ui/LoginDialog.h"  Menu* Menu::_instance = NULL; Menu* Menu::getInstance() {    static QMutex menuInstanceMutex;     // lock the menu instance mutex to make sure we don't race and create two menus and crash    menuInstanceMutex.lock();     if (!_instance) {        qDebug("First call to Menu::getInstance() - initing menu.");         _instance = new Menu();    }     menuInstanceMutex.unlock();     return _instance;} const ViewFrustumOffset DEFAULT_FRUSTUM_OFFSET = {-135.0f, 0.0f, 0.0f, 25.0f, 0.0f};const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f;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; Menu::Menu() :    _actionHash(),    _audioJitterBufferSamples(0),    _bandwidthDialog(NULL),    _fieldOfView(DEFAULT_FIELD_OF_VIEW_DEGREES),    _faceshiftEyeDeflection(DEFAULT_FACESHIFT_EYE_DEFLECTION),    _frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),    _viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),    _octreeStatsDialog(NULL),    _lodToolsDialog(NULL),    _maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM),    _voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE),    _automaticAvatarLOD(true),    _avatarLODDecreaseFPS(DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS),    _avatarLODIncreaseFPS(ADJUST_LOD_UP_FPS),    _avatarLODDistanceMultiplier(DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER),    _boundaryLevelAdjust(0),    _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS),    _lastAdjust(usecTimestampNow()),    _lastAvatarDetailDrop(usecTimestampNow()),    _fpsAverage(FIVE_SECONDS_OF_FRAMES),    _fastFPSAverage(ONE_SECOND_OF_FRAMES),    _loginAction(NULL),    _preferencesDialog(NULL),    _snapshotsLocation(){    Application *appInstance = Application::getInstance();     QMenu* fileMenu = addMenu("File"); #ifdef Q_OS_MAC    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::AboutApp,                                  0,                                  this,                                  SLOT(aboutApp()),                                  QAction::AboutRole);#endif     AccountManager& accountManager = AccountManager::getInstance();     _loginAction = addActionToQMenuAndActionHash(fileMenu, MenuOption::Logout);     // call our toggle login function now so the menu option is setup properly    toggleLoginMenuItem();     // connect to the appropriate slots of the AccountManager so that we can change the Login/Logout menu item    connect(&accountManager, &AccountManager::accessTokenChanged, this, &Menu::toggleLoginMenuItem);    connect(&accountManager, &AccountManager::logoutComplete, this, &Menu::toggleLoginMenuItem);     addDisabledActionAndSeparator(fileMenu, "Scripts");    addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadDialog()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScriptURL,                                    Qt::CTRL | Qt::SHIFT | Qt::Key_O, appInstance, SLOT(loadScriptURLDialog()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::StopAllScripts, 0, appInstance, SLOT(stopAllScripts()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::ReloadAllScripts, 0, appInstance, SLOT(reloadAllScripts()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J,                                  appInstance, SLOT(toggleRunningScriptsWidget()));     addDisabledActionAndSeparator(fileMenu, "Go");    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::GoHome,                                  Qt::CTRL | Qt::Key_G,                                  appInstance->getAvatar(),                                  SLOT(goHome()));    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::GoToDomain,                                  Qt::CTRL | Qt::Key_D,                                  this,                                  SLOT(goToDomainDialog()));    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::GoToLocation,                                  Qt::CTRL | Qt::SHIFT | Qt::Key_L,                                  this,                                  SLOT(goToLocation()));    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::NameLocation,                                  Qt::CTRL | Qt::Key_N,                                  this,                                  SLOT(nameLocation()));    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::GoTo,                                  Qt::Key_At,                                  this,                                  SLOT(goTo()));     addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model");    addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0, Application::getInstance(), SLOT(uploadHead()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadSkeleton, 0, Application::getInstance(), SLOT(uploadSkeleton()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadAttachment, 0,        Application::getInstance(), SLOT(uploadAttachment()));    addDisabledActionAndSeparator(fileMenu, "Settings");    addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings()));     addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::Quit,                                  Qt::CTRL | Qt::Key_Q,                                  appInstance,                                  SLOT(quit()),                                  QAction::QuitRole);      QMenu* editMenu = addMenu("Edit");     QUndoStack* undoStack = Application::getInstance()->getUndoStack();    QAction* undoAction = undoStack->createUndoAction(editMenu);    undoAction->setShortcut(Qt::CTRL | Qt::Key_Z);    addActionToQMenuAndActionHash(editMenu, undoAction);     QAction* redoAction = undoStack->createRedoAction(editMenu);    redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z);    addActionToQMenuAndActionHash(editMenu, redoAction);     addActionToQMenuAndActionHash(editMenu,                                  MenuOption::Preferences,                                  Qt::CTRL | Qt::Key_Comma,                                  this,                                  SLOT(editPreferences()),                                  QAction::PreferencesRole);     addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0, this, SLOT(editAttachments()));                                      addDisabledActionAndSeparator(editMenu, "Physics");    QObject* avatar = appInstance->getAvatar();    addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ObeyEnvironmentalGravity, Qt::SHIFT | Qt::Key_G, true,             avatar, SLOT(updateMotionBehaviorsFromMenu()));      addAvatarCollisionSubMenu(editMenu);     QMenu* toolsMenu = addMenu("Tools");    addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor()));    addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor,  Qt::ALT | Qt::Key_S, this, SLOT(showScriptEditor())); #ifdef HAVE_QXMPP    _chatAction = addActionToQMenuAndActionHash(toolsMenu,                                                MenuOption::Chat,                                                0,                                                this,                                                SLOT(showChat()));     const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient();    toggleChat();    connect(&xmppClient, SIGNAL(connected()), this, SLOT(toggleChat()));    connect(&xmppClient, SIGNAL(disconnected()), this, SLOT(toggleChat()));#endif     QMenu* viewMenu = addMenu("View");     addCheckableActionToQMenuAndActionHash(viewMenu,                                           MenuOption::Fullscreen,                                           Qt::CTRL | Qt::META | Qt::Key_F,                                           false,                                           appInstance,                                           SLOT(setFullscreen(bool)));    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true,                                            appInstance,SLOT(cameraMenuChanged()));    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true);    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false,                                            appInstance, SLOT(cameraMenuChanged()));     addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0,                                           false,                                           appInstance,                                           SLOT(setEnable3DTVMode(bool)));      QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size");     addActionToQMenuAndActionHash(avatarSizeMenu,                                  MenuOption::IncreaseAvatarSize,                                  Qt::Key_Plus,                                  appInstance->getAvatar(),                                  SLOT(increaseSize()));    addActionToQMenuAndActionHash(avatarSizeMenu,                                  MenuOption::DecreaseAvatarSize,                                  Qt::Key_Minus,                                  appInstance->getAvatar(),                                  SLOT(decreaseSize()));    addActionToQMenuAndActionHash(avatarSizeMenu,                                  MenuOption::ResetAvatarSize,                                  Qt::Key_Equal,                                  appInstance->getAvatar(),                                  SLOT(resetSize()));     addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, false);    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false);    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MoveWithLean, 0, false);    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false);      addDisabledActionAndSeparator(viewMenu, "Stats");    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash);    addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog()));    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true);    addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails()));    addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, this, SLOT(octreeStatsDetails()));    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::AudioScope, 0, false,                                           appInstance->getAudio(),                                           SLOT(toggleScope()));     QMenu* developerMenu = addMenu("Developer");     QMenu* renderOptionsMenu = developerMenu->addMenu("Rendering Options");     addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, Qt::Key_Asterisk, true);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, Qt::SHIFT | Qt::Key_A, true);    addActionToQMenuAndActionHash(renderOptionsMenu,                                  MenuOption::GlowMode,                                  0,                                  appInstance->getGlowEffect(),                                  SLOT(cycleRenderMode()));     addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Shadows, 0, false);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, true);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::BuckyBalls, 0, false);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Particles, 0, true);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Models, 0, true);    addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));     QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options");     addCheckableActionToQMenuAndActionHash(voxelOptionsMenu,                                           MenuOption::Voxels,                                           Qt::SHIFT | Qt::Key_V,                                           true,                                           appInstance,                                           SLOT(setRenderVoxels(bool)));     addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);    addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);    addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges);    addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD);     QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options");     addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true);    addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderSkeletonCollisionShapes);    addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderHeadCollisionShapes);    addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderBoundingCollisionShapes);     addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, false);    addCheckableActionToQMenuAndActionHash(avatarOptionsMenu,                                           MenuOption::Faceshift,                                           0,                                           true,                                           appInstance->getFaceshift(),                                           SLOT(setTCPEnabled(bool)));#ifdef HAVE_FACEPLUS    addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Faceplus, 0, true,        appInstance->getFaceplus(), SLOT(updateEnabled()));#endif #ifdef HAVE_VISAGE    addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Visage, 0, true,        appInstance->getVisage(), SLOT(updateEnabled()));#endif     addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true);    addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false);     QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options");     addCheckableActionToQMenuAndActionHash(handOptionsMenu,                                           MenuOption::FilterSixense,                                           0,                                           true,                                           appInstance->getSixenseManager(),                                           SLOT(setFilter(bool)));    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true);    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandsCollideWithSelf, 0, false);    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false);    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, true);     addDisabledActionAndSeparator(developerMenu, "Testing");     QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools");    addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::TestPing, 0, true);    addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::FrameTimer);    addActionToQMenuAndActionHash(timingMenu, MenuOption::RunTimingTests, 0, this, SLOT(runTests()));     QMenu* frustumMenu = developerMenu->addMenu("View Frustum Debugging Tools");    addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F);    addActionToQMenuAndActionHash(frustumMenu,                                  MenuOption::FrustumRenderMode,                                  Qt::SHIFT | Qt::Key_R,                                  this,                                  SLOT(cycleFrustumRenderMode()));    updateFrustumRenderModeAction();      QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools");    addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings);    addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::SuppressShortTimings);     addCheckableActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::CullSharedFaces,                                  Qt::CTRL | Qt::SHIFT | Qt::Key_C,                                  false,                                  appInstance->getVoxels(),                                  SLOT(cullSharedFaces()));     addCheckableActionToQMenuAndActionHash(renderDebugMenu,                                  MenuOption::ShowCulledSharedFaces,                                  0,                                  false,                                  appInstance->getVoxels(),                                  SLOT(showCulledSharedFaces()));     QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");    addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,                                           0,                                           true,                                           appInstance->getAudio(),                                           SLOT(toggleAudioNoiseReduction()));    addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);    addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);    addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio,                                           Qt::CTRL | Qt::Key_M,                                           false,                                           appInstance->getAudio(),                                           SLOT(toggleMute()));    addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioToneInjection,                                           0,                                           false,                                           appInstance->getAudio(),                                           SLOT(toggleToneInjection()));    addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioScopePause,                                           Qt::CTRL | Qt::Key_P,                                           false,                                           appInstance->getAudio(),                                           SLOT(toggleScopePause()));     QMenu* spatialAudioMenu = audioDebugMenu->addMenu("Spatial Audio");     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessing,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_M,                                           false,                                           appInstance->getAudio(),                                           SLOT(toggleAudioSpatialProcessing()));     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingIncludeOriginal,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_O,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingSeparateEars,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_E,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingPreDelay,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_D,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingStereoSource,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_S,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingHeadOriented,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_H,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingWithDiffusions,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_W,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingRenderPaths,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_R,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingSlightlyRandomSurfaces,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_X,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingProcessLocalAudio,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_A,                                           true);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingDontDistanceAttenuate,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_Y,                                           false);     addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_U,                                           false);     addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel,                Qt::CTRL | Qt::SHIFT | Qt::Key_V,                this,                SLOT(pasteToVoxel()));     connect(appInstance->getAudio(), SIGNAL(muteToggled()), this, SLOT(audioMuteToggled())); #ifndef Q_OS_MAC    QMenu* helpMenu = addMenu("Help");    QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp);    connect(helpAction, SIGNAL(triggered()), this, SLOT(aboutApp()));#endif} Menu::~Menu() {    bandwidthDetailsClosed();    octreeStatsDetailsClosed();} void Menu::loadSettings(QSettings* settings) {    bool lockedSettings = false;    if (!settings) {        settings = Application::getInstance()->lockSettings();        lockedSettings = true;    }     _audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);    _fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);    _faceshiftEyeDeflection = loadSetting(settings, "faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION);    _maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM);    _maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS);    _voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE);    _automaticAvatarLOD = settings->value("automaticAvatarLOD", true).toBool();    _avatarLODDecreaseFPS = loadSetting(settings, "avatarLODDecreaseFPS", DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS);    _avatarLODIncreaseFPS = loadSetting(settings, "avatarLODIncreaseFPS", ADJUST_LOD_UP_FPS);    _avatarLODDistanceMultiplier = loadSetting(settings, "avatarLODDistanceMultiplier",        DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER);    _boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0);    _snapshotsLocation = settings->value("snapshotsLocation",                                         QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).toString();     settings->beginGroup("View Frustum Offset Camera");

Lines 1–500 of 1601.