Fixing the item insert in cell criteria for subcell and adding debgging tool

This commit is contained in:
samcake 2016-02-05 16:49:43 -08:00
parent 57b6ad3c54
commit e5f3805d0e
7 changed files with 299 additions and 72 deletions

View file

@ -0,0 +1,81 @@
//
// debugRenderOctree.js
// examples/utilities/tools
//
// Sam Gateau
// 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
//
Script.include("cookies.js");
var panel = new Panel(10, 300);
var drawOctree = Render.RenderDeferredTask.DrawSceneOctree;
Render.RenderDeferredTask.DrawSceneOctree.enabled = true;
Render.RenderDeferredTask.DrawItemSelection.enabled = true;
panel.newCheckbox("Show Octree Cells",
function(value) { Render.RenderDeferredTask.DrawSceneOctree.showVisibleCells = value; },
function() { return (Render.RenderDeferredTask.DrawSceneOctree.showVisibleCells); },
function(value) { return (value); }
);
panel.newCheckbox("Show Empty Cells",
function(value) { Render.RenderDeferredTask.DrawSceneOctree.showEmptyCells = value; },
function() { return (Render.RenderDeferredTask.DrawSceneOctree.showEmptyCells); },
function(value) { return (value); }
);
panel.newCheckbox("Freeze Frustum",
function(value) { Render.RenderDeferredTask.DrawSceneOctree.freezeFrustum = value; },
function() { return (Render.RenderDeferredTask.DrawSceneOctree.freezeFrustum); },
function(value) { return (value); }
);
panel.newCheckbox("Show Inside Items",
function(value) { Render.RenderDeferredTask.DrawItemSelection.showInsideItems = value; },
function() { return (Render.RenderDeferredTask.DrawItemSelection.showInsideItems); },
function(value) { return (value); }
);
panel.newCheckbox("Show Inside Subcell Items",
function(value) { Render.RenderDeferredTask.DrawItemSelection.showInsideSubcellItems = value; },
function() { return (Render.RenderDeferredTask.DrawItemSelection.showInsideSubcellItems); },
function(value) { return (value); }
);
panel.newCheckbox("Show Partial Items",
function(value) { Render.RenderDeferredTask.DrawItemSelection.showPartialItems = value; },
function() { return (Render.RenderDeferredTask.DrawItemSelection.showPartialItems); },
function(value) { return (value); }
);
panel.newCheckbox("Show Partial Subcell Items",
function(value) { Render.RenderDeferredTask.DrawItemSelection.showPartialSubcellItems = value; },
function() { return (Render.RenderDeferredTask.DrawItemSelection.showPartialSubcellItems); },
function(value) { return (value); }
);
function mouseMoveEvent(event) {
panel.mouseMoveEvent(event);
}
function mousePressEvent(event) {
panel.mousePressEvent(event);
}
function mouseReleaseEvent(event) {
panel.mouseReleaseEvent(event);
}
Controller.mouseMoveEvent.connect(mouseMoveEvent);
Controller.mousePressEvent.connect(mousePressEvent);
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
function scriptEnding() {
panel.destroy();
Render.RenderDeferredTask.DrawSceneOctree.enabled = false;
Render.RenderDeferredTask.DrawItemSelection.enabled = false;
}
Script.scriptEnding.connect(scriptEnding);

View file

@ -113,8 +113,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
// Scene Octree Debuging job
{
addJob<DrawSceneOctree>("DrawSceneOctree", opaqueSelection);
// _drawStatusJobIndex = (int)_jobs.size() - 1;
// enableJob(_drawStatusJobIndex, false);
addJob<DrawItemSelection>("DrawItemSelection", opaqueSelection);
}
// Status icon rendering job

View file

@ -182,7 +182,11 @@ void FetchSpatialTree::run(const SceneContextPointer& sceneContext, const Render
}
// Octree selection!
scene->getSpatialTree().selectCellItems(outSelection, _filter, queryFrustum, _lodAngle);
float angle = glm::degrees(args->_viewFrustum->getAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust));
scene->getSpatialTree().selectCellItems(outSelection, _filter, queryFrustum, angle);
}

