DDisplay of the octree cells is working, added the Brick empty / full per cell

This commit is contained in:
samcake 2016-01-29 18:16:45 -08:00
parent 7b50a4d05f
commit 59434e1ea9
9 changed files with 132 additions and 57 deletions

View file

@ -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)));

View file

@ -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++;
}
}

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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() {}

View file

@ -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++;
}
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));
}