mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 07:43:57 +02:00
DDisplay of the octree cells is working, added the Brick empty / full per cell
This commit is contained in:
parent
7b50a4d05f
commit
59434e1ea9
9 changed files with 132 additions and 57 deletions
|
@ -42,9 +42,7 @@ const gpu::PipelinePointer DrawSceneOctree::getDrawCellBoundsPipeline() {
|
|||
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,
|
||||
gpu::State::DEST_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ZERO);
|
||||
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
|
||||
_drawCellBoundsPipeline = gpu::Pipeline::create(program, state);
|
||||
|
@ -99,9 +97,13 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
|||
|
||||
const auto& inCells = scene->getSpatialTree()._cells;
|
||||
|
||||
for (int i = 0; i < nbCells; i++) {
|
||||
auto& cellLoc = inCells[i].getlocation();
|
||||
for (const auto& cell: inCells ) {
|
||||
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;
|
||||
}
|
||||
|
||||
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ const gpu::PipelinePointer DrawStatus::getDrawItemBoundsPipeline() {
|
|||
|
||||
_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
|
||||
_drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
|
||||
_drawItemCellLocLoc = program->getUniforms().findLocation("inCellLocation");
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
|
||||
|
@ -121,11 +122,17 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
|||
if (!_itemStatus) {
|
||||
_itemStatus = std::make_shared<gpu::Buffer>();;
|
||||
}
|
||||
if (!_itemCells) {
|
||||
_itemCells = std::make_shared<gpu::Buffer>();;
|
||||
}
|
||||
|
||||
_itemBounds->resize((inItems.size() * sizeof(AABox)));
|
||||
_itemStatus->resize((inItems.size() * NUM_STATUS_VEC4_PER_ITEM * sizeof(glm::vec4)));
|
||||
_itemCells->resize((inItems.size() * sizeof(Octree::Location)));
|
||||
|
||||
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
||||
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
||||
Octree::Location* itemCell = reinterpret_cast<Octree::Location*> (_itemCells->editData());
|
||||
for (auto& item : inItems) {
|
||||
if (!item.bound.isInvalid()) {
|
||||
if (!item.bound.isNull()) {
|
||||
|
@ -133,8 +140,12 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
|||
} else {
|
||||
(*itemAABox).setBox(item.bound.getCorner(), 0.1f);
|
||||
}
|
||||
|
||||
|
||||
auto& itemScene = scene->getItem(item.id);
|
||||
|
||||
(*itemCell) = scene->getSpatialTree().getCellLocation(itemScene.getCell());
|
||||
|
||||
auto itemStatusPointer = itemScene.getStatus();
|
||||
if (itemStatusPointer) {
|
||||
// Query the current status values, this is where the statusGetter lambda get called
|
||||
|
@ -159,6 +170,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
|||
|
||||
nbItems++;
|
||||
itemAABox++;
|
||||
itemCell++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +196,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
|||
|
||||
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
||||
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
||||
Octree::Location* itemCell = reinterpret_cast<Octree::Location*> (_itemCells->editData());
|
||||
|
||||
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
||||
|
||||
|
@ -191,8 +204,15 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
|||
for (int i = 0; i < nbItems; i++) {
|
||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
|
||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
||||
|
||||
|
||||
glm::ivec4 cellLocation(itemCell->pos.x, itemCell->pos.y, itemCell->pos.z, itemCell->depth);
|
||||
|
||||
batch._glUniform4iv(_drawItemCellLocLoc, 1, ((const int*)(&cellLocation)));
|
||||
|
||||
|
||||
batch.draw(gpu::LINES, 24, 0);
|
||||
itemCell++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,11 +21,11 @@ namespace render {
|
|||
Q_PROPERTY(bool showDisplay MEMBER showDisplay WRITE setShowDisplay)
|
||||
Q_PROPERTY(bool showNetwork MEMBER showNetwork WRITE setShowNetwork)
|
||||
public:
|
||||
DrawStatusConfig() : Job::Config(false) {}
|
||||
DrawStatusConfig() : Job::Config(true) {} // FIXME FOR debug
|
||||
|
||||
void dirtyHelper();
|
||||
|
||||
bool showDisplay{ false };
|
||||
bool showDisplay{ true }; // FIXME FOR debug
|
||||
bool showNetwork{ false };
|
||||
|
||||
public slots:
|
||||
|
@ -59,6 +59,7 @@ namespace render {
|
|||
|
||||
int _drawItemBoundPosLoc = -1;
|
||||
int _drawItemBoundDimLoc = -1;
|
||||
int _drawItemCellLocLoc = -1;
|
||||
int _drawItemStatusPosLoc = -1;
|
||||
int _drawItemStatusDimLoc = -1;
|
||||
int _drawItemStatusValue0Loc = -1;
|
||||
|
@ -68,6 +69,7 @@ namespace render {
|
|||
gpu::PipelinePointer _drawItemBoundsPipeline;
|
||||
gpu::PipelinePointer _drawItemStatusPipeline;
|
||||
gpu::BufferPointer _itemBounds;
|
||||
gpu::BufferPointer _itemCells;
|
||||
gpu::BufferPointer _itemStatus;
|
||||
gpu::TexturePointer _statusIconMap;
|
||||
};
|
||||
|
|
|
@ -73,7 +73,7 @@ Octree::Indices Octree::indexConcreteCellPath(const Locations& path) const {
|
|||
|
||||
for (int l = 1; l < path.size(); l++) {
|
||||
auto& location = path[l];
|
||||
auto nextIndex = getCell(currentIndex).child(location.octant());
|
||||
auto nextIndex = getConcreteCell(currentIndex).child(location.octant());
|
||||
if (nextIndex == INVALID) {
|
||||
break;
|
||||
}
|
||||
|
@ -133,8 +133,8 @@ Octree::Index Octree::allocateBrick() {
|
|||
|
||||
Octree::Index Octree::accessCellBrick(Index cellID, const CellBrickAccessor& accessor, bool createBrick) {
|
||||
assert(cellID != INVALID);
|
||||
auto cell = editCell(cellID);
|
||||
if (!cell.asBrick()) {
|
||||
auto& cell = editCell(cellID);
|
||||
if (!cell.hasBrick()) {
|
||||
if (!createBrick) {
|
||||
return INVALID;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ Octree::Index Octree::accessCellBrick(Index cellID, const CellBrickAccessor& acc
|
|||
auto& brick = _bricks[brickID];
|
||||
|
||||
// execute the accessor
|
||||
accessor(brick, brickID);
|
||||
accessor(cell, brick, brickID);
|
||||
|
||||
return brickID;
|
||||
}
|
||||
|
@ -164,13 +164,11 @@ Octree::Locations ItemSpatialTree::evalLocations(const ItemBounds& bounds) const
|
|||
return locations;
|
||||
}
|
||||
|
||||
ItemSpatialTree::Index ItemSpatialTree::insertItem(const Location& location, const ItemID& item) {
|
||||
// Go to the cell
|
||||
auto cellIdx = indexCell(location);
|
||||
|
||||
ItemSpatialTree::Index ItemSpatialTree::insertItem(Index cellIdx, const ItemID& item) {
|
||||
// Add the item to the brick (and a brick if needed)
|
||||
accessCellBrick(cellIdx, [&](Brick& brick, Octree::Index cellID) {
|
||||
auto brickID = accessCellBrick(cellIdx, [&](Cell& cell, Brick& brick, Octree::Index cellID) {
|
||||
brick.items.push_back(item);
|
||||
cell.signalBrickFilled();
|
||||
}, true);
|
||||
|
||||
return cellIdx;
|
||||
|
@ -180,9 +178,12 @@ 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) {
|
||||
accessCellBrick(cellIdx, [&](Cell& cell, Brick& brick, Octree::Index brickID) {
|
||||
// remove the item from the list
|
||||
brick.items.erase(std::find(brick.items.begin(), brick.items.end(), item));
|
||||
if (brick.items.empty()) {
|
||||
cell.signalBrickEmpty();
|
||||
}
|
||||
success = true;
|
||||
}, false); // do not create brick!
|
||||
|
||||
|
@ -190,25 +191,27 @@ bool ItemSpatialTree::removeItem(Index cellIdx, const ItemID& item) {
|
|||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
// Early exit if nothing changed
|
||||
if (newCell == oldCell) {
|
||||
return newCell;
|
||||
}
|
||||
// do we know about this item ?
|
||||
else if (oldCell == Item::INVALID_CELL) {
|
||||
insertItem(newCell, item);
|
||||
return newCell;
|
||||
}
|
||||
// A true update of cell is required
|
||||
else {
|
||||
// Add the item to the brick (and a brick if needed)
|
||||
accessCellBrick(newCell, [&](Cell& cell, Brick& brick, Octree::Index cellID) {
|
||||
brick.items.push_back(item);
|
||||
cell.signalBrickFilled();
|
||||
}, 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);
|
||||
}
|
||||
// And remove it from the previous one
|
||||
removeItem(oldCell, item);
|
||||
|
||||
return newCell;
|
||||
}
|
||||
|
|
|
@ -162,8 +162,11 @@ namespace render {
|
|||
void setChild(Link octant, Index child) { _links[octant] = child; }
|
||||
|
||||
Index brick() const { return _links[BrickLink]; }
|
||||
bool asBrick() const { return _links[BrickLink] != INVALID; }
|
||||
bool hasBrick() const { return _links[BrickLink] != INVALID; }
|
||||
void setBrick(Index brick) { _links[BrickLink] = brick; }
|
||||
void signalBrickFilled() { _location.spare = 1; }
|
||||
void signalBrickEmpty() { _location.spare = 0; }
|
||||
bool isBrickEmpty() const { return _location.spare == 0; }
|
||||
|
||||
Cell() :
|
||||
_links({ { INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID } })
|
||||
|
@ -198,8 +201,16 @@ namespace render {
|
|||
// the returned indices stops at the last existing cell on the requested path.
|
||||
Indices indexConcreteCellPath(const Locations& path) const;
|
||||
|
||||
// Get the cell location from the CellID
|
||||
Location getCellLocation(Index cellID) const {
|
||||
if ((cellID >= 0) && (cellID < _cells.size())) {
|
||||
return getConcreteCell(cellID).getlocation();
|
||||
}
|
||||
return Location();
|
||||
}
|
||||
|
||||
// Reach a concrete cell
|
||||
const Cell& getCell(Index index) const {
|
||||
const Cell& getConcreteCell(Index index) const {
|
||||
assert(index < _cells.size());
|
||||
return _cells[index];
|
||||
}
|
||||
|
@ -207,14 +218,14 @@ namespace render {
|
|||
|
||||
|
||||
// Let s talk about the Cell Bricks now
|
||||
using CellBrickAccessor = std::function<void(Brick& brick, Index brickIdx)>;
|
||||
using CellBrickAccessor = std::function<void(Cell& cell, Brick& brick, Index brickIdx)>;
|
||||
|
||||
// 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& getConcreteBrick(Index index) const {
|
||||
assert(index < _bricks.size());
|
||||
return _bricks[index];
|
||||
}
|
||||
|
@ -272,8 +283,10 @@ namespace render {
|
|||
Locations evalLocations(const ItemBounds& bounds) const;
|
||||
|
||||
// Managing itemsInserting items in cells
|
||||
Index insertItem(const Location& location, const ItemID& item);
|
||||
// Cells need to have been allocated first calling indexCell
|
||||
Index insertItem(Index cellIdx, const ItemID& item);
|
||||
bool removeItem(Index cellIdx, const ItemID& item);
|
||||
|
||||
Index resetItem(Index oldCell, const Location& location, const ItemID& item);
|
||||
|
||||
ItemSpatialTree() {}
|
||||
|
|
|
@ -155,15 +155,38 @@ void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) {
|
|||
|
||||
void Scene::removeItems(const ItemIDs& ids) {
|
||||
for (auto removedID :ids) {
|
||||
_masterBucketMap.erase(removedID, _items[removedID].getKey());
|
||||
_items[removedID].kill();
|
||||
// Access the true item
|
||||
auto& item = _items[removedID];
|
||||
|
||||
// Remove from Bucket map
|
||||
_masterBucketMap.erase(removedID, item.getKey());
|
||||
|
||||
// Remove from spatial tree
|
||||
_masterSpatialTree.removeItem(item.getCell(), removedID);
|
||||
|
||||
// Kill it
|
||||
item.kill();
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::updateItems(const ItemIDs& ids, UpdateFunctors& functors) {
|
||||
auto updateID = ids.begin();
|
||||
auto updateFunctor = functors.begin();
|
||||
for (;updateID != ids.end(); updateID++, updateFunctor++) {
|
||||
_items[(*updateID)].update((*updateFunctor));
|
||||
|
||||
auto& updateFunctor = functors.begin();
|
||||
for (auto updateID : ids) {
|
||||
// Access the true item
|
||||
auto& item = _items[updateID];
|
||||
auto oldCell = item.getCell();
|
||||
|
||||
// Update it
|
||||
_items[updateID].update((*updateFunctor));
|
||||
|
||||
// Update the citem in the spatial tree if needed
|
||||
// THis could be avoided if we
|
||||
auto newCellLocation = _masterSpatialTree.evalLocation(item.getBound());
|
||||
auto newCell = _masterSpatialTree.resetItem(oldCell, newCellLocation, updateID);
|
||||
item.resetCell(newCell);
|
||||
|
||||
// next loop
|
||||
updateFunctor++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
<@include gpu/Color.slh@>
|
||||
<$declareColorWheel()$>
|
||||
|
||||
<@include SceneOctree.slh@>
|
||||
|
||||
uniform ivec4 inCellLocation;
|
||||
|
@ -53,7 +52,9 @@ void main(void) {
|
|||
);
|
||||
vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
|
||||
|
||||
vec4 cellBound = evalBound(inCellLocation);
|
||||
int cellIsEmpty = sign(inCellLocation.w);
|
||||
ivec4 cellLocation = ivec4(inCellLocation.xyz, (inCellLocation.w < 0 ? -inCellLocation.w : inCellLocation.w));
|
||||
vec4 cellBound = evalBound(cellLocation);
|
||||
|
||||
pos.xyz = cellBound.xyz + vec3(cellBound.w) * pos.xyz;
|
||||
|
||||
|
@ -62,5 +63,5 @@ void main(void) {
|
|||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, pos, gl_Position)$>
|
||||
|
||||
varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 1.0);
|
||||
varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 0.5 + 0.4 * cellIsEmpty);
|
||||
}
|
|
@ -12,9 +12,12 @@
|
|||
//
|
||||
|
||||
in vec4 varColor;
|
||||
in vec2 varTexcoord;
|
||||
out vec4 outFragColor;
|
||||
|
||||
|
||||
void main(void) {
|
||||
outFragColor = vec4(1.0, 0.5, 0.0, 1.0);
|
||||
float var = step(fract(varTexcoord.x * varTexcoord.y * 1.0), 0.5);
|
||||
|
||||
outFragColor = vec4(mix(vec3(1.0), varColor.xyz, var), varColor.a);
|
||||
}
|
||||
|
|
|
@ -13,22 +13,28 @@
|
|||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include gpu/Color.slh@>
|
||||
<$declareColorWheel()$>
|
||||
|
||||
uniform vec3 inBoundPos;
|
||||
uniform vec3 inBoundDim;
|
||||
uniform ivec4 inCellLocation;
|
||||
|
||||
out vec4 varColor;
|
||||
out vec2 varTexcoord;
|
||||
|
||||
void main(void) {
|
||||
const vec4 UNIT_BOX[8] = vec4[8](
|
||||
vec4(0.0, 0.0, 0.0, 1.0),
|
||||
vec4(0.0, 0.0, 0.0, 0.0),
|
||||
vec4(1.0, 0.0, 0.0, 1.0),
|
||||
vec4(0.0, 1.0, 0.0, 1.0),
|
||||
vec4(1.0, 1.0, 0.0, 1.0),
|
||||
vec4(1.0, 1.0, 0.0, 2.0),
|
||||
vec4(0.0, 0.0, 1.0, 1.0),
|
||||
vec4(1.0, 0.0, 1.0, 1.0),
|
||||
vec4(0.0, 1.0, 1.0, 1.0),
|
||||
vec4(1.0, 1.0, 1.0, 1.0)
|
||||
vec4(1.0, 0.0, 1.0, 2.0),
|
||||
vec4(0.0, 1.0, 1.0, 2.0),
|
||||
vec4(1.0, 1.0, 1.0, 3.0)
|
||||
);
|
||||
const int UNIT_BOX_LINE_INDICES[24] = int[24](
|
||||
0, 1,
|
||||
|
@ -44,14 +50,16 @@ void main(void) {
|
|||
0, 4,
|
||||
1, 5
|
||||
);
|
||||
vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
|
||||
vec4 cubeVec = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
|
||||
|
||||
pos.xyz = inBoundPos + inBoundDim * pos.xyz;
|
||||
vec4 pos = vec4(inBoundPos + inBoundDim * cubeVec.xyz, 1.0);
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, pos, gl_Position)$>
|
||||
|
||||
// varTexcoord = (pos.xy + 1) * 0.5;
|
||||
varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 1.0);
|
||||
varTexcoord = vec2(cubeVec.w, length(inBoundDim));
|
||||
|
||||
}
|
Loading…
Reference in a new issue