mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 17:35:45 +02:00
Starting to remove empty bricks and empty cells
This commit is contained in:
parent
ad3f3a6dcf
commit
40e49b2376
7 changed files with 179 additions and 25 deletions
|
@ -55,6 +55,24 @@ panel.newCheckbox("Show Partial Subcell Items",
|
||||||
function(value) { return (value); }
|
function(value) { return (value); }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
panel.newSlider('Cells Free / Allocated', -1, 1,
|
||||||
|
function(value) { value; }, // setter
|
||||||
|
function() { return Render.RenderDeferredTask.DrawSceneOctree.numFreeCells; }, // getter
|
||||||
|
function(value) { return value; });
|
||||||
|
|
||||||
|
this.update = function () {
|
||||||
|
var numFree = Render.RenderDeferredTask.DrawSceneOctree.numFreeCells;
|
||||||
|
var numAlloc = Render.RenderDeferredTask.DrawSceneOctree.numAllocatedCells;
|
||||||
|
var title = [
|
||||||
|
' ' + name,
|
||||||
|
numFree + ' / ' + numAlloc
|
||||||
|
].join('\t');
|
||||||
|
|
||||||
|
widget.editTitle({ text: title });
|
||||||
|
slider.setMaxValue(numAlloc);
|
||||||
|
};
|
||||||
|
*/
|
||||||
function mouseMoveEvent(event) {
|
function mouseMoveEvent(event) {
|
||||||
panel.mouseMoveEvent(event);
|
panel.mouseMoveEvent(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,10 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
auto& scene = sceneContext->_scene;
|
auto& scene = sceneContext->_scene;
|
||||||
|
|
||||||
|
std::static_pointer_cast<Config>(renderContext->jobConfig)->numAllocatedCells = (int)scene->getSpatialTree().getNumAllocatedCells();
|
||||||
|
std::static_pointer_cast<Config>(renderContext->jobConfig)->numFreeCells = (int)scene->getSpatialTree().getNumFreeCells();
|
||||||
|
|
||||||
|
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
Transform viewMat;
|
Transform viewMat;
|
||||||
|
@ -171,6 +175,8 @@ const gpu::PipelinePointer DrawItemSelection::getDrawItemBoundPipeline() {
|
||||||
_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
|
_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
|
||||||
_drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
|
_drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
|
||||||
|
|
||||||
|
_drawCellLocationLoc = program->getUniforms().findLocation("inCellLocation");
|
||||||
|
|
||||||
auto state = std::make_shared<gpu::State>();
|
auto state = std::make_shared<gpu::State>();
|
||||||
|
|
||||||
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
||||||
|
@ -217,7 +223,10 @@ void DrawItemSelection::run(const SceneContextPointer& sceneContext,
|
||||||
for (const auto& itemID : inSelection.insideItems) {
|
for (const auto& itemID : inSelection.insideItems) {
|
||||||
auto& item = scene->getItem(itemID);
|
auto& item = scene->getItem(itemID);
|
||||||
auto itemBound = item.getBound();
|
auto itemBound = item.getBound();
|
||||||
|
auto itemCell = scene->getSpatialTree().getCellLocation(item.getCell());
|
||||||
|
glm::ivec4 cellLocation(0, 0, 0, itemCell.depth);
|
||||||
|
|
||||||
|
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
|
||||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
|
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
|
||||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
|
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
|
||||||
|
|
||||||
|
@ -229,7 +238,10 @@ void DrawItemSelection::run(const SceneContextPointer& sceneContext,
|
||||||
for (const auto& itemID : inSelection.insideSubcellItems) {
|
for (const auto& itemID : inSelection.insideSubcellItems) {
|
||||||
auto& item = scene->getItem(itemID);
|
auto& item = scene->getItem(itemID);
|
||||||
auto itemBound = item.getBound();
|
auto itemBound = item.getBound();
|
||||||
|
auto itemCell = scene->getSpatialTree().getCellLocation(item.getCell());
|
||||||
|
glm::ivec4 cellLocation(0, 0, 1, itemCell.depth);
|
||||||
|
|
||||||
|
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
|
||||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
|
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
|
||||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
|
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
|
||||||
|
|
||||||
|
@ -241,7 +253,10 @@ void DrawItemSelection::run(const SceneContextPointer& sceneContext,
|
||||||
for (const auto& itemID : inSelection.partialItems) {
|
for (const auto& itemID : inSelection.partialItems) {
|
||||||
auto& item = scene->getItem(itemID);
|
auto& item = scene->getItem(itemID);
|
||||||
auto itemBound = item.getBound();
|
auto itemBound = item.getBound();
|
||||||
|
auto itemCell = scene->getSpatialTree().getCellLocation(item.getCell());
|
||||||
|
glm::ivec4 cellLocation(0, 0, 0, itemCell.depth);
|
||||||
|
|
||||||
|
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
|
||||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
|
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
|
||||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
|
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
|
||||||
|
|
||||||
|
@ -253,7 +268,9 @@ void DrawItemSelection::run(const SceneContextPointer& sceneContext,
|
||||||
for (const auto& itemID : inSelection.partialSubcellItems) {
|
for (const auto& itemID : inSelection.partialSubcellItems) {
|
||||||
auto& item = scene->getItem(itemID);
|
auto& item = scene->getItem(itemID);
|
||||||
auto itemBound = item.getBound();
|
auto itemBound = item.getBound();
|
||||||
|
auto itemCell = scene->getSpatialTree().getCellLocation(item.getCell());
|
||||||
|
glm::ivec4 cellLocation(0, 0, 1, itemCell.depth);
|
||||||
|
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
|
||||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
|
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)(&itemBound.getCorner()));
|
||||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
|
batch._glUniform3fv(_drawItemBoundDimLoc, 1, (const float*)(&itemBound.getScale()));
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,9 @@ namespace render {
|
||||||
Q_PROPERTY(bool showVisibleCells MEMBER showVisibleCells WRITE setShowVisibleCells)
|
Q_PROPERTY(bool showVisibleCells MEMBER showVisibleCells WRITE setShowVisibleCells)
|
||||||
Q_PROPERTY(bool showEmptyCells MEMBER showEmptyCells WRITE setShowEmptyCells)
|
Q_PROPERTY(bool showEmptyCells MEMBER showEmptyCells WRITE setShowEmptyCells)
|
||||||
Q_PROPERTY(bool freezeFrustum MEMBER freezeFrustum WRITE setFreezeFrustum)
|
Q_PROPERTY(bool freezeFrustum MEMBER freezeFrustum WRITE setFreezeFrustum)
|
||||||
|
Q_PROPERTY(int numAllocatedCells READ getNumAllocatedCells)
|
||||||
|
Q_PROPERTY(int numFreeCells READ getNumFreeCells)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DrawSceneOctreeConfig() : Job::Config(false) {}
|
DrawSceneOctreeConfig() : Job::Config(false) {}
|
||||||
|
@ -31,6 +34,12 @@ namespace render {
|
||||||
bool showEmptyCells{ false };
|
bool showEmptyCells{ false };
|
||||||
bool freezeFrustum{ false };
|
bool freezeFrustum{ false };
|
||||||
|
|
||||||
|
int numAllocatedCells{ 0 };
|
||||||
|
int numFreeCells{ 0 };
|
||||||
|
|
||||||
|
int getNumAllocatedCells() const { return numAllocatedCells; }
|
||||||
|
int getNumFreeCells() const { return numFreeCells; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setShowVisibleCells(bool show) { showVisibleCells = show; emit dirty(); }
|
void setShowVisibleCells(bool show) { showVisibleCells = show; emit dirty(); }
|
||||||
void setShowEmptyCells(bool show) { showEmptyCells = show; emit dirty(); }
|
void setShowEmptyCells(bool show) { showEmptyCells = show; emit dirty(); }
|
||||||
|
@ -103,6 +112,7 @@ namespace render {
|
||||||
|
|
||||||
int _drawItemBoundPosLoc = -1;
|
int _drawItemBoundPosLoc = -1;
|
||||||
int _drawItemBoundDimLoc = -1;
|
int _drawItemBoundDimLoc = -1;
|
||||||
|
int _drawCellLocationLoc = -1;
|
||||||
gpu::PipelinePointer _drawItemBoundPipeline;
|
gpu::PipelinePointer _drawItemBoundPipeline;
|
||||||
|
|
||||||
bool _showInsideItems; // initialized by Config
|
bool _showInsideItems; // initialized by Config
|
||||||
|
|
|
@ -109,21 +109,70 @@ Octree::Indices Octree::indexConcreteCellPath(const Locations& path) const {
|
||||||
|
|
||||||
Octree::Index Octree::allocateCell(Index parent, const Location& location) {
|
Octree::Index Octree::allocateCell(Index parent, const Location& location) {
|
||||||
|
|
||||||
if (_cells[parent].asChild(location.octant())) {
|
if (_cells[parent].hasChild(location.octant())) {
|
||||||
assert(_cells[parent].child(location.octant()) == INVALID);
|
assert(_cells[parent].child(location.octant()) == INVALID);
|
||||||
return _cells[parent].child(location.octant());
|
return _cells[parent].child(location.octant());
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(_cells[parent].getlocation().child(location.octant()) == location);
|
assert(_cells[parent].getlocation().child(location.octant()) == location);
|
||||||
|
|
||||||
auto newIndex = (Index) _cells.size();
|
Index newIndex;
|
||||||
_cells.push_back(Cell(parent, location));
|
if (_freeCells.empty()) {
|
||||||
_cells[parent].setChild(location.octant(), newIndex);
|
newIndex = (Index)_cells.size();
|
||||||
|
_cells.push_back(Cell(parent, location));
|
||||||
|
} else {
|
||||||
|
newIndex = _freeCells.back();
|
||||||
|
_freeCells.pop_back();
|
||||||
|
_cells[newIndex] = Cell(parent, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
_cells[parent].setChild(location.octant(), newIndex);
|
||||||
return newIndex;
|
return newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Octree::freeCell(Index index) {
|
||||||
|
if (checkCellIndex(index)) {
|
||||||
|
auto & cell = _cells[index];
|
||||||
|
cell.free();
|
||||||
|
_freeCells.push_back(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::clearCell(Index index) {
|
||||||
|
auto& cell = editCell(index);
|
||||||
|
|
||||||
|
// Free the brick
|
||||||
|
if (cell.hasBrick()) {
|
||||||
|
freeBrick(cell.brick());
|
||||||
|
cell.setBrick(INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the cell ?
|
||||||
|
Index parentIdx = cell.parent();
|
||||||
|
if (!cell.hasParent()) {
|
||||||
|
if (index == ROOT_CELL) {
|
||||||
|
// Stop here, this is the root cell!
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// THis is not expected
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool traverseParent = false;
|
||||||
|
if (!cell.hasChildren()) {
|
||||||
|
editCell(parentIdx).setChild(cell.getlocation().octant(), INVALID);
|
||||||
|
freeCell(index);
|
||||||
|
traverseParent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (traverseParent) {
|
||||||
|
clearCell(parentIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Octree::Indices Octree::indexCellPath(const Locations& path) {
|
Octree::Indices Octree::indexCellPath(const Locations& path) {
|
||||||
// First through the allocated cells
|
// First through the allocated cells
|
||||||
Indices cellPath = indexConcreteCellPath(path);
|
Indices cellPath = indexConcreteCellPath(path);
|
||||||
|
@ -147,13 +196,27 @@ Octree::Indices Octree::indexCellPath(const Locations& path) {
|
||||||
|
|
||||||
|
|
||||||
Octree::Index Octree::allocateBrick() {
|
Octree::Index Octree::allocateBrick() {
|
||||||
Index brickIdx = (int) _bricks.size();
|
if (_freeBricks.empty()) {
|
||||||
_bricks.push_back(Brick());
|
Index brickIdx = (int)_bricks.size();
|
||||||
return brickIdx;
|
_bricks.push_back(Brick());
|
||||||
|
return brickIdx;
|
||||||
|
} else {
|
||||||
|
Index brickIdx = _freeBricks.back();
|
||||||
|
_freeBricks.pop_back();
|
||||||
|
return brickIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::freeBrick(Index index) {
|
||||||
|
if (checkCellIndex(index)) {
|
||||||
|
auto & brick = _bricks[index];
|
||||||
|
// brick.free();
|
||||||
|
_freeBricks.push_back(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Octree::Index Octree::accessCellBrick(Index cellID, const CellBrickAccessor& accessor, bool createBrick) {
|
Octree::Index Octree::accessCellBrick(Index cellID, const CellBrickAccessor& accessor, bool createBrick) {
|
||||||
assert(cellID != INVALID);
|
assert(checkCellIndex(cellID));
|
||||||
auto& cell = editCell(cellID);
|
auto& cell = editCell(cellID);
|
||||||
if (!cell.hasBrick()) {
|
if (!cell.hasBrick()) {
|
||||||
if (!createBrick) {
|
if (!createBrick) {
|
||||||
|
@ -220,6 +283,7 @@ bool ItemSpatialTree::removeItem(Index cellIdx, const ItemKey& key, const ItemID
|
||||||
auto success = false;
|
auto success = false;
|
||||||
|
|
||||||
// Remove the item from the brick
|
// Remove the item from the brick
|
||||||
|
bool emptyCell = false;
|
||||||
accessCellBrick(cellIdx, [&](Cell& cell, Brick& brick, Octree::Index brickID) {
|
accessCellBrick(cellIdx, [&](Cell& cell, Brick& brick, Octree::Index brickID) {
|
||||||
auto& itemList = (key.isSmall() ? brick.subcellItems : brick.items);
|
auto& itemList = (key.isSmall() ? brick.subcellItems : brick.items);
|
||||||
|
|
||||||
|
@ -227,10 +291,16 @@ bool ItemSpatialTree::removeItem(Index cellIdx, const ItemKey& key, const ItemID
|
||||||
|
|
||||||
if (brick.items.empty() && brick.subcellItems.empty()) {
|
if (brick.items.empty() && brick.subcellItems.empty()) {
|
||||||
cell.signalBrickEmpty();
|
cell.signalBrickEmpty();
|
||||||
|
emptyCell = true;
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
}, false); // do not create brick!
|
}, false); // do not create brick!
|
||||||
|
|
||||||
|
|
||||||
|
if (emptyCell) {
|
||||||
|
clearCell(cellIdx);
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +315,11 @@ ItemSpatialTree::Index ItemSpatialTree::resetItem(Index oldCell, const ItemKey&
|
||||||
auto rangeSizef = maxCoordf - minCoordf;
|
auto rangeSizef = maxCoordf - minCoordf;
|
||||||
float cellFitSize = getCellHalfDiagonalSquare(location.depth);
|
float cellFitSize = getCellHalfDiagonalSquare(location.depth);
|
||||||
bool subcellItem = glm::dot(rangeSizef, rangeSizef) < cellFitSize;
|
bool subcellItem = glm::dot(rangeSizef, rangeSizef) < cellFitSize;
|
||||||
newKey.setSmaller(subcellItem);
|
if (subcellItem) {
|
||||||
|
newKey.setSmaller(subcellItem);
|
||||||
|
} else {
|
||||||
|
newKey.setSmaller(false);
|
||||||
|
}
|
||||||
|
|
||||||
auto newCell = indexCell(location);
|
auto newCell = indexCell(location);
|
||||||
|
|
||||||
|
@ -461,3 +535,6 @@ int ItemSpatialTree::selectCellItems(ItemSelection& selection, const ItemFilter&
|
||||||
|
|
||||||
return (int) selection.numItems();
|
return (int) selection.numItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -172,13 +172,23 @@ namespace render {
|
||||||
// the cell description
|
// the cell description
|
||||||
class Cell {
|
class Cell {
|
||||||
public:
|
public:
|
||||||
|
void free() { _location = Location(); for (auto& link : _links) { link = INVALID; } }
|
||||||
|
|
||||||
const Location& getlocation() const { return _location; }
|
const Location& getlocation() const { return _location; }
|
||||||
|
|
||||||
Index parent() const { return _links[Parent]; }
|
Index parent() const { return _links[Parent]; }
|
||||||
bool asParent() const { return parent() != INVALID; }
|
bool hasParent() const { return parent() != INVALID; }
|
||||||
|
|
||||||
Index child(Link octant) const { return _links[octant]; }
|
Index child(Link octant) const { return _links[octant]; }
|
||||||
bool asChild(Link octant) const { return child(octant) != INVALID; }
|
bool hasChild(Link octant) const { return child(octant) != INVALID; }
|
||||||
|
bool hasChildren() const {
|
||||||
|
for (LinkStorage octant = Octant_L_B_N; octant < NUM_OCTANTS; octant++) {
|
||||||
|
if (hasChild((Link)octant)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void setChild(Link octant, Index child) { _links[octant] = child; }
|
void setChild(Link octant, Index child) { _links[octant] = child; }
|
||||||
|
|
||||||
Index brick() const { return _links[BrickLink]; }
|
Index brick() const { return _links[BrickLink]; }
|
||||||
|
@ -205,13 +215,17 @@ namespace render {
|
||||||
|
|
||||||
using Bricks = std::vector< Brick >;
|
using Bricks = std::vector< Brick >;
|
||||||
|
|
||||||
|
bool checkCellIndex(Index index) const { return (index >= 0) && (index < _cells.size()); }
|
||||||
// Octree members
|
bool checkBrickIndex(Index index) const { return (index >= 0) && (index < _bricks.size()); }
|
||||||
Cells _cells = Cells(1, Cell()); // start with only the Cell root
|
|
||||||
Bricks _bricks;
|
|
||||||
|
|
||||||
Octree() {};
|
Octree() {};
|
||||||
|
|
||||||
|
// Clear a cell:
|
||||||
|
// Check that the cell brick is empty, if so free it
|
||||||
|
// CHeck that the cell has no children, if so free itself
|
||||||
|
// Apply the same logic to the parent cell
|
||||||
|
void clearCell(Index index);
|
||||||
|
|
||||||
// Indexing/Allocating the cells as the tree gets populated
|
// Indexing/Allocating the cells as the tree gets populated
|
||||||
// Return the cell Index/Indices at the specified location/path, allocate all the cells on the path from the root if needed
|
// Return the cell Index/Indices at the specified location/path, allocate all the cells on the path from the root if needed
|
||||||
Indices indexCellPath(const Locations& path);
|
Indices indexCellPath(const Locations& path);
|
||||||
|
@ -223,7 +237,7 @@ namespace render {
|
||||||
|
|
||||||
// Get the cell location from the CellID
|
// Get the cell location from the CellID
|
||||||
Location getCellLocation(Index cellID) const {
|
Location getCellLocation(Index cellID) const {
|
||||||
if ((cellID >= 0) && (cellID < _cells.size())) {
|
if (checkCellIndex(cellID)) {
|
||||||
return getConcreteCell(cellID).getlocation();
|
return getConcreteCell(cellID).getlocation();
|
||||||
}
|
}
|
||||||
return Location();
|
return Location();
|
||||||
|
@ -231,12 +245,10 @@ namespace render {
|
||||||
|
|
||||||
// Reach a concrete cell
|
// Reach a concrete cell
|
||||||
const Cell& getConcreteCell(Index index) const {
|
const Cell& getConcreteCell(Index index) const {
|
||||||
assert(index < _cells.size());
|
assert(checkCellIndex(index));
|
||||||
return _cells[index];
|
return _cells[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Let s talk about the Cell Bricks now
|
// Let s talk about the Cell Bricks now
|
||||||
using CellBrickAccessor = std::function<void(Cell& cell, Brick& brick, Index brickIdx)>;
|
using CellBrickAccessor = std::function<void(Cell& cell, Brick& brick, Index brickIdx)>;
|
||||||
|
|
||||||
|
@ -244,9 +256,8 @@ namespace render {
|
||||||
// This returns the Brick index
|
// This returns the Brick index
|
||||||
Index accessCellBrick(Index cellID, const CellBrickAccessor& accessor, bool createBrick = true);
|
Index accessCellBrick(Index cellID, const CellBrickAccessor& accessor, bool createBrick = true);
|
||||||
|
|
||||||
|
|
||||||
const Brick& getConcreteBrick(Index index) const {
|
const Brick& getConcreteBrick(Index index) const {
|
||||||
assert(index < _bricks.size());
|
assert(checkBrickIndex(index));
|
||||||
return _bricks[index];
|
return _bricks[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,15 +308,28 @@ namespace render {
|
||||||
int selectBranch(Index cellID, CellSelection& selection, const FrustumSelector& selector) const;
|
int selectBranch(Index cellID, CellSelection& selection, const FrustumSelector& selector) const;
|
||||||
int selectCellBrick(Index cellID, CellSelection& selection, bool inside) const;
|
int selectCellBrick(Index cellID, CellSelection& selection, bool inside) const;
|
||||||
|
|
||||||
|
|
||||||
|
int getNumAllocatedCells() const { return (int)_cells.size(); }
|
||||||
|
int getNumFreeCells() const { return (int)_freeCells.size(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Index allocateCell(Index parent, const Location& location);
|
Index allocateCell(Index parent, const Location& location);
|
||||||
|
void freeCell(Index index);
|
||||||
|
|
||||||
Index allocateBrick();
|
Index allocateBrick();
|
||||||
|
void freeBrick(Index index);
|
||||||
|
|
||||||
Cell& editCell(Index index) {
|
Cell& editCell(Index index) {
|
||||||
assert(index < _cells.size());
|
assert(checkCellIndex(index));
|
||||||
return _cells[index];
|
return _cells[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Octree members
|
||||||
|
Cells _cells = Cells(1, Cell()); // start with only the Cell root
|
||||||
|
Bricks _bricks;
|
||||||
|
Indices _freeCells; // stack of free cells to be reused for allocation
|
||||||
|
Indices _freeBricks; // stack of free bricks to be reused for allocation
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,5 +19,11 @@ out vec4 outFragColor;
|
||||||
void main(void) {
|
void main(void) {
|
||||||
float var = step(fract(varTexcoord.x * varTexcoord.y * 1.0), 0.5);
|
float var = step(fract(varTexcoord.x * varTexcoord.y * 1.0), 0.5);
|
||||||
|
|
||||||
outFragColor = vec4(mix(vec3(1.0), varColor.xyz, var), varColor.a);
|
if (varColor.a == 0) {
|
||||||
|
outFragColor = vec4(mix(vec3(0.0), varColor.xyz, var), mix(0.0, 1.0, var));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
outFragColor = vec4(mix(vec3(1.0), varColor.xyz, var), varColor.a);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,9 @@ void main(void) {
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, pos, gl_Position)$>
|
<$transformModelToClipPos(cam, obj, pos, gl_Position)$>
|
||||||
|
|
||||||
varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 1.0);
|
bool subcell = bool((inCellLocation.z));
|
||||||
|
float cellDepth = float(inCellLocation.w);
|
||||||
|
varColor = vec4(colorWheel(fract(cellDepth / 5.0)), 1.0 - float(subcell));
|
||||||
varTexcoord = vec2(cubeVec.w, length(inBoundDim));
|
varTexcoord = vec2(cubeVec.w, length(inBoundDim));
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue