From a999e046b5d5196959f05c6f653eb85412e0cf7a Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 4 Feb 2016 17:59:35 -0800 Subject: [PATCH] Showing the LOD angle --- libraries/octree/src/ViewFrustum.cpp | 6 ++++ libraries/octree/src/ViewFrustum.h | 2 ++ libraries/render/src/render/CullTask.cpp | 1 + .../render/src/render/DrawSceneOctree.cpp | 36 +++++++++++++++++++ libraries/render/src/render/DrawSceneOctree.h | 3 ++ libraries/render/src/render/Octree.h | 10 +++--- .../render/src/render/drawLODReticle.slf | 26 ++++++++++++++ 7 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 libraries/render/src/render/drawLODReticle.slf diff --git a/libraries/octree/src/ViewFrustum.cpp b/libraries/octree/src/ViewFrustum.cpp index dd4ddc28e7..4c07a0c784 100644 --- a/libraries/octree/src/ViewFrustum.cpp +++ b/libraries/octree/src/ViewFrustum.cpp @@ -810,3 +810,9 @@ float ViewFrustum::calculateRenderAccuracy(const AABox& bounds, float octreeSize float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale) { return voxelSizeScale / powf(2, renderLevel); } + +float ViewFrustum::getAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust) const { + const float maxScale = (float)TREE_SCALE; + float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO; + return atan(maxScale / visibleDistanceAtMaxScale); +} diff --git a/libraries/octree/src/ViewFrustum.h b/libraries/octree/src/ViewFrustum.h index 548bd6a940..b6096114a4 100644 --- a/libraries/octree/src/ViewFrustum.h +++ b/libraries/octree/src/ViewFrustum.h @@ -125,6 +125,8 @@ public: float calculateRenderAccuracy(const AABox& bounds, float octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE, int boundaryLevelAdjust = 0) const; + float getAccuracyAngle(float octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE, int boundaryLevelAdjust = 0) const; + enum PlaneIndex { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE, NUM_PLANES }; const ::Plane* getPlanes() const { return _planes; } diff --git a/libraries/render/src/render/CullTask.cpp b/libraries/render/src/render/CullTask.cpp index 53bed259d2..70cf420e3b 100644 --- a/libraries/render/src/render/CullTask.cpp +++ b/libraries/render/src/render/CullTask.cpp @@ -183,6 +183,7 @@ void FetchSpatialTree::run(const SceneContextPointer& sceneContext, const Render // Octree selection! scene->getSpatialTree().selectCellItems(outSelection, _filter, queryFrustum, _lodAngle); + } void CullSpatialSelection::configure(const Config& config) { diff --git a/libraries/render/src/render/DrawSceneOctree.cpp b/libraries/render/src/render/DrawSceneOctree.cpp index e41c94ced8..d664af3c9b 100644 --- a/libraries/render/src/render/DrawSceneOctree.cpp +++ b/libraries/render/src/render/DrawSceneOctree.cpp @@ -18,9 +18,12 @@ #include #include +#include + #include "drawCellBounds_vert.h" #include "drawCellBounds_frag.h" +#include "drawLODReticle_frag.h" using namespace render; @@ -49,6 +52,27 @@ const gpu::PipelinePointer DrawSceneOctree::getDrawCellBoundsPipeline() { return _drawCellBoundsPipeline; } +const gpu::PipelinePointer DrawSceneOctree::getDrawLODReticlePipeline() { + if (!_drawLODReticlePipeline) { + auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); + auto ps = gpu::Shader::createPixel(std::string(drawLODReticle_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + + // _drawCellLocationLoc = program->getUniforms().findLocation("inCellLocation"); + + auto state = std::make_shared(); + + // Blend on transparent + state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + + // Good to go add the brand new pipeline + _drawLODReticlePipeline = gpu::Pipeline::create(program, state); + } + return _drawLODReticlePipeline; +} void DrawSceneOctree::configure(const Config& config) { _showVisibleCells = config.showVisibleCells; @@ -145,5 +169,17 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext, batch.draw(gpu::LINES, 24, 0); } + + // Draw the LOD Reticle + { + float angle = glm::degrees(args->_viewFrustum->getAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust)); + Transform crosshairModel; + crosshairModel.setTranslation(glm::vec3(0.0, 0.0, -1.0)); + crosshairModel.setScale(tan(glm::radians(angle))); // Scaling at the actual tan of the lod angle => Multiplied by TWO + batch.setViewTransform(Transform()); + batch.setModelTransform(crosshairModel); + batch.setPipeline(getDrawLODReticlePipeline()); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); + } }); } diff --git a/libraries/render/src/render/DrawSceneOctree.h b/libraries/render/src/render/DrawSceneOctree.h index 2137bd5c4d..ddf22f4e9b 100644 --- a/libraries/render/src/render/DrawSceneOctree.h +++ b/libraries/render/src/render/DrawSceneOctree.h @@ -42,6 +42,8 @@ namespace render { gpu::PipelinePointer _drawCellBoundsPipeline; gpu::BufferPointer _cells; + gpu::PipelinePointer _drawLODReticlePipeline; + bool _showVisibleCells; // initialized by Config bool _freezeFrustum{ false }; // initialized by Config @@ -58,6 +60,7 @@ namespace render { void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& selection); const gpu::PipelinePointer getDrawCellBoundsPipeline(); + const gpu::PipelinePointer getDrawLODReticlePipeline(); }; } diff --git a/libraries/render/src/render/Octree.h b/libraries/render/src/render/Octree.h index 48118ea4a9..6309ea8d6b 100644 --- a/libraries/render/src/render/Octree.h +++ b/libraries/render/src/render/Octree.h @@ -87,7 +87,8 @@ namespace render { // Max depth is 15 => 32Km root down to 1m cells using Depth = int8_t; static const Depth ROOT_DEPTH{ 0 }; - static const Depth MAX_DEPTH { 15 }; + static const Depth MAX_DEPTH{ 15 }; + static const Depth METRIC_COORD_DEPTH{ 15 }; static const double INV_DEPTH_DIM[Octree::MAX_DEPTH + 1]; static int getDepthDimension(Depth depth) { return 1 << depth; } @@ -279,6 +280,7 @@ namespace render { float squareTanAlpha; void setAngle(float a) { + angle = std::min(glm::radians(45.0f), a); // no worse than 45 degrees angle = std::max(glm::radians(1.0f/60.0f), a); // no better than 1 minute of degree auto tanAlpha = tan(angle); squareTanAlpha = (float)(tanAlpha * tanAlpha); @@ -325,18 +327,18 @@ namespace render { float getCellWidth(Depth depth) const { return (float) _size * getInvDepthDimension(depth); } float getInvCellWidth(Depth depth) const { return (float) getDepthDimension(depth) * _invSize; } - glm::vec3 evalPos(const Coord3& coord, Depth depth = Octree::MAX_DEPTH) const { + glm::vec3 evalPos(const Coord3& coord, Depth depth = Octree::METRIC_COORD_DEPTH) const { return getOrigin() + glm::vec3(coord) * getCellWidth(depth); } glm::vec3 evalPos(const Coord3& coord, float cellWidth) const { return getOrigin() + glm::vec3(coord) * cellWidth; } - Coord3 evalCoord(const glm::vec3& pos, Depth depth = Octree::MAX_DEPTH) const { + Coord3 evalCoord(const glm::vec3& pos, Depth depth = Octree::METRIC_COORD_DEPTH) const { auto npos = (pos - getOrigin()); return Coord3(npos * getInvCellWidth(depth)); // Truncate fractional part } - Coord3f evalCoordf(const glm::vec3& pos, Depth depth = Octree::MAX_DEPTH) const { + Coord3f evalCoordf(const glm::vec3& pos, Depth depth = Octree::METRIC_COORD_DEPTH) const { auto npos = (pos - getOrigin()); return Coord3f(npos * getInvCellWidth(depth)); } diff --git a/libraries/render/src/render/drawLODReticle.slf b/libraries/render/src/render/drawLODReticle.slf new file mode 100644 index 0000000000..68eb27b775 --- /dev/null +++ b/libraries/render/src/render/drawLODReticle.slf @@ -0,0 +1,26 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw the LOD reticle used to visualize the current LOD angle +// +// Created by Sam Gateau on 2/4/16 +// Copyright 2015 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 +// + +in vec2 varTexCoord0; +out vec4 outFragColor; + +void main(void) { + vec2 circlePos = 2.0 * ( varTexCoord0.xy * 2.0 - vec2(1.0) ); + float radius = length(circlePos); + + float lodEdge = step(abs(1.0 - radius), 0.05); + + float cellEdge = step(abs(2.0 - radius), 0.05); + + outFragColor = vec4(lodEdge * vec3(1.0, 1.0, 0.0) + cellEdge * vec3(0.0, 1.0, 1.0), lodEdge + 0.5 * cellEdge); +} \ No newline at end of file