From bc3acfa3c0c4123292653433e0acfacf3e14c2b6 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 5 Aug 2019 18:59:29 -0700 Subject: [PATCH] Clean up and re-name to reflect what uses octreeSizeScale and what uses visibilityDistance --- .../qml/hifi/dialogs/TabletLODTools.qml | 13 ++--- interface/src/Application.cpp | 2 +- interface/src/LODManager.cpp | 29 +++++++--- interface/src/LODManager.h | 6 +- interface/src/ui/LodToolsDialog.cpp | 13 ++--- libraries/octree/src/OctreeConstants.h | 5 +- libraries/octree/src/OctreeUtils.cpp | 57 +++---------------- libraries/octree/src/OctreeUtils.h | 13 +---- 8 files changed, 49 insertions(+), 89 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/TabletLODTools.qml b/interface/resources/qml/hifi/dialogs/TabletLODTools.qml index bb3d668850..cd99b75a61 100644 --- a/interface/resources/qml/hifi/dialogs/TabletLODTools.qml +++ b/interface/resources/qml/hifi/dialogs/TabletLODTools.qml @@ -27,11 +27,8 @@ Rectangle { HifiConstants { id: hifi } - readonly property real treeScale: 32768; // ~20 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe - readonly property real halfTreeScale: treeScale / 2; - - // This controls the LOD. Larger number will make smaller voxels visible at greater distance. - readonly property real defaultOctreeSizeScale: treeScale * 400.0 + // This controls the LOD. Larger number will make smaller objects visible at greater distance. + readonly property real defaultMaxVisibilityDistance: 400.0 Column { anchors.margins: 10 @@ -89,10 +86,10 @@ Rectangle { anchors.right: parent.right minimumValue: 5 maximumValue: 2000 - value: LODManager.getOctreeSizeScale() / treeScale + value: defaultMaxVisibilityDistance tickmarksEnabled: false onValueChanged: { - LODManager.setOctreeSizeScale(value * treeScale); + LODManager.setVisibilityDistanceForUnitElement(value); whatYouCanSeeLabel.text = LODManager.getLODFeedbackText() } } @@ -106,7 +103,7 @@ Rectangle { colorScheme: root.colorScheme height: 30 onClicked: { - slider.value = defaultOctreeSizeScale/treeScale + slider.value = defaultMaxVisibilityDistance adjustCheckbox.checked = false LODManager.setAutomaticLODAdjust(adjustCheckbox.checked); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8789fcde1c..5f4850485f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6817,7 +6817,7 @@ void Application::updateRenderArgs(float deltaTime) { _viewFrustum.setProjection(adjustedProjection); _viewFrustum.calculate(); } - appRenderArgs._renderArgs = RenderArgs(_graphicsEngine.getGPUContext(), lodManager->getOctreeSizeScale(), + appRenderArgs._renderArgs = RenderArgs(_graphicsEngine.getGPUContext(), lodManager->getVisibilityDistance(), lodManager->getBoundaryLevelAdjust(), lodManager->getLODAngleHalfTan(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::DEFERRED, RenderArgs::RENDER_DEBUG_NONE); appRenderArgs._renderArgs._scene = getMain3DScene(); diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 24043f4124..2b303aed74 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -94,7 +94,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { } // Previous values for output - float oldOctreeSizeScale = getOctreeSizeScale(); + float oldVisibilityDistance = getVisibilityDistance(); float oldLODAngle = getLODAngleDeg(); // Target fps is slightly overshooted by 5hz @@ -165,7 +165,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { // And now add the output of the controller to the LODAngle where we will guarantee it is in the proper range setLODAngleDeg(oldLODAngle + output); - if (oldOctreeSizeScale != _octreeSizeScale) { + if (oldVisibilityDistance != _visibilityDistance) { auto lodToolsDialog = DependencyManager::get()->getLodToolsDialog(); if (lodToolsDialog) { lodToolsDialog->reloadSliders(); @@ -174,7 +174,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { } float LODManager::getLODAngleHalfTan() const { - return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust); + return getPerspectiveAccuracyAngleTan(_visibilityDistance, _boundaryLevelAdjust); } float LODManager::getLODAngle() const { @@ -184,11 +184,19 @@ float LODManager::getLODAngleDeg() const { return glm::degrees(getLODAngle()); } +float LODManager::getVisibilityDistance() const { + return _visibilityDistance; +} + +void LODManager::setVisibilityDistance(float distance) { + _visibilityDistance = distance; +} + void LODManager::setLODAngleDeg(float lodAngle) { auto newSolidAngle = std::max(0.001f, std::min(lodAngle, 90.f)); auto halfTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); - auto octreeSizeScale = /*TREE_SCALE * OCTREE_TO_MESH_RATIO */ (sqrtf(3.0f) * 0.5f) / halfTan; - setOctreeSizeScale(octreeSizeScale); + auto visibilityDistance = UNIT_ELEMENT_MAX_EXTENT / halfTan; + setVisibilityDistance(visibilityDistance); } void LODManager::setSmoothScale(float t) { @@ -268,7 +276,11 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { }; void LODManager::setOctreeSizeScale(float sizeScale) { - _octreeSizeScale = sizeScale; + setVisibilityDistance(sizeScale / TREE_SCALE); +} + +float LODManager::getOctreeSizeScale() const { + return getVisibilityDistance() * TREE_SCALE; } void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) { @@ -294,9 +306,8 @@ QString LODManager::getLODFeedbackText() { } break; } // distance feedback - float octreeSizeScale = getOctreeSizeScale(); - // float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE; - float relativeToDefault = octreeSizeScale / MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT; + float visibilityDistance = getVisibilityDistance(); + float relativeToDefault = visibilityDistance / DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT; int relativeToTwentyTwenty = 20 / relativeToDefault; QString result; diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 649e0e8e34..fbf38ee638 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -145,7 +145,7 @@ public: * @function LODManager.getOctreeSizeScale * @returns {number} */ - Q_INVOKABLE float getOctreeSizeScale() const { return _octreeSizeScale; } + Q_INVOKABLE float getOctreeSizeScale() const; /**jsdoc * @function LODManager.setBoundaryLevelAdjust @@ -198,6 +198,8 @@ public: void setLODAngleDeg(float lodAngle); float getLODAngleHalfTan() const; float getLODAngle() const; + float getVisibilityDistance() const; + void setVisibilityDistance(float distance); float getPidKp() const; float getPidKi() const; @@ -254,7 +256,7 @@ private: float _desktopTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS }; float _hmdTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS }; - float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; + float _visibilityDistance = DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT; int _boundaryLevelAdjust = 0; glm::vec4 _pidCoefs{ 1.0f, 0.0f, 0.0f, 1.0f }; // Kp, Ki, Kd, Kv diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index b2d0131d3b..b25b9bc5a6 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -64,7 +64,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : _lodSize->setTickPosition(QSlider::TicksBelow); _lodSize->setFixedWidth(SLIDER_WIDTH); _lodSize->setPageStep(PAGE_STEP_LOD_SIZE); - int sliderValue = lodManager->getOctreeSizeScale() / TREE_SCALE; + int sliderValue = lodManager->getVisibilityDistance(); _lodSize->setValue(sliderValue); form->addRow("Level of Detail:", _lodSize); connect(_lodSize,SIGNAL(valueChanged(int)),this,SLOT(sizeScaleValueChanged(int))); @@ -81,7 +81,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : void LodToolsDialog::reloadSliders() { auto lodManager = DependencyManager::get(); - _lodSize->setValue(lodManager->getOctreeSizeScale() / TREE_SCALE); + _lodSize->setValue(lodManager->getVisibilityDistance()); _feedback->setText(lodManager->getLODFeedbackText()); } @@ -93,15 +93,14 @@ void LodToolsDialog::updateAutomaticLODAdjust() { void LodToolsDialog::sizeScaleValueChanged(int value) { auto lodManager = DependencyManager::get(); - float realValue = value /** TREE_SCALE*/; - lodManager->setOctreeSizeScale(realValue); + lodManager->setVisibilityDistance(value); _feedback->setText(lodManager->getLODFeedbackText()); } void LodToolsDialog::resetClicked(bool checked) { - int sliderValue = DEFAULT_OCTREE_SIZE_SCALE / TREE_SCALE; + int sliderValue = DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT; _lodSize->setValue(sliderValue); _manualLODAdjust->setChecked(false); @@ -124,8 +123,8 @@ void LodToolsDialog::closeEvent(QCloseEvent* event) { lodManager->setAutomaticLODAdjust(true); // if the user adjusted the LOD above "normal" then always revert back to default - if (lodManager->getOctreeSizeScale() > DEFAULT_OCTREE_SIZE_SCALE) { - lodManager->setOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE); + if (lodManager->getVisibilityDistance() > DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT) { + lodManager->setVisibilityDistance(DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT); } #endif } diff --git a/libraries/octree/src/OctreeConstants.h b/libraries/octree/src/OctreeConstants.h index 062d4e1ef2..26f0246538 100644 --- a/libraries/octree/src/OctreeConstants.h +++ b/libraries/octree/src/OctreeConstants.h @@ -21,8 +21,9 @@ const int TREE_SCALE = 32768; // ~20 miles.. This is the number of meters of the const int HALF_TREE_SCALE = TREE_SCALE / 2; // This controls the LOD. Larger number will make smaller voxels visible at greater distance. -const float MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT = 400.0f; // max distance where a 1x1x1 cube is visible for 20:20 vision -const float DEFAULT_OCTREE_SIZE_SCALE = TREE_SCALE * MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT; +const float DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT = 400.0f; // max distance where a 1x1x1 cube is visible for 20:20 vision +const float UNIT_ELEMENT_MAX_EXTENT = sqrt(3.0f) / 2.0f; // A unit cube tilted on its edge will have its edge jutting out sqrt(3)/2 units from the center +const float DEFAULT_OCTREE_SIZE_SCALE = TREE_SCALE * DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT; // Since entities like models live inside of octree cells, and they themselves can have very small mesh parts, // we want to have some constant that controls have big a mesh part must be to render even if the octree cell itself diff --git a/libraries/octree/src/OctreeUtils.cpp b/libraries/octree/src/OctreeUtils.cpp index 788f6da85f..2a1f520819 100644 --- a/libraries/octree/src/OctreeUtils.cpp +++ b/libraries/octree/src/OctreeUtils.cpp @@ -18,64 +18,21 @@ #include #include -float calculateRenderAccuracy(const glm::vec3& position, - const AABox& bounds, - float octreeSizeScale, - int boundaryLevelAdjust) { - float largestDimension = bounds.getLargestDimension(); - - const float maxScale = (float)TREE_SCALE; - float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO; - - static std::once_flag once; - static QMap shouldRenderTable; - std::call_once(once, [&] { - float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small - float scale = maxScale; - float factor = 1.0f; - - while (scale > SMALLEST_SCALE_IN_TABLE) { - scale /= 2.0f; - factor /= 2.0f; - shouldRenderTable[scale] = factor; - } - }); - - float closestScale = maxScale; - float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale; - QMap::const_iterator lowerBound = shouldRenderTable.lowerBound(largestDimension); - if (lowerBound != shouldRenderTable.constEnd()) { - closestScale = lowerBound.key(); - visibleDistanceAtClosestScale = visibleDistanceAtMaxScale * lowerBound.value(); - } - - if (closestScale < largestDimension) { - visibleDistanceAtClosestScale *= 2.0f; - } - - // FIXME - for now, it's either visible or not visible. We want to adjust this to eventually return - // a floating point for objects that have small angular size to indicate that they may be rendered - // with lower preciscion - float distanceToCamera = glm::length(bounds.calcCenter() - position); - return (distanceToCamera <= visibleDistanceAtClosestScale) ? 1.0f : 0.0f; -} - float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) { return voxelSizeScale / powf(2.0f, renderLevel); } -float getPerspectiveAccuracyAngleTan(float octreeSizeScale, int boundaryLevelAdjust) { - const float maxScale = sqrtf(3.0f) * 0.5f; //(float)TREE_SCALE; - float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) /* / OCTREE_TO_MESH_RATIO*/; - return (maxScale / visibleDistanceAtMaxScale); +float getPerspectiveAccuracyAngleTan(float visibilityDistance, int boundaryLevelAdjust) { + float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, visibilityDistance); + return UNIT_ELEMENT_MAX_EXTENT / visibleDistanceAtMaxScale; // TODO: consider renaming this function to half tangent because we're taking into account a factor of 1/2 } -float getPerspectiveAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust) { - return atan(getPerspectiveAccuracyAngleTan(octreeSizeScale, boundaryLevelAdjust)); +float getPerspectiveAccuracyAngle(float visibilityDistance, int boundaryLevelAdjust) { + return atan(getPerspectiveAccuracyAngleTan(visibilityDistance, boundaryLevelAdjust)); } -float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust) { +float getOrthographicAccuracySize(float visibilityDistance, int boundaryLevelAdjust) { // Smallest visible element is 1cm const float smallestSize = 0.01f; - return (smallestSize * MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT) / boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale); + return (smallestSize * DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT) / boundaryDistanceForRenderLevel(boundaryLevelAdjust, visibilityDistance); } diff --git a/libraries/octree/src/OctreeUtils.h b/libraries/octree/src/OctreeUtils.h index eedbfe8bda..4ac3937cd0 100644 --- a/libraries/octree/src/OctreeUtils.h +++ b/libraries/octree/src/OctreeUtils.h @@ -20,18 +20,11 @@ class AABox; class AACube; class QJsonDocument; -/// renderAccuracy represents a floating point "visibility" of an object based on it's view from the camera. At a simple -/// level it returns 0.0f for things that are so small for the current settings that they could not be visible. -float calculateRenderAccuracy(const glm::vec3& position, - const AABox& bounds, - float octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE, - int boundaryLevelAdjust = 0); - float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale); -float getPerspectiveAccuracyAngleTan(float octreeSizeScale, int boundaryLevelAdjust); -float getPerspectiveAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust); -float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust); +float getPerspectiveAccuracyAngleTan(float visibilityDistance, int boundaryLevelAdjust); +float getPerspectiveAccuracyAngle(float visibilityDistance, int boundaryLevelAdjust); +float getOrthographicAccuracySize(float visibilityDistance, int boundaryLevelAdjust); // MIN_ELEMENT_ANGULAR_DIAMETER = angular diameter of 1x1x1m cube at 400m = sqrt(3) / 400 = 0.0043301 radians ~= 0.25 degrees const float MIN_ELEMENT_ANGULAR_DIAMETER = 0.0043301f; // radians