From 2774df38bc9d20b557dbb7b4649896ce886e1ff3 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 14 Jan 2016 17:31:39 -0800 Subject: [PATCH] check for entity size before including it for LOD --- interface/src/LODManager.cpp | 2 +- libraries/entities/src/EntityTreeElement.cpp | 20 ++++++++ libraries/octree/src/Octree.cpp | 4 -- libraries/octree/src/Octree.h | 2 - libraries/octree/src/ViewFrustum.cpp | 48 ++++++++++++++++++++ libraries/octree/src/ViewFrustum.h | 2 + 6 files changed, 71 insertions(+), 7 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 13bedb128a..d8815be640 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -253,7 +253,7 @@ QString LODManager::getLODStatsRenderText() { const QString label = "Rendered objects: "; return label + QString::number(getRenderedCount()) + " w/in " + QString::number((int)getRenderDistance()) + "m"; } -// compare audoAdjustLOD() +// compare autoAdjustLOD() void LODManager::updatePIDRenderDistance(float targetFps, float measuredFps, float deltaTime, bool isThrottled) { float distance; if (!isThrottled) { diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 2320004be8..6d47a286d2 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -307,9 +307,29 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData if (!success || params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) { includeThisEntity = false; // out of view, don't include it } + + // Now check the size of the entity, it's possible that a "too small to see" entity is included in a larger + // octree cell because of it's position (for example if it crosses the boundary of a cell it pops to the next + // higher cell. So we want to check to see that the entity is large enough to be seen before we consider + // including it. + if (includeThisEntity) { + AABox entityBounds = entity->getAABox(success); + if (success) { + auto renderAccuracy = params.viewFrustum->calculateRenderAccuracy(entityBounds, params.octreeElementSizeScale, params.boundaryLevelAdjust); + qDebug() << "checking entity:" << entity->getID() << " entityBounds:" << entityBounds << "---renderAccuracy:" << renderAccuracy + << " [ sizeScale:" << params.octreeElementSizeScale << "levelAdjust:" << params.boundaryLevelAdjust << " ]"; + if (renderAccuracy <= 0.0f) { + includeThisEntity = false; // too small, don't include it + qDebug() << "returning FALSE... too small..."; + } + } else { + includeThisEntity = false; // couldn't get box, don't include it + } + } } if (includeThisEntity) { + qDebug() << "including entity:" << entity->getID() << " octree cell:" << getAACube(); indexesOfEntitiesToInclude << i; numberOfEntities++; } diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 652089ebb1..bdad5682a9 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -50,10 +50,6 @@ QVector PERSIST_EXTENSIONS = {"svo", "json", "json.gz"}; -float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) { - return voxelSizeScale / powf(2, renderLevel); -} - Octree::Octree(bool shouldReaverage) : _rootElement(NULL), _isDirty(true), diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index dc0294e1de..789d0f5600 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -385,6 +385,4 @@ protected: bool _isServer; }; -float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale); - #endif // hifi_Octree_h diff --git a/libraries/octree/src/ViewFrustum.cpp b/libraries/octree/src/ViewFrustum.cpp index fd175a8e5b..63cad25b8b 100644 --- a/libraries/octree/src/ViewFrustum.cpp +++ b/libraries/octree/src/ViewFrustum.cpp @@ -750,3 +750,51 @@ void ViewFrustum::evalViewTransform(Transform& view) const { view.setTranslation(getPosition()); view.setRotation(getOrientation()); } + +// 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 ViewFrustum::calculateRenderAccuracy(const AABox& bounds, float octreeSizeScale, int boundaryLevelAdjust) const { + float distanceToCamera = glm::length(bounds.calcCenter() - getPosition()); + float largestDimension = bounds.getLargestDimension(); + + const float maxScale = (float)TREE_SCALE; + const float octreeToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it. + float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / octreeToMeshRatio; + + static bool shouldRenderTableNeedsBuilding = true; + static QMap shouldRenderTable; + if (shouldRenderTableNeedsBuilding) { + 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; + } + + shouldRenderTableNeedsBuilding = false; + } + + 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 + return (distanceToCamera <= visibleDistanceAtClosestScale) ? 1.0f : 0.0f; +} + +float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) { + return voxelSizeScale / powf(2, renderLevel); +} diff --git a/libraries/octree/src/ViewFrustum.h b/libraries/octree/src/ViewFrustum.h index 795a259a3c..0d6170e3ed 100644 --- a/libraries/octree/src/ViewFrustum.h +++ b/libraries/octree/src/ViewFrustum.h @@ -107,6 +107,7 @@ public: void evalProjectionMatrix(glm::mat4& proj) const; void evalViewTransform(Transform& view) const; + float calculateRenderAccuracy(const AABox& bounds, float octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE, int boundaryLevelAdjust = 0) const; private: // Used for keyhole calculations @@ -152,5 +153,6 @@ private: glm::mat4 _ourModelViewProjectionMatrix; }; +float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale); #endif // hifi_ViewFrustum_h