Fancy selection of the brick and cells

This commit is contained in:
samcake 2016-02-01 18:16:23 -08:00
parent a4d7297e03
commit a29831bdf4
4 changed files with 87 additions and 70 deletions

View file

@ -98,8 +98,9 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
}
// Try that:
render::ItemIDs itemsCell;
scene->getSpatialTree().select(itemsCell, queryFrustum);
render::Octree::Indices itemsBrick;
render::Octree::Indices itemsCell;
scene->getSpatialTree().select(itemsBrick, itemsCell, queryFrustum);
// Allright, something to render let's do it
@ -129,7 +130,7 @@ void DrawSceneOctree::run(const SceneContextPointer& sceneContext,
glm::ivec4 cellLocation(cellLoc.pos.x, cellLoc.pos.y, cellLoc.pos.z, cellLoc.depth);
if (cell.isBrickEmpty() || !cell.hasBrick()) {
// cellLocation.w *= -1;
cellLocation.w *= -1;
}
batch._glUniform4iv(_drawCellLocationLoc, 1, ((const int*)(&cellLocation)));

View file

@ -19,17 +19,18 @@
namespace render {
class DrawSceneOctreeConfig : public Job::Config {
Q_OBJECT
Q_PROPERTY(bool showVisibleCells MEMBER showVisibleCells WRITE setShowVisibleCells)
Q_PROPERTY(bool freezeFrustum MEMBER freezeFrustum WRITE setFreezeFrustum)
public:
Q_PROPERTY(bool showVisibleCells MEMBER showVisibleCells WRITE setShowVisibleCells)
Q_PROPERTY(bool freezeFrustum MEMBER freezeFrustum WRITE setFreezeFrustum)
DrawSceneOctreeConfig() : Job::Config(true) {} // FIXME FOR debug
bool showVisibleCells{ true }; // FIXME FOR debug
bool freezeFrustum{ false };
public slots:
void setShowVisibleCells(bool enabled) { showVisibleCells = enabled; dirty(); }
void setFreezeFrustum(bool enabled) { freezeFrustum = enabled; dirty(); }
void setShowVisibleCells(bool enabled) { showVisibleCells = enabled; emit dirty(); }
void setFreezeFrustum(bool enabled) { freezeFrustum = enabled; emit dirty(); }
signals:
void dirty();

View file

@ -219,7 +219,7 @@ ItemSpatialTree::Index ItemSpatialTree::resetItem(Index oldCell, const Location&
}
}
int ItemSpatialTree::select(ItemIDs& selection, const ViewFrustum& frustum) const {
int ItemSpatialTree::select(Indices& selectedBricks, Indices& selectedCells, const ViewFrustum& frustum) const {
auto worldPlanes = frustum.getPlanes();
Coord4f planes[6];
for (int i = 0; i < ViewFrustum::NUM_PLANES; i++) {
@ -227,69 +227,16 @@ int ItemSpatialTree::select(ItemIDs& selection, const ViewFrustum& frustum) cons
octPlane.setNormalAndPoint(worldPlanes[i].getNormal(), evalCoordf(worldPlanes[i].getPoint(), ROOT_DEPTH));
planes[i] = Coord4f(octPlane.getNormal(), octPlane.getDCoefficient());
}
return Octree::select(selection, planes);
return Octree::select(selectedBricks, selectedCells, planes);
}
int Octree::select(ItemIDs& selection, const glm::vec4 frustum[6]) const {
int Octree::select(Indices& selectedBricks, Indices& selectedCells, const glm::vec4 frustum[6]) const {
Index cellID = ROOT_CELL;
selectTraverse(cellID, selection, frustum);
return selection.size();
selectTraverse(cellID, selectedBricks, selectedCells, frustum);
return selectedCells.size();
}
int Octree::selectTraverse(Index cellID, ItemIDs& selection, const Coord4f frustum[6]) const {
int numSelectedsIn = selection.size();
auto cell = getConcreteCell(cellID);
auto intersection = Octree::Location::intersectCell(cell.getlocation(), frustum);
switch (intersection) {
case Octree::Location::Outside:
// cell is outside, stop traversing this branch
return 0;
break;
case Octree::Location::Inside: {
// traverse all the Cell Branch and collect items in the selection
selectBranch(cellID, selection, frustum);
break;
}
case Octree::Location::Intersect:
default: {
// Cell is partially in
selection.push_back(cellID);
// Collect the items of this cell
// then traverse further
for (int i = 0; i < NUM_OCTANTS; i++) {
Index subCellID = cell.child((Link)i);
if (subCellID != INVALID) {
selectTraverse(subCellID, selection, frustum);
}
}
}
}
return selection.size() - numSelectedsIn;
}
int Octree::selectBranch(Index cellID, ItemIDs& selection, const Coord4f frustum[6]) const {
int numSelectedsIn = selection.size();
auto cell = getConcreteCell(cellID);
// Collect the items of this cell
selection.push_back(cellID);
// then traverse further
for (int i = 0; i < NUM_OCTANTS; i++) {
Index subCellID = cell.child((Link)i);
if (subCellID != INVALID) {
selectBranch(subCellID, selection, frustum);
}
}
return selection.size() - numSelectedsIn;
}
Octree::Location::Intersection Octree::Location::intersectCell(const Location& cell, const Coord4f frustum[6]) {
const Coord3f CornerOffsets[8] = {
@ -347,4 +294,71 @@ Octree::Location::Intersection Octree::Location::intersectCell(const Location& c
}
return Inside;
}
}
int Octree::selectTraverse(Index cellID, Indices& selectedBricks, Indices& selectedCells, const Coord4f frustum[6]) const {
int numSelectedsIn = selectedCells.size();
auto cell = getConcreteCell(cellID);
auto intersection = Octree::Location::intersectCell(cell.getlocation(), frustum);
switch (intersection) {
case Octree::Location::Outside:
// cell is outside, stop traversing this branch
return 0;
break;
case Octree::Location::Inside: {
// traverse all the Cell Branch and collect items in the selection
selectBranch(cellID, selectedBricks, selectedCells, frustum);
break;
}
case Octree::Location::Intersect:
default: {
// Cell is partially in
// Select within this cell
selectInCell(cellID, selectedBricks, selectedCells, frustum);
// then traverse deeper
for (int i = 0; i < NUM_OCTANTS; i++) {
Index subCellID = cell.child((Link)i);
if (subCellID != INVALID) {
selectTraverse(subCellID, selectedBricks, selectedCells, frustum);
}
}
}
}
return selectedCells.size() - numSelectedsIn;
}
int Octree::selectBranch(Index cellID, Indices& selectedBricks, Indices& selectedCells, const Coord4f frustum[6]) const {
int numSelectedsIn = selectedCells.size();
auto cell = getConcreteCell(cellID);
// Select within this cell
selectInCell(cellID, selectedBricks, selectedCells, frustum);
// then traverse deeper
for (int i = 0; i < NUM_OCTANTS; i++) {
Index subCellID = cell.child((Link)i);
if (subCellID != INVALID) {
selectBranch(subCellID, selectedBricks, selectedCells, frustum);
}
}
return selectedCells.size() - numSelectedsIn;
}
int Octree::selectInCell(Index cellID, Indices& selectedBricks, Indices& selectedCells, const Coord4f frustum[6]) const {
int numSelectedsIn = selectedCells.size();
auto cell = getConcreteCell(cellID);
selectedCells.push_back(cellID);
if (!cell.isBrickEmpty()) {
// Collect the items of this cell
selectedBricks.push_back(cell.brick());
}
return selectedCells.size() - numSelectedsIn;
}

View file

@ -243,9 +243,10 @@ namespace render {
}
// Selection and traverse
int select(ItemIDs& selection, const Coord4f frustum[6]) const;
int selectTraverse(Index cellID, ItemIDs& selection, const Coord4f frustum[6]) const;
int selectBranch(Index cellID, ItemIDs& selection, const Coord4f frustum[6]) const;
int select(Indices& selectedBricks, Indices& selectedCells, const Coord4f frustum[6]) const;
int selectTraverse(Index cellID, Indices& selectedBricks, Indices& selectedCells, const Coord4f frustum[6]) const;
int selectBranch(Index cellID, Indices& selectedBricks, Indices& selectedCells, const Coord4f frustum[6]) const;
int selectInCell(Index cellID, Indices& selectedBricks, Indices& selectedCells, const Coord4f frustum[6]) const;
protected:
Index allocateCell(Index parent, const Location& location);
@ -311,7 +312,7 @@ namespace render {
Index resetItem(Index oldCell, const Location& location, const ItemID& item);
// Selection and traverse
int select(ItemIDs& selection, const ViewFrustum& frustum) const;
int select(Indices& selectedBricks, Indices& selectedCells, const ViewFrustum& frustum) const;
};