View file

@ -25,6 +25,9 @@
#include "drawCellBounds_frag.h"
#include "drawLODReticle_frag.h"
#include "drawItemBounds_vert.h"
#include "drawItemBounds_frag.h"
using namespace render;
@ -76,6 +79,7 @@ const gpu::PipelinePointer DrawSceneOctree::getDrawLODReticlePipeline() {
void DrawSceneOctree::configure(const Config& config) {
_showVisibleCells = config.showVisibleCells;
_showEmptyCells = config.showEmptyCells;
_justFrozeFrustum = (config.freezeFrustum && !_freezeFrustum);
_freezeFrustum = config.freezeFrustum;
@ -88,45 +92,7 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
auto& scene = sceneContext->_scene;
/*const int NUM_STATUS_VEC4_PER_ITEM = 2;
const int VEC4_LENGTH = 4;
// FIrst thing, we update the local buffers with the values coming from Scene octree
int nbCells = 0;
{
if (!_cells) {
_cells = std::make_shared<gpu::Buffer>();
}
const auto& inCells = scene->getSpatialTree()._cells;
_cells->resize(inCells.size() * sizeof(AABox));
AABox* cellAABox = reinterpret_cast<AABox*> (_cells->editData());
for (const auto& cell : inCells) {
(*cellAABox) = scene->getSpatialTree().evalBound(cell.getlocation());
nbCells++;
cellAABox++;
}
}
if (nbCells == 0) {
return;
}
auto queryFrustum = *args->_viewFrustum;
if (_freezeFrustum) {
if (_justFrozeFrustum) {
_justFrozeFrustum = false;
_frozenFrutstum = *args->_viewFrustum;
}
queryFrustum = _frozenFrutstum;
}
*/
// Try that:
// Octree::CellSelection selection;
// scene->getSpatialTree().selectCells(selection, queryFrustum);
// Allright, something to render let's do it
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
glm::mat4 projMat;
Transform viewMat;
@ -141,41 +107,50 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
// bind the one gpu::Pipeline we need
batch.setPipeline(getDrawCellBoundsPipeline());
for (const auto& cellID : inSelection.cellSelection.insideCells) {
auto cell = scene->getSpatialTree().getConcreteCell(cellID);
if (_showVisibleCells) {
auto cellLoc = cell.getlocation();
for (const auto& cellID : inSelection.cellSelection.insideCells) {
auto cell = scene->getSpatialTree().getConcreteCell(cellID);
auto cellLoc = cell.getlocation();
glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth);
glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth);
if (cell.isBrickEmpty() || !cell.hasBrick()) {
cellLocation.w *= -1;
bool doDraw = true;
if (cell.isBrickEmpty() || !cell.hasBrick()) {
if (!_showEmptyCells) {
doDraw = false;
}
cellLocation.w *= -1;
}
if (doDraw) {
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
batch.draw(gpu::LINES, 24, 0);
}
}
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
for (const auto& cellID : inSelection.cellSelection.partialCells) {
auto cell = scene->getSpatialTree().getConcreteCell(cellID);
auto cellLoc = cell.getlocation();
glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth);
batch.draw(gpu::LINES, 24, 0);
}
for (const auto& cellID : inSelection.cellSelection.partialCells) {
auto cell = scene->getSpatialTree().getConcreteCell(cellID);
auto cellLoc = cell.getlocation();
glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth);
if (cell.isBrickEmpty() || !cell.hasBrick()) {
cellLocation.w *= -1;
bool doDraw = true;
if (cell.isBrickEmpty() || !cell.hasBrick()) {
if (!_showEmptyCells) {
doDraw = false;
}
cellLocation.w *= -1;
}
if (doDraw) {
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
batch.draw(gpu::LINES, 24, 0);
}
}
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
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
crosshairModel.setTranslation(glm::vec3(0.0, 0.0, -1000.0));
crosshairModel.setScale(1000.0 * 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());
@ -183,3 +158,107 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
}
});
}
const gpu::PipelinePointer DrawItemSelection::getDrawItemBoundPipeline() {
if (!_drawItemBoundPipeline) {
auto vs = gpu::Shader::createVertex(std::string(drawItemBounds_vert));
auto ps = gpu::Shader::createPixel(std::string(drawItemBounds_frag));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
gpu::Shader::makeProgram(*program, slotBindings);
_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
_drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
auto state = std::make_shared<gpu::State>();
state->setDepthTest(true, false, gpu::LESS_EQUAL);
// 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
_drawItemBoundPipeline = gpu::Pipeline::create(program, state);
}
return _drawItemBoundPipeline;
}
void DrawItemSelection::configure(const Config& config) {
_showInsideItems = config.showInsideItems;
_showInsideSubcellItems = config.showInsideSubcellItems;
_showPartialItems = config.showPartialItems;
_showPartialSubcellItems = config.showPartialSubcellItems;
}
void DrawItemSelection::run(const SceneContextPointer& sceneContext,
const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& inSelection) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
auto& scene = sceneContext->_scene;
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setViewportTransform(args->_viewport);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
// bind the one gpu::Pipeline we need
batch.setPipeline(getDrawItemBoundPipeline());
if (_showInsideItems) {
for (const auto& itemID : inSelection.insideItems) {
auto& item = scene->getItem(itemID);
auto itemBound = item.getBound();
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
batch.draw(gpu::LINES, 24, 0);
}
}
if (_showInsideSubcellItems) {
for (const auto& itemID : inSelection.insideSubcellItems) {
auto& item = scene->getItem(itemID);
auto itemBound = item.getBound();
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
batch.draw(gpu::LINES, 24, 0);
}
}
if (_showPartialItems) {
for (const auto& itemID : inSelection.partialItems) {
auto& item = scene->getItem(itemID);
auto itemBound = item.getBound();
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
batch.draw(gpu::LINES, 24, 0);
}
}
if (_showPartialSubcellItems) {
for (const auto& itemID : inSelection.partialSubcellItems) {
auto& item = scene->getItem(itemID);
auto itemBound = item.getBound();
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
batch.draw(gpu::LINES, 24, 0);
}
}
});
}

