// // OctreeUtils.cpp // libraries/octree/src // // Created by Andrew Meadows 2016.03.04 // Copyright 2016 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "OctreeUtils.h" #include #include #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 = (float)TREE_SCALE; float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO; return (maxScale / visibleDistanceAtMaxScale); } float getPerspectiveAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust) { return atan(getPerspectiveAccuracyAngleTan(octreeSizeScale, boundaryLevelAdjust)); } float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust) { // Smallest visible element is 1cm const float smallestSize = 0.01f; return (smallestSize * MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT) / boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale); }