From fe7a359545afb2e5cacc4f8ea0e579c23d5ae66d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 11 Apr 2014 15:55:48 -0700 Subject: [PATCH 1/4] Added tools to adjust avatar LOD to LOD tools dialog. Closes #2624. --- interface/src/Menu.cpp | 51 +++++++++++++++----------- interface/src/Menu.h | 14 ++++++++ interface/src/ui/LodToolsDialog.cpp | 56 +++++++++++++++++++++++++++++ interface/src/ui/LodToolsDialog.h | 9 +++++ 4 files changed, 110 insertions(+), 20 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 0d3c66e3e7..4b5d24e376 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -79,6 +79,9 @@ Menu::Menu() : _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), @@ -273,7 +276,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, true); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::BuckyBalls, 0, true); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Particles, 0, true); - + addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options"); @@ -286,7 +289,6 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); - addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD); @@ -415,6 +417,11 @@ void Menu::loadSettings(QSettings* settings) { _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); settings->beginGroup("View Frustum Offset Camera"); @@ -454,6 +461,10 @@ void Menu::saveSettings(QSettings* settings) { settings->setValue("maxVoxels", _maxVoxels); settings->setValue("maxVoxelsPPS", _maxVoxelPacketsPerSecond); settings->setValue("voxelSizeScale", _voxelSizeScale); + settings->setValue("automaticAvatarLOD", _automaticAvatarLOD); + settings->setValue("avatarLODDecreaseFPS", _avatarLODDecreaseFPS); + settings->setValue("avatarLODIncreaseFPS", _avatarLODIncreaseFPS); + settings->setValue("avatarLODDistanceMultiplier", _avatarLODDistanceMultiplier); settings->setValue("boundaryLevelAdjust", _boundaryLevelAdjust); settings->beginGroup("View Frustum Offset Camera"); settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw); @@ -1165,27 +1176,27 @@ void Menu::autoAdjustLOD(float currentFPS) { quint64 now = usecTimestampNow(); - const float ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f; const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000; - if (_fastFPSAverage.getAverage() < ADJUST_AVATAR_LOD_DOWN_FPS) { - if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) { - // attempt to lower the detail in proportion to the fps difference - float targetFps = (ADJUST_AVATAR_LOD_DOWN_FPS + ADJUST_LOD_UP_FPS) * 0.5f; - float averageFps = _fastFPSAverage.getAverage(); - const float MAXIMUM_MULTIPLIER_SCALE = 2.0f; - const float MAXIMUM_DISTANCE_MULTIPLIER = 15.0f; - _avatarLODDistanceMultiplier = qMin(MAXIMUM_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier * - (averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE : qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps))); - _lastAvatarDetailDrop = now; + 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); } - } else if (_fastFPSAverage.getAverage() > ADJUST_LOD_UP_FPS) { - // let the detail level creep slowly upwards - const float DISTANCE_DECREASE_RATE = 0.05f; - const float MINIMUM_DISTANCE_MULTIPLIER = 0.1f; - _avatarLODDistanceMultiplier = qMax(MINIMUM_DISTANCE_MULTIPLIER, - _avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE); } - + bool changed = false; quint64 elapsed = now - _lastAdjust; diff --git a/interface/src/Menu.h b/interface/src/Menu.h index e827e43014..7151aeeb4c 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -27,6 +27,7 @@ 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; @@ -37,6 +38,9 @@ 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; + enum FrustumDrawMode { FRUSTUM_DRAW_MODE_ALL, FRUSTUM_DRAW_MODE_VECTORS, @@ -95,6 +99,13 @@ public: void resetLODAdjust(); void setVoxelSizeScale(float sizeScale); float getVoxelSizeScale() const { return _voxelSizeScale; } + 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; } void setBoundaryLevelAdjust(int boundaryLevelAdjust); int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } @@ -217,6 +228,9 @@ private: LodToolsDialog* _lodToolsDialog; int _maxVoxels; float _voxelSizeScale; + bool _automaticAvatarLOD; + float _avatarLODDecreaseFPS; + float _avatarLODIncreaseFPS; float _avatarLODDistanceMultiplier; int _boundaryLevelAdjust; QAction* _useVoxelShader; diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index 35d5eada41..92456956e3 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -75,6 +76,27 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : const int FEEDBACK_WIDTH = 350; _feedback->setFixedWidth(FEEDBACK_WIDTH); form->addRow("You can see... ", _feedback); + + form->addRow("Automatic Avatar LOD Adjustment:", _automaticAvatarLOD = new QCheckBox()); + _automaticAvatarLOD->setChecked(Menu::getInstance()->getAutomaticAvatarLOD()); + connect(_automaticAvatarLOD, SIGNAL(toggled(bool)), SLOT(updateAvatarLODControls())); + + form->addRow("Decrease Avatar LOD Below FPS:", _avatarLODDecreaseFPS = new QDoubleSpinBox()); + _avatarLODDecreaseFPS->setValue(Menu::getInstance()->getAvatarLODDecreaseFPS()); + _avatarLODDecreaseFPS->setDecimals(0); + connect(_avatarLODDecreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues())); + + form->addRow("Increase Avatar LOD Above FPS:", _avatarLODIncreaseFPS = new QDoubleSpinBox()); + _avatarLODIncreaseFPS->setValue(Menu::getInstance()->getAvatarLODIncreaseFPS()); + _avatarLODIncreaseFPS->setDecimals(0); + connect(_avatarLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues())); + + form->addRow("Avatar LOD:", _avatarLOD = new QDoubleSpinBox()); + _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()); + connect(_avatarLOD, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues())); // Add a button to reset QPushButton* resetButton = new QPushButton("Reset"); @@ -82,6 +104,8 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : connect(resetButton,SIGNAL(clicked(bool)),this,SLOT(resetClicked(bool))); this->QDialog::setLayout(form); + + updateAvatarLODControls(); } LodToolsDialog::~LodToolsDialog() { @@ -96,6 +120,35 @@ void LodToolsDialog::reloadSliders() { _feedback->setText(Menu::getInstance()->getLODFeedbackText()); } +void LodToolsDialog::updateAvatarLODControls() { + QFormLayout* form = static_cast(layout()); + + Menu::getInstance()->setAutomaticAvatarLOD(_automaticAvatarLOD->isChecked()); + + _avatarLODDecreaseFPS->setVisible(_automaticAvatarLOD->isChecked()); + form->labelForField(_avatarLODDecreaseFPS)->setVisible(_automaticAvatarLOD->isChecked()); + + _avatarLODIncreaseFPS->setVisible(_automaticAvatarLOD->isChecked()); + form->labelForField(_avatarLODIncreaseFPS)->setVisible(_automaticAvatarLOD->isChecked()); + + _avatarLOD->setVisible(!_automaticAvatarLOD->isChecked()); + form->labelForField(_avatarLOD)->setVisible(!_automaticAvatarLOD->isChecked()); + + if (!_automaticAvatarLOD->isChecked()) { + _avatarLOD->setValue(1.0 / Menu::getInstance()->getAvatarLODDistanceMultiplier()); + } +} + +void LodToolsDialog::updateAvatarLODValues() { + if (_automaticAvatarLOD->isChecked()) { + Menu::getInstance()->setAvatarLODDecreaseFPS(_avatarLODDecreaseFPS->value()); + Menu::getInstance()->setAvatarLODIncreaseFPS(_avatarLODIncreaseFPS->value()); + + } else { + Menu::getInstance()->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value()); + } +} + void LodToolsDialog::sizeScaleValueChanged(int value) { float realValue = value * TREE_SCALE; Menu::getInstance()->setVoxelSizeScale(realValue); @@ -113,6 +166,9 @@ void LodToolsDialog::resetClicked(bool checked) { //sizeScaleValueChanged(sliderValue); _lodSize->setValue(sliderValue); _boundaryLevelAdjust->setValue(0); + _automaticAvatarLOD->setChecked(true); + _avatarLODDecreaseFPS->setValue(DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS); + _avatarLODIncreaseFPS->setValue(ADJUST_LOD_UP_FPS); } void LodToolsDialog::reject() { diff --git a/interface/src/ui/LodToolsDialog.h b/interface/src/ui/LodToolsDialog.h index a3223806aa..5b34a5efd0 100644 --- a/interface/src/ui/LodToolsDialog.h +++ b/interface/src/ui/LodToolsDialog.h @@ -16,6 +16,9 @@ #include #include +class QCheckBox; +class QDoubleSpinBox; + class LodToolsDialog : public QDialog { Q_OBJECT public: @@ -32,6 +35,8 @@ public slots: void boundaryLevelValueChanged(int value); void resetClicked(bool checked); void reloadSliders(); + void updateAvatarLODControls(); + void updateAvatarLODValues(); protected: @@ -41,6 +46,10 @@ protected: private: QSlider* _lodSize; QSlider* _boundaryLevelAdjust; + QCheckBox* _automaticAvatarLOD; + QDoubleSpinBox* _avatarLODDecreaseFPS; + QDoubleSpinBox* _avatarLODIncreaseFPS; + QDoubleSpinBox* _avatarLOD; QLabel* _feedback; }; From 4265617c3edf787cf97164681310b403d4cc6b30 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 11 Apr 2014 16:02:46 -0700 Subject: [PATCH 2/4] Add missing include. --- interface/src/ui/LodToolsDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index 92456956e3..3612e06e34 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include From 0ca68e4cb4c2fad9f840d203cae32d61d4c2bf7e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 11 Apr 2014 17:53:02 -0700 Subject: [PATCH 3/4] Adjust the size when we toggle the avatar LOD options. --- interface/src/ui/LodToolsDialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index 3612e06e34..6df5121104 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -138,6 +138,10 @@ void LodToolsDialog::updateAvatarLODControls() { if (!_automaticAvatarLOD->isChecked()) { _avatarLOD->setValue(1.0 / Menu::getInstance()->getAvatarLODDistanceMultiplier()); } + + if (isVisible()) { + adjustSize(); + } } void LodToolsDialog::updateAvatarLODValues() { From 873620e60174984eb3c64ebe3bbb78923ee1491a Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 14 Apr 2014 12:27:15 -0700 Subject: [PATCH 4/4] Make sure we set the texture data even if the texture URL is invalid. --- interface/src/renderer/TextureCache.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index 17146dc2bb..3f523cf4bb 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -244,7 +244,6 @@ NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) : if (!url.isValid()) { _loaded = true; - return; } // default to white/blue