View file

@ -19,18 +19,22 @@
namespace render {
class DrawSceneOctreeConfig : public Job::Config {
Q_OBJECT
Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty())
Q_PROPERTY(bool showVisibleCells MEMBER showVisibleCells WRITE setShowVisibleCells)
Q_PROPERTY(bool showEmptyCells MEMBER showEmptyCells WRITE setShowEmptyCells)
Q_PROPERTY(bool freezeFrustum MEMBER freezeFrustum WRITE setFreezeFrustum)
public:
DrawSceneOctreeConfig() : Job::Config(true) {} // FIXME FOR debug
DrawSceneOctreeConfig() : Job::Config(false) {}
bool showVisibleCells{ true }; // FIXME FOR debug
bool showVisibleCells{ true };
bool showEmptyCells{ false };
bool freezeFrustum{ false };
public slots:
void setShowVisibleCells(bool enabled) { showVisibleCells = enabled; emit dirty(); }
void setFreezeFrustum(bool enabled) { freezeFrustum = enabled; emit dirty(); }
void setShowVisibleCells(bool show) { showVisibleCells = show; emit dirty(); }
void setShowEmptyCells(bool show) { showEmptyCells = show; emit dirty(); }
void setFreezeFrustum(bool freeze) { freezeFrustum = freeze; emit dirty(); }
signals:
void dirty();
@ -44,8 +48,12 @@ namespace render {
gpu::PipelinePointer _drawLODReticlePipeline;
int _drawItemBoundPosLoc = -1;
int _drawItemBoundDimLoc = -1;
gpu::PipelinePointer _drawItemBoundPipeline;
bool _showVisibleCells; // initialized by Config
bool _showEmptyCells; // initialized by Config
bool _freezeFrustum{ false }; // initialized by Config
bool _justFrozeFrustum{ false };
ViewFrustum _frozenFrutstum;
@ -61,6 +69,57 @@ namespace render {
const gpu::PipelinePointer getDrawCellBoundsPipeline();
const gpu::PipelinePointer getDrawLODReticlePipeline();
const gpu::PipelinePointer getDrawItemBoundPipeline();
};
class DrawItemSelectionConfig : public Job::Config {
Q_OBJECT
Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty())
Q_PROPERTY(bool showInsideItems MEMBER showInsideItems WRITE setShowInsideItems)
Q_PROPERTY(bool showInsideSubcellItems MEMBER showInsideSubcellItems WRITE setShowInsideSubcellItems)
Q_PROPERTY(bool showPartialItems MEMBER showPartialItems WRITE setShowPartialItems)
Q_PROPERTY(bool showPartialSubcellItems MEMBER showPartialSubcellItems WRITE setShowPartialSubcellItems)
public:
DrawItemSelectionConfig() : Job::Config(false) {}
bool showInsideItems{ true };
bool showInsideSubcellItems{ true };
bool showPartialItems{ true };
bool showPartialSubcellItems{ true };
public slots:
void setShowInsideItems(bool show) { showInsideItems = show; emit dirty(); }
void setShowInsideSubcellItems(bool show) { showInsideSubcellItems = show; emit dirty(); }
void setShowPartialItems(bool show) { showPartialItems = show; emit dirty(); }
void setShowPartialSubcellItems(bool show) { showPartialSubcellItems = show; emit dirty(); }
signals:
void dirty();
};
class DrawItemSelection {
int _drawItemBoundPosLoc = -1;
int _drawItemBoundDimLoc = -1;
gpu::PipelinePointer _drawItemBoundPipeline;
bool _showInsideItems; // initialized by Config
bool _showInsideSubcellItems; // initialized by Config
bool _showPartialItems; // initialized by Config
bool _showPartialSubcellItems; // initialized by Config
public:
using Config = DrawItemSelectionConfig;
using JobModel = Job::ModelI<DrawItemSelection, ItemSpatialTree::ItemSelection, Config>;
DrawItemSelection() {}
void configure(const Config& config);
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemSpatialTree::ItemSelection& selection);
const gpu::PipelinePointer getDrawItemBoundPipeline();
};
}

