mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:24:07 +02:00
Don't call settings in render loop
This commit is contained in:
parent
d7f6add74c
commit
88872825fa
4 changed files with 91 additions and 69 deletions
|
@ -17,28 +17,15 @@
|
|||
#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);
|
||||
}
|
||||
|
||||
float LODManager::getOctreeSizeScale() const {
|
||||
return SettingHandles::octreeSizeScale.get();
|
||||
}
|
||||
|
||||
void LODManager::setOctreeSizeScale(float sizeScale) {
|
||||
SettingHandles::octreeSizeScale.set(sizeScale);
|
||||
_shouldRenderTableNeedsRebuilding = true;
|
||||
}
|
||||
|
||||
int LODManager::getBoundaryLevelAdjust() const {
|
||||
return SettingHandles::boundaryLevelAdjust.get();
|
||||
}
|
||||
|
||||
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
|
||||
SettingHandles::boundaryLevelAdjust.set(boundaryLevelAdjust);
|
||||
_shouldRenderTableNeedsRebuilding = true;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -54,63 +41,54 @@ void LODManager::autoAdjustLOD(float currentFPS) {
|
|||
quint64 now = usecTimestampNow();
|
||||
|
||||
const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000;
|
||||
bool automaticAvatarLOD = SettingHandles::automaticAvatarLOD.get();
|
||||
if (automaticAvatarLOD) {
|
||||
float avatarLODIncreaseFPS = SettingHandles::avatarLODIncreaseFPS.get();
|
||||
float avatarLODDecreaseFPS = SettingHandles::avatarLODDecreaseFPS.get();
|
||||
float avatarLODDistanceMultiplier = SettingHandles::avatarLODDistanceMultiplier.get();
|
||||
if (_fastFPSAverage.getAverage() < avatarLODDecreaseFPS) {
|
||||
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 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)));
|
||||
|
||||
_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) {
|
||||
} 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);
|
||||
_avatarLODDistanceMultiplier = qMax(MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER,
|
||||
_avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
|
||||
}
|
||||
SettingHandles::avatarLODDistanceMultiplier.set(avatarLODDistanceMultiplier);
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
quint64 elapsed = now - _lastAdjust;
|
||||
float octreeSizeScale = getOctreeSizeScale();
|
||||
|
||||
if (elapsed > ADJUST_LOD_DOWN_DELAY && _fpsAverage.getAverage() < ADJUST_LOD_DOWN_FPS
|
||||
&& octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
|
||||
&& _octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
|
||||
|
||||
octreeSizeScale *= ADJUST_LOD_DOWN_BY;
|
||||
_octreeSizeScale *= ADJUST_LOD_DOWN_BY;
|
||||
|
||||
if (octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
|
||||
octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
|
||||
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;
|
||||
<< "_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;
|
||||
&& _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;
|
||||
<< "_octreeSizeScale=" << _octreeSizeScale;
|
||||
}
|
||||
setOctreeSizeScale(octreeSizeScale);
|
||||
|
||||
if (changed) {
|
||||
_shouldRenderTableNeedsRebuilding = true;
|
||||
|
@ -200,3 +178,33 @@ bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera
|
|||
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());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,26 +38,27 @@ 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
class LODManager : public Dependency {
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
// TODO: Once the SettingWatcher is implemented, replace them with normal SettingHandles.
|
||||
float getOctreeSizeScale() const;
|
||||
void setOctreeSizeScale(float sizeScale);
|
||||
int getBoundaryLevelAdjust() const;
|
||||
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
|
||||
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();
|
||||
|
@ -67,6 +68,17 @@ public:
|
|||
private:
|
||||
LODManager() {}
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
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;
|
||||
|
|
|
@ -115,7 +115,7 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
|
|||
}
|
||||
|
||||
float Avatar::getLODDistance() const {
|
||||
return SettingHandles::avatarLODDistanceMultiplier.get() *
|
||||
return DependencyManager::get<LODManager>()->getAvatarLODDistanceMultiplier() *
|
||||
glm::distance(qApp->getCamera()->getPosition(), _position) / _scale;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,16 +80,16 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
|||
form->addRow("You can see... ", _feedback);
|
||||
|
||||
form->addRow("Automatic Avatar LOD Adjustment:", _automaticAvatarLOD = new QCheckBox(this));
|
||||
_automaticAvatarLOD->setChecked(SettingHandles::automaticAvatarLOD.get());
|
||||
_automaticAvatarLOD->setChecked(lodManager->getAutomaticAvatarLOD());
|
||||
connect(_automaticAvatarLOD, SIGNAL(toggled(bool)), SLOT(updateAvatarLODControls()));
|
||||
|
||||
form->addRow("Decrease Avatar LOD Below FPS:", _avatarLODDecreaseFPS = new QDoubleSpinBox(this));
|
||||
_avatarLODDecreaseFPS->setValue(SettingHandles::avatarLODDecreaseFPS.get());
|
||||
_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(SettingHandles::avatarLODIncreaseFPS.get());
|
||||
_avatarLODIncreaseFPS->setValue(lodManager->getAvatarLODIncreaseFPS());
|
||||
_avatarLODIncreaseFPS->setDecimals(0);
|
||||
connect(_avatarLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
|
||||
|
||||
|
@ -97,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 / SettingHandles::avatarLODDistanceMultiplier.get());
|
||||
_avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier());
|
||||
connect(_avatarLOD, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
|
||||
|
||||
// Add a button to reset
|
||||
|
@ -120,7 +120,8 @@ void LodToolsDialog::reloadSliders() {
|
|||
void LodToolsDialog::updateAvatarLODControls() {
|
||||
QFormLayout* form = static_cast<QFormLayout*>(layout());
|
||||
|
||||
SettingHandles::automaticAvatarLOD.set(_automaticAvatarLOD->isChecked());
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
lodManager->setAutomaticAvatarLOD(_automaticAvatarLOD->isChecked());
|
||||
|
||||
_avatarLODDecreaseFPS->setVisible(_automaticAvatarLOD->isChecked());
|
||||
form->labelForField(_avatarLODDecreaseFPS)->setVisible(_automaticAvatarLOD->isChecked());
|
||||
|
@ -132,7 +133,7 @@ void LodToolsDialog::updateAvatarLODControls() {
|
|||
form->labelForField(_avatarLOD)->setVisible(!_automaticAvatarLOD->isChecked());
|
||||
|
||||
if (!_automaticAvatarLOD->isChecked()) {
|
||||
_avatarLOD->setValue(1.0 / SettingHandles::avatarLODDistanceMultiplier.get());
|
||||
_avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier());
|
||||
}
|
||||
|
||||
if (isVisible()) {
|
||||
|
@ -141,12 +142,13 @@ void LodToolsDialog::updateAvatarLODControls() {
|
|||
}
|
||||
|
||||
void LodToolsDialog::updateAvatarLODValues() {
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
if (_automaticAvatarLOD->isChecked()) {
|
||||
SettingHandles::avatarLODDecreaseFPS.set(_avatarLODDecreaseFPS->value());
|
||||
SettingHandles::avatarLODIncreaseFPS.set(_avatarLODIncreaseFPS->value());
|
||||
lodManager->setAvatarLODDecreaseFPS(_avatarLODDecreaseFPS->value());
|
||||
lodManager->setAvatarLODIncreaseFPS(_avatarLODIncreaseFPS->value());
|
||||
|
||||
} else {
|
||||
SettingHandles::avatarLODDistanceMultiplier.set(1.0 / _avatarLOD->value());
|
||||
lodManager->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue