Showing the LOD angle

This commit is contained in:
samcake 2016-02-04 17:59:35 -08:00
parent cc7f03e7e4
commit a999e046b5
7 changed files with 80 additions and 4 deletions

View file

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

View file

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

View file

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

View file

@ -18,9 +18,12 @@
#include <RenderArgs.h>
#include <gpu/Context.h>
#include <gpu/StandardShaderLib.h>
#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<gpu::State>();
// 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);
}
});
}

View file

@ -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();
};
}

View file

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

View file

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