View file

@ -243,9 +243,8 @@ ItemSpatialTree::Index ItemSpatialTree::resetItem(Index oldCell, const ItemKey&
// Compare range size vs cell location size and tag itemKey accordingly
auto rangeSizef = maxCoordf - minCoordf;
const float SQRT_OF_3 = 1.73205;
float cellDiagonalSquare = 3 * (float)getDepthDimension(location.depth);
bool subcellItem = glm::dot(rangeSizef, rangeSizef) < cellDiagonalSquare;
float cellFitSize = getCellHalfDiagonalSquare(location.depth);
bool subcellItem = glm::dot(rangeSizef, rangeSizef) < cellFitSize;
newKey.setSmaller(subcellItem);
auto newCell = indexCell(location);
@ -255,6 +254,7 @@ ItemSpatialTree::Index ItemSpatialTree::resetItem(Index oldCell, const ItemKey&
// Did the key changed, if yes update
if (newKey._flags != oldKey._flags) {
updateItem(newCell, oldKey, newKey, item);
return newCell;
}
return newCell;
}

View file

@ -327,6 +327,11 @@ namespace render {
float getCellWidth(Depth depth) const { return (float) _size * getInvDepthDimension(depth); }
float getInvCellWidth(Depth depth) const { return (float) getDepthDimension(depth) * _invSize; }
float getCellHalfDiagonalSquare(Depth depth) const {
float cellHalfWidth = 0.5f * getCellWidth(depth);
return 3.0f * cellHalfWidth * cellHalfWidth;
}
glm::vec3 evalPos(const Coord3& coord, Depth depth = Octree::METRIC_COORD_DEPTH) const {
return getOrigin() + glm::vec3(coord) * getCellWidth(depth);
}