check for entity size before including it for LOD

This commit is contained in:
Brad Hefta-Gaub 2016-01-14 17:31:39 -08:00
parent 8c4abd2a2d
commit 2774df38bc
6 changed files with 71 additions and 7 deletions

View file

@ -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) {

View file

@ -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++;
}

View file

@ -50,10 +50,6 @@
QVector<QString> 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),

View file

@ -385,6 +385,4 @@ protected:
bool _isServer;
};
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale);
#endif // hifi_Octree_h

View file

@ -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<float, float> 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<float, float>::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);
}

View file

@ -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