mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:21:16 +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::BindingSet slotBindings;
|
||||||
gpu::Shader::makeProgram(*program, slotBindings);
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
_drawBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
|
|
||||||
_drawBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
|
|
||||||
_drawCellLocationLoc = program->getUniforms().findLocation("inCellLocation");
|
_drawCellLocationLoc = program->getUniforms().findLocation("inCellLocation");
|
||||||
|
|
||||||
auto state = std::make_shared<gpu::State>();
|
auto state = std::make_shared<gpu::State>();
|
||||||
|
@ -69,10 +67,7 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
||||||
if (!_cells) {
|
if (!_cells) {
|
||||||
_cells = std::make_shared<gpu::Buffer>();
|
_cells = std::make_shared<gpu::Buffer>();
|
||||||
}
|
}
|
||||||
/* if (!_octreeInfo) {
|
|
||||||
_octreeInfo = std::make_shared<gpu::Buffer>();;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
const auto& inCells = scene->getSpatialTree()._cells;
|
const auto& inCells = scene->getSpatialTree()._cells;
|
||||||
_cells->resize(inCells.size() * sizeof(AABox));
|
_cells->resize(inCells.size() * sizeof(AABox));
|
||||||
AABox* cellAABox = reinterpret_cast<AABox*> (_cells->editData());
|
AABox* cellAABox = reinterpret_cast<AABox*> (_cells->editData());
|
||||||
|
@ -102,15 +97,9 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
||||||
// bind the one gpu::Pipeline we need
|
// bind the one gpu::Pipeline we need
|
||||||
batch.setPipeline(getDrawCellBoundsPipeline());
|
batch.setPipeline(getDrawCellBoundsPipeline());
|
||||||
|
|
||||||
AABox* cellAABox = reinterpret_cast<AABox*> (_cells->editData());
|
|
||||||
|
|
||||||
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
|
||||||
const auto& inCells = scene->getSpatialTree()._cells;
|
const auto& inCells = scene->getSpatialTree()._cells;
|
||||||
|
|
||||||
for (int i = 0; i < nbCells; i++) {
|
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();
|
auto& cellLoc = inCells[i].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);
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
namespace render {
|
namespace render {
|
||||||
class DrawSceneOctree {
|
class DrawSceneOctree {
|
||||||
|
|
||||||
int _drawBoundPosLoc;
|
|
||||||
int _drawBoundDimLoc;
|
|
||||||
int _drawCellLocationLoc;
|
int _drawCellLocationLoc;
|
||||||
gpu::PipelinePointer _drawCellBoundsPipeline;
|
gpu::PipelinePointer _drawCellBoundsPipeline;
|
||||||
gpu::BufferPointer _cells;
|
gpu::BufferPointer _cells;
|
||||||
|
|
|
@ -191,6 +191,7 @@ inline QDebug operator<<(QDebug debug, const ItemFilter& me) {
|
||||||
}
|
}
|
||||||
|
|
||||||
using ItemID = uint32_t;
|
using ItemID = uint32_t;
|
||||||
|
using ItemCell = int32_t;
|
||||||
|
|
||||||
class Item {
|
class Item {
|
||||||
public:
|
public:
|
||||||
|
@ -198,6 +199,7 @@ public:
|
||||||
typedef ItemID ID;
|
typedef ItemID ID;
|
||||||
|
|
||||||
static const ID INVALID_ITEM_ID = 0;
|
static const ID INVALID_ITEM_ID = 0;
|
||||||
|
static const ItemCell INVALID_CELL = -1;
|
||||||
|
|
||||||
// Bound is the AABBox fully containing this item
|
// Bound is the AABBox fully containing this item
|
||||||
typedef AABox Bound;
|
typedef AABox Bound;
|
||||||
|
@ -292,12 +294,16 @@ public:
|
||||||
|
|
||||||
// Main scene / item managment interface Reset/Update/Kill
|
// Main scene / item managment interface Reset/Update/Kill
|
||||||
void resetPayload(const PayloadPointer& payload);
|
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 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
|
// Check heuristic key
|
||||||
const ItemKey& getKey() const { return _key; }
|
const ItemKey& getKey() const { return _key; }
|
||||||
|
|
||||||
|
// Check spatial cell
|
||||||
|
const ItemCell& getCell() const { return _cell; }
|
||||||
|
|
||||||
// Payload Interface
|
// Payload Interface
|
||||||
|
|
||||||
// Get the bound of the item expressed in world space (or eye space depending on the key.isWorldSpace())
|
// Get the bound of the item expressed in world space (or eye space depending on the key.isWorldSpace())
|
||||||
|
@ -318,6 +324,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
PayloadPointer _payload;
|
PayloadPointer _payload;
|
||||||
ItemKey _key;
|
ItemKey _key;
|
||||||
|
ItemCell _cell{ INVALID_CELL };
|
||||||
|
|
||||||
friend class Scene;
|
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;
|
Index currentIndex = ROOT;
|
||||||
Indices cellPath(1, currentIndex);
|
Indices cellPath(1, currentIndex);
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ Octree::Index Octree::allocateCell(Index parent, const Location& location) {
|
||||||
|
|
||||||
Octree::Indices Octree::indexCellPath(const Locations& path) {
|
Octree::Indices Octree::indexCellPath(const Locations& path) {
|
||||||
// First through the aallocated cells
|
// First through the aallocated cells
|
||||||
Indices cellPath = indexAllocatedCellPath(path);
|
Indices cellPath = indexConcreteCellPath(path);
|
||||||
|
|
||||||
// Catch up from the last allocated cell on the path
|
// Catch up from the last allocated cell on the path
|
||||||
auto currentIndex = cellPath.back();
|
auto currentIndex = cellPath.back();
|
||||||
|
@ -131,34 +131,86 @@ Octree::Index Octree::allocateBrick() {
|
||||||
return brickIdx;
|
return brickIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
Octree::Index Octree::accessCellBrick(const Location& loc, const CellBrickAccessor& accessor) {
|
Octree::Index Octree::accessCellBrick(Index cellID, const CellBrickAccessor& accessor, bool createBrick) {
|
||||||
auto cellId = indexCell(loc);
|
assert(cellID != INVALID);
|
||||||
auto cell = editCell(cellId);
|
auto cell = editCell(cellID);
|
||||||
if (!cell.asBrick()) {
|
if (!cell.asBrick()) {
|
||||||
|
if (!createBrick) {
|
||||||
|
return INVALID;
|
||||||
|
}
|
||||||
cell.setBrick(allocateBrick());
|
cell.setBrick(allocateBrick());
|
||||||
}
|
}
|
||||||
|
|
||||||
// access the brick
|
// access the brick
|
||||||
auto& brick = _bricks[cell.brick()];
|
auto brickID = cell.brick();
|
||||||
|
auto& brick = _bricks[brickID];
|
||||||
|
|
||||||
// execute the accessor
|
// execute the accessor
|
||||||
accessor(brick, cell.brick());
|
accessor(brick, brickID);
|
||||||
|
|
||||||
return cell.brick();
|
return brickID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemSpatialTree::insert(const ItemBounds& items) {
|
Octree::Locations ItemSpatialTree::evalLocations(const ItemBounds& bounds) const {
|
||||||
for (auto& item : items) {
|
Locations locations;
|
||||||
if (!item.bound.isNull()) {
|
locations.reserve(bounds.size());
|
||||||
auto cellIdx = indexCell(evalLocation(item.bound));
|
for (auto& bound : bounds) {
|
||||||
|
if (!bound.bound.isNull()) {
|
||||||
accessCellBrick(evalLocation(item.bound), [&] (Brick& brick, Octree::Index cellID) {
|
locations.emplace_back(evalLocation(bound.bound));
|
||||||
brick.items.push_back(item.id);
|
} 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;
|
using Locations = Location::vector;
|
||||||
|
|
||||||
// Cell or Brick Indexing
|
// Cell or Brick Indexing
|
||||||
using Index = int32_t;
|
using Index = ItemCell; // int32_t
|
||||||
static const Index INVALID = -1;
|
static const Index INVALID = -1;
|
||||||
static const Index ROOT = 0;
|
static const Index ROOT = 0;
|
||||||
using Indices = std::vector<Index>;
|
using Indices = std::vector<Index>;
|
||||||
|
@ -194,9 +194,9 @@ namespace render {
|
||||||
Indices indexCellPath(const Locations& path);
|
Indices indexCellPath(const Locations& path);
|
||||||
Index indexCell(const Location& loc) { return indexCellPath(Location::pathTo(loc)).back(); }
|
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.
|
// 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
|
// Reach a concrete cell
|
||||||
const Cell& getCell(Index index) const {
|
const Cell& getCell(Index index) const {
|
||||||
|
@ -209,7 +209,10 @@ namespace render {
|
||||||
// Let s talk about the Cell Bricks now
|
// Let s talk about the Cell Bricks now
|
||||||
using CellBrickAccessor = std::function<void(Brick& brick, Index brickIdx)>;
|
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 {
|
const Brick& getBrick(Index index) const {
|
||||||
assert(index < _bricks.size());
|
assert(index < _bricks.size());
|
||||||
|
@ -258,19 +261,22 @@ namespace render {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Bound to Location
|
||||||
AABox evalBound(const Location& loc) const {
|
AABox evalBound(const Location& loc) const {
|
||||||
float cellWidth = getCellWidth(loc.depth);
|
float cellWidth = getCellWidth(loc.depth);
|
||||||
return AABox(evalPos(loc.pos, cellWidth), cellWidth);
|
return AABox(evalPos(loc.pos, cellWidth), cellWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
Location evalLocation(const AABox& bound) const {
|
Location evalLocation(const AABox& bound) const {
|
||||||
return Location::evalFromRange(evalCoord(bound.getMinimumPoint()), evalCoord(bound.getMaximumPoint()));
|
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() {}
|
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) {
|
void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) {
|
||||||
auto resetID = ids.begin();
|
|
||||||
auto resetPayload = payloads.begin();
|
auto& resetPayload = payloads.begin();
|
||||||
ItemBounds itemBounds;
|
for (auto resetID : ids) {
|
||||||
itemBounds.reserve(ids.size());
|
// Access the true item
|
||||||
|
auto& item = _items[resetID];
|
||||||
for (;resetID != ids.end(); resetID++, resetPayload++) {
|
|
||||||
auto& item = _items[(*resetID)];
|
|
||||||
auto oldKey = item.getKey();
|
auto oldKey = item.getKey();
|
||||||
|
auto oldCell = item.getCell();
|
||||||
|
|
||||||
|
// Reset the item with a new payload
|
||||||
item.resetPayload(*resetPayload);
|
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) {
|
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@>
|
<@include gpu/Color.slh@>
|
||||||
<$declareColorWheel()$>
|
<$declareColorWheel()$>
|
||||||
|
|
||||||
<!
|
<@include SceneOctree.slh@>
|
||||||
uniform ivec4 inCellLocation;
|
|
||||||
|
|
||||||
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;
|
uniform ivec4 inCellLocation;
|
||||||
|
|
||||||
out vec4 varColor;
|
out vec4 varColor;
|
||||||
|
@ -101,7 +53,9 @@ void main(void) {
|
||||||
);
|
);
|
||||||
vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
|
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
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
|
|
Loading…
Reference in a new issue