mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 20:06:02 +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);
|
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
||||||
|
|
||||||
// Blend on transparent
|
// Blend on transparent
|
||||||
state->setBlendFunction(true,
|
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
||||||
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);
|
|
||||||
|
|
||||||
// Good to go add the brand new pipeline
|
// Good to go add the brand new pipeline
|
||||||
_drawCellBoundsPipeline = gpu::Pipeline::create(program, state);
|
_drawCellBoundsPipeline = gpu::Pipeline::create(program, state);
|
||||||
|
@ -99,9 +97,13 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
|
||||||
|
|
||||||
const auto& inCells = scene->getSpatialTree()._cells;
|
const auto& inCells = scene->getSpatialTree()._cells;
|
||||||
|
|
||||||
for (int i = 0; i < nbCells; i++) {
|
for (const auto& cell: inCells ) {
|
||||||
auto& cellLoc = inCells[i].getlocation();
|
auto cellLoc = cell.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);
|
||||||
|
if (cell.isBrickEmpty() || !cell.hasBrick()) {
|
||||||
|
cellLocation.w *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
|
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ const gpu::PipelinePointer DrawStatus::getDrawItemBoundsPipeline() {
|
||||||
|
|
||||||
_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
|
_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
|
||||||
_drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
|
_drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
|
||||||
|
_drawItemCellLocLoc = program->getUniforms().findLocation("inCellLocation");
|
||||||
|
|
||||||
auto state = std::make_shared<gpu::State>();
|
auto state = std::make_shared<gpu::State>();
|
||||||
|
|
||||||
|
@ -121,11 +122,17 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
if (!_itemStatus) {
|
if (!_itemStatus) {
|
||||||
_itemStatus = std::make_shared<gpu::Buffer>();;
|
_itemStatus = std::make_shared<gpu::Buffer>();;
|
||||||
}
|
}
|
||||||
|
if (!_itemCells) {
|
||||||
|
_itemCells = std::make_shared<gpu::Buffer>();;
|
||||||
|
}
|
||||||
|
|
||||||
_itemBounds->resize((inItems.size() * sizeof(AABox)));
|
_itemBounds->resize((inItems.size() * sizeof(AABox)));
|
||||||
_itemStatus->resize((inItems.size() * NUM_STATUS_VEC4_PER_ITEM * sizeof(glm::vec4)));
|
_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());
|
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
||||||
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
||||||
|
Octree::Location* itemCell = reinterpret_cast<Octree::Location*> (_itemCells->editData());
|
||||||
for (auto& item : inItems) {
|
for (auto& item : inItems) {
|
||||||
if (!item.bound.isInvalid()) {
|
if (!item.bound.isInvalid()) {
|
||||||
if (!item.bound.isNull()) {
|
if (!item.bound.isNull()) {
|
||||||
|
@ -133,8 +140,12 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
} else {
|
} else {
|
||||||
(*itemAABox).setBox(item.bound.getCorner(), 0.1f);
|
(*itemAABox).setBox(item.bound.getCorner(), 0.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto& itemScene = scene->getItem(item.id);
|
auto& itemScene = scene->getItem(item.id);
|
||||||
|
|
||||||
|
(*itemCell) = scene->getSpatialTree().getCellLocation(itemScene.getCell());
|
||||||
|
|
||||||
auto itemStatusPointer = itemScene.getStatus();
|
auto itemStatusPointer = itemScene.getStatus();
|
||||||
if (itemStatusPointer) {
|
if (itemStatusPointer) {
|
||||||
// Query the current status values, this is where the statusGetter lambda get called
|
// Query the current status values, this is where the statusGetter lambda get called
|
||||||
|
@ -159,6 +170,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
|
|
||||||
nbItems++;
|
nbItems++;
|
||||||
itemAABox++;
|
itemAABox++;
|
||||||
|
itemCell++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +196,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
|
|
||||||
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
||||||
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->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;
|
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
||||||
|
|
||||||
|
@ -191,8 +204,15 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
|
||||||
for (int i = 0; i < nbItems; i++) {
|
for (int i = 0; i < nbItems; i++) {
|
||||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
|
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
|
||||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
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);
|
batch.draw(gpu::LINES, 24, 0);
|
||||||
|
itemCell++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,11 @@ namespace render {
|
||||||
Q_PROPERTY(bool showDisplay MEMBER showDisplay WRITE setShowDisplay)
|
Q_PROPERTY(bool showDisplay MEMBER showDisplay WRITE setShowDisplay)
|
||||||
Q_PROPERTY(bool showNetwork MEMBER showNetwork WRITE setShowNetwork)
|
Q_PROPERTY(bool showNetwork MEMBER showNetwork WRITE setShowNetwork)
|
||||||
public:
|
public:
|
||||||
DrawStatusConfig() : Job::Config(false) {}
|
DrawStatusConfig() : Job::Config(true) {} // FIXME FOR debug
|
||||||
|
|
||||||
void dirtyHelper();
|
void dirtyHelper();
|
||||||
|
|
||||||
bool showDisplay{ false };
|
bool showDisplay{ true }; // FIXME FOR debug
|
||||||
bool showNetwork{ false };
|
bool showNetwork{ false };
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -59,6 +59,7 @@ namespace render {
|
||||||
|
|
||||||
int _drawItemBoundPosLoc = -1;
|
int _drawItemBoundPosLoc = -1;
|
||||||
int _drawItemBoundDimLoc = -1;
|
int _drawItemBoundDimLoc = -1;
|
||||||
|
int _drawItemCellLocLoc = -1;
|
||||||
int _drawItemStatusPosLoc = -1;
|
int _drawItemStatusPosLoc = -1;
|
||||||
int _drawItemStatusDimLoc = -1;
|
int _drawItemStatusDimLoc = -1;
|
||||||
int _drawItemStatusValue0Loc = -1;
|
int _drawItemStatusValue0Loc = -1;
|
||||||
|
@ -68,6 +69,7 @@ namespace render {
|
||||||
gpu::PipelinePointer _drawItemBoundsPipeline;
|
gpu::PipelinePointer _drawItemBoundsPipeline;
|
||||||
gpu::PipelinePointer _drawItemStatusPipeline;
|
gpu::PipelinePointer _drawItemStatusPipeline;
|
||||||
gpu::BufferPointer _itemBounds;
|
gpu::BufferPointer _itemBounds;
|
||||||
|
gpu::BufferPointer _itemCells;
|
||||||
gpu::BufferPointer _itemStatus;
|
gpu::BufferPointer _itemStatus;
|
||||||
gpu::TexturePointer _statusIconMap;
|
gpu::TexturePointer _statusIconMap;
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,7 +73,7 @@ Octree::Indices Octree::indexConcreteCellPath(const Locations& path) const {
|
||||||
|
|
||||||
for (int l = 1; l < path.size(); l++) {
|
for (int l = 1; l < path.size(); l++) {
|
||||||
auto& location = path[l];
|
auto& location = path[l];
|
||||||
auto nextIndex = getCell(currentIndex).child(location.octant());
|
auto nextIndex = getConcreteCell(currentIndex).child(location.octant());
|
||||||
if (nextIndex == INVALID) {
|
if (nextIndex == INVALID) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -133,8 +133,8 @@ Octree::Index Octree::allocateBrick() {
|
||||||
|
|
||||||
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(cellID != INVALID);
|
||||||
auto cell = editCell(cellID);
|
auto& cell = editCell(cellID);
|
||||||
if (!cell.asBrick()) {
|
if (!cell.hasBrick()) {
|
||||||
if (!createBrick) {
|
if (!createBrick) {
|
||||||
return INVALID;
|
return INVALID;
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ Octree::Index Octree::accessCellBrick(Index cellID, const CellBrickAccessor& acc
|
||||||
auto& brick = _bricks[brickID];
|
auto& brick = _bricks[brickID];
|
||||||
|
|
||||||
// execute the accessor
|
// execute the accessor
|
||||||
accessor(brick, brickID);
|
accessor(cell, brick, brickID);
|
||||||
|
|
||||||
return brickID;
|
return brickID;
|
||||||
}
|
}
|
||||||
|
@ -164,13 +164,11 @@ Octree::Locations ItemSpatialTree::evalLocations(const ItemBounds& bounds) const
|
||||||
return locations;
|
return locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemSpatialTree::Index ItemSpatialTree::insertItem(const Location& location, const ItemID& item) {
|
ItemSpatialTree::Index ItemSpatialTree::insertItem(Index cellIdx, const ItemID& item) {
|
||||||
// Go to the cell
|
|
||||||
auto cellIdx = indexCell(location);
|
|
||||||
|
|
||||||
// Add the item to the brick (and a brick if needed)
|
// 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);
|
brick.items.push_back(item);
|
||||||
|
cell.signalBrickFilled();
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
return cellIdx;
|
return cellIdx;
|
||||||
|
@ -180,9 +178,12 @@ bool ItemSpatialTree::removeItem(Index cellIdx, const ItemID& item) {
|
||||||
auto success = false;
|
auto success = false;
|
||||||
|
|
||||||
// Access the brick at the cell (without createing new ones)
|
// 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
|
// remove the item from the list
|
||||||
brick.items.erase(std::find(brick.items.begin(), brick.items.end(), item));
|
brick.items.erase(std::find(brick.items.begin(), brick.items.end(), item));
|
||||||
|
if (brick.items.empty()) {
|
||||||
|
cell.signalBrickEmpty();
|
||||||
|
}
|
||||||
success = true;
|
success = true;
|
||||||
}, false); // do not create brick!
|
}, 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) {
|
ItemSpatialTree::Index ItemSpatialTree::resetItem(Index oldCell, const Location& location, const ItemID& item) {
|
||||||
// do we know about this item ?
|
auto newCell = indexCell(location);
|
||||||
if (oldCell == Item::INVALID_CELL) {
|
|
||||||
auto newCell = insertItem(location, item);
|
|
||||||
return newCell;
|
|
||||||
} else {
|
|
||||||
auto newCell = indexCell(location);
|
|
||||||
|
|
||||||
accessCellBrick(newCell, [&](Brick& brick, Octree::Index brickID) {
|
// Early exit if nothing changed
|
||||||
// insert the item only if the new cell is different from the previous one
|
if (newCell == oldCell) {
|
||||||
if (newCell != oldCell) {
|
return newCell;
|
||||||
brick.items.push_back(item);
|
}
|
||||||
}
|
// 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);
|
}, true);
|
||||||
|
|
||||||
// now we know where the cell has been added and where it was,
|
// And remove it from the previous one
|
||||||
// if different then go clean the previous cell
|
removeItem(oldCell, item);
|
||||||
if (newCell != oldCell) {
|
|
||||||
removeItem(oldCell, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newCell;
|
return newCell;
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,8 +162,11 @@ namespace render {
|
||||||
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]; }
|
||||||
bool asBrick() const { return _links[BrickLink] != INVALID; }
|
bool hasBrick() const { return _links[BrickLink] != INVALID; }
|
||||||
void setBrick(Index brick) { _links[BrickLink] = brick; }
|
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() :
|
Cell() :
|
||||||
_links({ { INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID } })
|
_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.
|
// the returned indices stops at the last existing cell on the requested path.
|
||||||
Indices indexConcreteCellPath(const Locations& path) const;
|
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
|
// Reach a concrete cell
|
||||||
const Cell& getCell(Index index) const {
|
const Cell& getConcreteCell(Index index) const {
|
||||||
assert(index < _cells.size());
|
assert(index < _cells.size());
|
||||||
return _cells[index];
|
return _cells[index];
|
||||||
}
|
}
|
||||||
|
@ -207,14 +218,14 @@ 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(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)
|
// 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
|
// 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& getBrick(Index index) const {
|
const Brick& getConcreteBrick(Index index) const {
|
||||||
assert(index < _bricks.size());
|
assert(index < _bricks.size());
|
||||||
return _bricks[index];
|
return _bricks[index];
|
||||||
}
|
}
|
||||||
|
@ -272,8 +283,10 @@ namespace render {
|
||||||
Locations evalLocations(const ItemBounds& bounds) const;
|
Locations evalLocations(const ItemBounds& bounds) const;
|
||||||
|
|
||||||
// Managing itemsInserting items in cells
|
// 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);
|
bool removeItem(Index cellIdx, const ItemID& item);
|
||||||
|
|
||||||
Index resetItem(Index oldCell, const Location& location, const ItemID& item);
|
Index resetItem(Index oldCell, const Location& location, const ItemID& item);
|
||||||
|
|
||||||
ItemSpatialTree() {}
|
ItemSpatialTree() {}
|
||||||
|
|
|
@ -155,15 +155,38 @@ void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) {
|
||||||
|
|
||||||
void Scene::removeItems(const ItemIDs& ids) {
|
void Scene::removeItems(const ItemIDs& ids) {
|
||||||
for (auto removedID :ids) {
|
for (auto removedID :ids) {
|
||||||
_masterBucketMap.erase(removedID, _items[removedID].getKey());
|
// Access the true item
|
||||||
_items[removedID].kill();
|
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) {
|
void Scene::updateItems(const ItemIDs& ids, UpdateFunctors& functors) {
|
||||||
auto updateID = ids.begin();
|
|
||||||
auto updateFunctor = functors.begin();
|
auto& updateFunctor = functors.begin();
|
||||||
for (;updateID != ids.end(); updateID++, updateFunctor++) {
|
for (auto updateID : ids) {
|
||||||
_items[(*updateID)].update((*updateFunctor));
|
// 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@>
|
<@include gpu/Color.slh@>
|
||||||
<$declareColorWheel()$>
|
<$declareColorWheel()$>
|
||||||
|
|
||||||
<@include SceneOctree.slh@>
|
<@include SceneOctree.slh@>
|
||||||
|
|
||||||
uniform ivec4 inCellLocation;
|
uniform ivec4 inCellLocation;
|
||||||
|
@ -53,7 +52,9 @@ void main(void) {
|
||||||
);
|
);
|
||||||
vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
|
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;
|
pos.xyz = cellBound.xyz + vec3(cellBound.w) * pos.xyz;
|
||||||
|
|
||||||
|
@ -62,5 +63,5 @@ 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);
|
varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 0.5 + 0.4 * cellIsEmpty);
|
||||||
}
|
}
|
|
@ -12,9 +12,12 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
in vec4 varColor;
|
in vec4 varColor;
|
||||||
|
in vec2 varTexcoord;
|
||||||
out vec4 outFragColor;
|
out vec4 outFragColor;
|
||||||
|
|
||||||
|
|
||||||
void main(void) {
|
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@>
|
<@include gpu/Transform.slh@>
|
||||||
|
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
|
<@include gpu/Color.slh@>
|
||||||
|
<$declareColorWheel()$>
|
||||||
|
|
||||||
uniform vec3 inBoundPos;
|
uniform vec3 inBoundPos;
|
||||||
uniform vec3 inBoundDim;
|
uniform vec3 inBoundDim;
|
||||||
|
uniform ivec4 inCellLocation;
|
||||||
|
|
||||||
|
out vec4 varColor;
|
||||||
|
out vec2 varTexcoord;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
const vec4 UNIT_BOX[8] = vec4[8](
|
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(1.0, 0.0, 0.0, 1.0),
|
||||||
vec4(0.0, 1.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(0.0, 0.0, 1.0, 1.0),
|
||||||
vec4(1.0, 0.0, 1.0, 1.0),
|
vec4(1.0, 0.0, 1.0, 2.0),
|
||||||
vec4(0.0, 1.0, 1.0, 1.0),
|
vec4(0.0, 1.0, 1.0, 2.0),
|
||||||
vec4(1.0, 1.0, 1.0, 1.0)
|
vec4(1.0, 1.0, 1.0, 3.0)
|
||||||
);
|
);
|
||||||
const int UNIT_BOX_LINE_INDICES[24] = int[24](
|
const int UNIT_BOX_LINE_INDICES[24] = int[24](
|
||||||
0, 1,
|
0, 1,
|
||||||
|
@ -44,14 +50,16 @@ void main(void) {
|
||||||
0, 4,
|
0, 4,
|
||||||
1, 5
|
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
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, pos, gl_Position)$>
|
<$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