mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 09:33:36 +02:00
clening up the BRick insert item interface and the shaders
This commit is contained in:
parent
2a5aab6dc8
commit
7b50a4d05f
8 changed files with 192 additions and 104 deletions
|
@ -34,9 +34,7 @@ const gpu::PipelinePointer DrawSceneOctree::getDrawCellBoundsPipeline() {
|
|||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
_drawBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
|
||||
_drawBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
|
||||
|
||||
_drawCellLocationLoc = program->getUniforms().findLocation("inCellLocation");
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
|
@ -69,10 +67,7 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
|||
if (!_cells) {
|
||||
_cells = std::make_shared<gpu::Buffer>();
|
||||
}
|
||||
/* if (!_octreeInfo) {
|
||||
_octreeInfo = std::make_shared<gpu::Buffer>();;
|
||||
}*/
|
||||
|
||||
|
||||
const auto& inCells = scene->getSpatialTree()._cells;
|
||||
_cells->resize(inCells.size() * sizeof(AABox));
|
||||
AABox* cellAABox = reinterpret_cast<AABox*> (_cells->editData());
|
||||
|
@ -102,15 +97,9 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
|||
// bind the one gpu::Pipeline we need
|
||||
batch.setPipeline(getDrawCellBoundsPipeline());
|
||||
|
||||
AABox* cellAABox = reinterpret_cast<AABox*> (_cells->editData());
|
||||
|
||||
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
||||
const auto& inCells = scene->getSpatialTree()._cells;
|
||||
|
||||
for (int i = 0; i < nbCells; i++) {
|
||||
batch._glUniform3fv(_drawBoundPosLoc, 1, (const float*) (cellAABox + i));
|
||||
batch._glUniform3fv(_drawBoundDimLoc, 1, ((const float*)(cellAABox + i)) + VEC3_ADRESS_OFFSET);
|
||||
|
||||
auto& cellLoc = inCells[i].getlocation();
|
||||
glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth);
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
namespace render {
|
||||
class DrawSceneOctree {
|
||||
|
||||
int _drawBoundPosLoc;
|
||||
int _drawBoundDimLoc;
|
||||
int _drawCellLocationLoc;
|
||||
gpu::PipelinePointer _drawCellBoundsPipeline;
|
||||
gpu::BufferPointer _cells;
|
||||
|
|
|
@ -191,6 +191,7 @@ inline QDebug operator<<(QDebug debug, const ItemFilter& me) {
|
|||
}
|
||||
|
||||
using ItemID = uint32_t;
|
||||
using ItemCell = int32_t;
|
||||
|
||||
class Item {
|
||||
public:
|
||||
|
@ -198,6 +199,7 @@ public:
|
|||
typedef ItemID ID;
|
||||
|
||||
static const ID INVALID_ITEM_ID = 0;
|
||||
static const ItemCell INVALID_CELL = -1;
|
||||
|
||||
// Bound is the AABBox fully containing this item
|
||||
typedef AABox Bound;
|
||||
|
@ -292,12 +294,16 @@ public:
|
|||
|
||||
// Main scene / item managment interface Reset/Update/Kill
|
||||
void resetPayload(const PayloadPointer& payload);
|
||||
void resetCell(ItemCell cell) { _cell = cell; }
|
||||
void update(const UpdateFunctorPointer& updateFunctor) { _payload->update(updateFunctor); } // Communicate update to the payload
|
||||
void kill() { _payload.reset(); _key._flags.reset(); } // Kill means forget the payload and key
|
||||
void kill() { _payload.reset(); _key._flags.reset(); _cell = INVALID_CELL; } // Kill means forget the payload and key and cell
|
||||
|
||||
// Check heuristic key
|
||||
const ItemKey& getKey() const { return _key; }
|
||||
|
||||
// Check spatial cell
|
||||
const ItemCell& getCell() const { return _cell; }
|
||||
|
||||
// Payload Interface
|
||||
|
||||
// Get the bound of the item expressed in world space (or eye space depending on the key.isWorldSpace())
|
||||
|
@ -318,6 +324,7 @@ public:
|
|||
protected:
|
||||
PayloadPointer _payload;
|
||||
ItemKey _key;
|
||||
ItemCell _cell{ INVALID_CELL };
|
||||
|
||||
friend class Scene;
|
||||
};
|
||||
|
|
|
@ -67,7 +67,7 @@ Octree::Location Octree::Location::evalFromRange(const Coord3& minCoord, const C
|
|||
}
|
||||
}
|
||||
|
||||
Octree::Indices Octree::indexAllocatedCellPath(const Locations& path) const {
|
||||
Octree::Indices Octree::indexConcreteCellPath(const Locations& path) const {
|
||||
Index currentIndex = ROOT;
|
||||
Indices cellPath(1, currentIndex);
|
||||
|
||||
|
@ -105,7 +105,7 @@ Octree::Index Octree::allocateCell(Index parent, const Location& location) {
|
|||
|
||||
Octree::Indices Octree::indexCellPath(const Locations& path) {
|
||||
// First through the aallocated cells
|
||||
Indices cellPath = indexAllocatedCellPath(path);
|
||||
Indices cellPath = indexConcreteCellPath(path);
|
||||
|
||||
// Catch up from the last allocated cell on the path
|
||||
auto currentIndex = cellPath.back();
|
||||
|
@ -131,34 +131,86 @@ Octree::Index Octree::allocateBrick() {
|
|||
return brickIdx;
|
||||
}
|
||||
|
||||
Octree::Index Octree::accessCellBrick(const Location& loc, const CellBrickAccessor& accessor) {
|
||||
auto cellId = indexCell(loc);
|
||||
auto cell = editCell(cellId);
|
||||
Octree::Index Octree::accessCellBrick(Index cellID, const CellBrickAccessor& accessor, bool createBrick) {
|
||||
assert(cellID != INVALID);
|
||||
auto cell = editCell(cellID);
|
||||
if (!cell.asBrick()) {
|
||||
if (!createBrick) {
|
||||
return INVALID;
|
||||
}
|
||||
cell.setBrick(allocateBrick());
|
||||
}
|
||||
|
||||
// access the brick
|
||||
auto& brick = _bricks[cell.brick()];
|
||||
auto brickID = cell.brick();
|
||||
auto& brick = _bricks[brickID];
|
||||
|
||||
// execute the accessor
|
||||
accessor(brick, cell.brick());
|
||||
accessor(brick, brickID);
|
||||
|
||||
return cell.brick();
|
||||
return brickID;
|
||||
}
|
||||
|
||||
void ItemSpatialTree::insert(const ItemBounds& items) {
|
||||
for (auto& item : items) {
|
||||
if (!item.bound.isNull()) {
|
||||
auto cellIdx = indexCell(evalLocation(item.bound));
|
||||
|
||||
accessCellBrick(evalLocation(item.bound), [&] (Brick& brick, Octree::Index cellID) {
|
||||
brick.items.push_back(item.id);
|
||||
});
|
||||
Octree::Locations ItemSpatialTree::evalLocations(const ItemBounds& bounds) const {
|
||||
Locations locations;
|
||||
locations.reserve(bounds.size());
|
||||
for (auto& bound : bounds) {
|
||||
if (!bound.bound.isNull()) {
|
||||
locations.emplace_back(evalLocation(bound.bound));
|
||||
} else {
|
||||
locations.emplace_back(Location());
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
ItemSpatialTree::Index ItemSpatialTree::insertItem(const Location& location, const ItemID& item) {
|
||||
// Go to the cell
|
||||
auto cellIdx = indexCell(location);
|
||||
|
||||
// Add the item to the brick (and a brick if needed)
|
||||
accessCellBrick(cellIdx, [&](Brick& brick, Octree::Index cellID) {
|
||||
brick.items.push_back(item);
|
||||
}, true);
|
||||
|
||||
return cellIdx;
|
||||
}
|
||||
|
||||
bool ItemSpatialTree::removeItem(Index cellIdx, const ItemID& item) {
|
||||
auto success = false;
|
||||
|
||||
// Access the brick at the cell (without createing new ones)
|
||||
auto brickIdx = accessCellBrick(cellIdx, [&](Brick& brick, Octree::Index brickID) {
|
||||
// remove the item from the list
|
||||
brick.items.erase(std::find(brick.items.begin(), brick.items.end(), item));
|
||||
success = true;
|
||||
}, false); // do not create brick!
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
ItemSpatialTree::Index ItemSpatialTree::resetItem(Index oldCell, const Location& location, const ItemID& item) {
|
||||
// do we know about this item ?
|
||||
if (oldCell == Item::INVALID_CELL) {
|
||||
auto newCell = insertItem(location, item);
|
||||
return newCell;
|
||||
} else {
|
||||
auto newCell = indexCell(location);
|
||||
|
||||
accessCellBrick(newCell, [&](Brick& brick, Octree::Index brickID) {
|
||||
// insert the item only if the new cell is different from the previous one
|
||||
if (newCell != oldCell) {
|
||||
brick.items.push_back(item);
|
||||
}
|
||||
}, true);
|
||||
|
||||
// now we know where the cell has been added and where it was,
|
||||
// if different then go clean the previous cell
|
||||
if (newCell != oldCell) {
|
||||
removeItem(oldCell, item);
|
||||
}
|
||||
|
||||
return newCell;
|
||||
}
|
||||
}
|
||||
|
||||
void ItemSpatialTree::erase(const ItemBounds& items) {
|
||||
|
||||
}
|
|
@ -144,7 +144,7 @@ namespace render {
|
|||
using Locations = Location::vector;
|
||||
|
||||
// Cell or Brick Indexing
|
||||
using Index = int32_t;
|
||||
using Index = ItemCell; // int32_t
|
||||
static const Index INVALID = -1;
|
||||
static const Index ROOT = 0;
|
||||
using Indices = std::vector<Index>;
|
||||
|
@ -194,9 +194,9 @@ namespace render {
|
|||
Indices indexCellPath(const Locations& path);
|
||||
Index indexCell(const Location& loc) { return indexCellPath(Location::pathTo(loc)).back(); }
|
||||
|
||||
// Same as indexCellPath except that NO cells are allocated,
|
||||
// Same as indexCellPath except that NO cells are allocated, only the COncrete cells previously allocated
|
||||
// the returned indices stops at the last existing cell on the requested path.
|
||||
Indices indexAllocatedCellPath(const Locations& path) const;
|
||||
Indices indexConcreteCellPath(const Locations& path) const;
|
||||
|
||||
// Reach a concrete cell
|
||||
const Cell& getCell(Index index) const {
|
||||
|
@ -209,7 +209,10 @@ namespace render {
|
|||
// Let s talk about the Cell Bricks now
|
||||
using CellBrickAccessor = std::function<void(Brick& brick, Index brickIdx)>;
|
||||
|
||||
Index accessCellBrick(const Location& loc, const CellBrickAccessor& accessor);
|
||||
// acces a cell (must be concrete), then call the brick accessor if the brick exists ( or is just created if authorized to)
|
||||
// This returns the Brick index
|
||||
Index accessCellBrick(Index cellID, const CellBrickAccessor& accessor, bool createBrick = true);
|
||||
|
||||
|
||||
const Brick& getBrick(Index index) const {
|
||||
assert(index < _bricks.size());
|
||||
|
@ -258,19 +261,22 @@ namespace render {
|
|||
}
|
||||
|
||||
|
||||
// Bound to Location
|
||||
AABox evalBound(const Location& loc) const {
|
||||
float cellWidth = getCellWidth(loc.depth);
|
||||
return AABox(evalPos(loc.pos, cellWidth), cellWidth);
|
||||
}
|
||||
|
||||
Location evalLocation(const AABox& bound) const {
|
||||
return Location::evalFromRange(evalCoord(bound.getMinimumPoint()), evalCoord(bound.getMaximumPoint()));
|
||||
}
|
||||
Locations evalLocations(const ItemBounds& bounds) const;
|
||||
|
||||
// Managing itemsInserting items in cells
|
||||
Index insertItem(const Location& location, const ItemID& item);
|
||||
bool removeItem(Index cellIdx, const ItemID& item);
|
||||
Index resetItem(Index oldCell, const Location& location, const ItemID& item);
|
||||
|
||||
ItemSpatialTree() {}
|
||||
|
||||
void insert(const ItemBounds& items);
|
||||
void erase(const ItemBounds& items);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -129,22 +129,28 @@ void Scene::processPendingChangesQueue() {
|
|||
}
|
||||
|
||||
void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) {
|
||||
auto resetID = ids.begin();
|
||||
auto resetPayload = payloads.begin();
|
||||
ItemBounds itemBounds;
|
||||
itemBounds.reserve(ids.size());
|
||||
|
||||
for (;resetID != ids.end(); resetID++, resetPayload++) {
|
||||
auto& item = _items[(*resetID)];
|
||||
|
||||
auto& resetPayload = payloads.begin();
|
||||
for (auto resetID : ids) {
|
||||
// Access the true item
|
||||
auto& item = _items[resetID];
|
||||
auto oldKey = item.getKey();
|
||||
auto oldCell = item.getCell();
|
||||
|
||||
// Reset the item with a new payload
|
||||
item.resetPayload(*resetPayload);
|
||||
|
||||
_masterBucketMap.reset((*resetID), oldKey, item.getKey());
|
||||
// Reset the item in the Bucket map
|
||||
_masterBucketMap.reset(resetID, oldKey, item.getKey());
|
||||
|
||||
itemBounds.emplace_back(ItemBound((*resetID), item.getBound()));
|
||||
// Reset the item in the spatial tree
|
||||
auto newCellLocation = _masterSpatialTree.evalLocation(item.getBound());
|
||||
auto newCell = _masterSpatialTree.resetItem(oldCell, newCellLocation, resetID);
|
||||
item.resetCell(newCell);
|
||||
|
||||
// next loop
|
||||
resetPayload++;
|
||||
}
|
||||
|
||||
_masterSpatialTree.insert(itemBounds);
|
||||
}
|
||||
|
||||
void Scene::removeItems(const ItemIDs& ids) {
|
||||
|
|
76
libraries/render/src/render/SceneOctree.slh
Normal file
76
libraries/render/src/render/SceneOctree.slh
Normal file
|
@ -0,0 +1,76 @@
|
|||
<!
|
||||
// render/SceneOctree.slh
|
||||
//
|
||||
// Created by Sam Gateau on 1/29/16.
|
||||
// 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
|
||||
!>
|
||||
<@if not RENDER_OCTREE_SLH@>
|
||||
<@def RENDER_OCTREE_SLH@>
|
||||
|
||||
const float _size = 32768.0;
|
||||
const float _invSize = 1.0 / _size;
|
||||
const vec3 _origin = vec3(-16384.0);
|
||||
|
||||
float getSize() { return _size; }
|
||||
vec3 getOrigin() { return _origin; }
|
||||
|
||||
const int MAX_DEPTH = 15;
|
||||
const float DEPTH_DIM[16] = float[16](
|
||||
1.0,
|
||||
2.0,
|
||||
4.0,
|
||||
8.0,
|
||||
16.0,
|
||||
32.0,
|
||||
64.0,
|
||||
128.0,
|
||||
256.0,
|
||||
512.0,
|
||||
1024.0,
|
||||
2048.0,
|
||||
4096.0,
|
||||
8192.0,
|
||||
16384.0,
|
||||
32768.0 );
|
||||
const float INV_DEPTH_DIM[16] = float[16](
|
||||
1.0,
|
||||
1.0 / 2.0,
|
||||
1.0 / 4.0,
|
||||
1.0 / 8.0,
|
||||
1.0 / 16.0,
|
||||
1.0 / 32.0,
|
||||
1.0 / 64.0,
|
||||
1.0 / 128.0,
|
||||
1.0 / 256.0,
|
||||
1.0 / 512.0,
|
||||
1.0 / 1024.0,
|
||||
1.0 / 2048.0,
|
||||
1.0 / 4096.0,
|
||||
1.0 / 8192.0,
|
||||
1.0 / 16384.0,
|
||||
1.0 / 32768.0 );
|
||||
|
||||
int getDepthDimension(int depth) { return 1 << depth; }
|
||||
float getDepthDimensionf(int depth) { return DEPTH_DIM[depth]; }
|
||||
float getInvDepthDimension(int depth) { return INV_DEPTH_DIM[depth]; }
|
||||
|
||||
float getCellWidth(int depth) { return _size * getInvDepthDimension(depth); }
|
||||
float getInvCellWidth(int depth) { return getDepthDimensionf(depth) * _invSize; }
|
||||
|
||||
vec3 evalPos(ivec3 coord, int depth = MAX_DEPTH) {
|
||||
return getOrigin() + vec3(coord) * getCellWidth(depth);
|
||||
}
|
||||
vec3 evalPosDepthWidth(ivec3 coord, float cellWidth) {
|
||||
return getOrigin() + vec3(coord) * cellWidth;
|
||||
}
|
||||
|
||||
vec4 evalBound(ivec4 loc) {
|
||||
float cellWidth = getCellWidth(loc.w);
|
||||
return vec4(evalPosDepthWidth(loc.xyz, cellWidth), cellWidth);
|
||||
}
|
||||
|
||||
|
||||
<@endif@>
|
|
@ -19,56 +19,8 @@
|
|||
<@include gpu/Color.slh@>
|
||||
<$declareColorWheel()$>
|
||||
|
||||
<!
|
||||
uniform ivec4 inCellLocation;
|
||||
<@include SceneOctree.slh@>
|
||||
|
||||
const float _size = 32768.0;
|
||||
const float _invSize = 1.0 / _size;
|
||||
const vec3 _origin = vec3(-16384.0);
|
||||
|
||||
float getSize() { return _size; }
|
||||
vec3 getOrigin() { return _origin; }
|
||||
|
||||
const int MAX_DEPTH = 15;
|
||||
const float INV_DEPTH_DIM[16] = float[16](
|
||||
1.0,
|
||||
1.0 / 2.0,
|
||||
1.0 / 4.0,
|
||||
1.0 / 8.0,
|
||||
1.0 / 16.0,
|
||||
1.0 / 32.0,
|
||||
1.0 / 64.0,
|
||||
1.0 / 128.0,
|
||||
1.0 / 256.0,
|
||||
1.0 / 512.0,
|
||||
1.0 / 1024.0,
|
||||
1.0 / 2048.0,
|
||||
1.0 / 4096.0,
|
||||
1.0 / 8192.0,
|
||||
1.0 / 16384.0,
|
||||
1.0 / 32768.0 );
|
||||
|
||||
int getDepthDimension(int depth) { return 1 << depth; }
|
||||
float getInvDepthDimension(int depth) { return INV_DEPTH_DIM[depth]; }
|
||||
|
||||
float getCellWidth(int depth) { return _size * getInvDepthDimension(depth); }
|
||||
float getInvCellWidth(int depth) { return float(getDepthDimension(depth)) * _invSize; }
|
||||
|
||||
vec3 evalPos(ivec3 coord, int depth = MAX_DEPTH) {
|
||||
return getOrigin() + vec3(coord) * getCellWidth(depth);
|
||||
}
|
||||
vec3 evalPos(ivec3 coord, float cellWidth) {
|
||||
return getOrigin() + vec3(coord) * cellWidth;
|
||||
}
|
||||
|
||||
vec4 evalBound(ivec4 loc) {
|
||||
float cellWidth = getCellWidth(loc.w);
|
||||
return vec4(evalPos(loc.xyz, cellWidth), cellWidth);
|
||||
}
|
||||
!>
|
||||
|
||||
uniform vec3 inBoundPos;
|
||||
uniform vec3 inBoundDim;
|
||||
uniform ivec4 inCellLocation;
|
||||
|
||||
out vec4 varColor;
|
||||
|
@ -101,7 +53,9 @@ void main(void) {
|
|||
);
|
||||
vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
|
||||
|
||||
pos.xyz = inBoundPos + inBoundDim * pos.xyz;
|
||||
vec4 cellBound = evalBound(inCellLocation);
|
||||
|
||||
pos.xyz = cellBound.xyz + vec3(cellBound.w) * pos.xyz;
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
|
Loading…
Reference in a new issue