mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Optimized removeOutOfView()
- don't recurse down trees that are fully INSIDE of the view frustum, because those nodes are guaranteed to also be INSIDE - changes to extraData of the recurse operation to make this possible - adding debug stats to track how many nodes are inside, outside, intersect - change call to removeOutOfView() to not call if last elapsed time has not yet passed since last call (similar to treeToArrays() logic)
This commit is contained in:
parent
66e416d4dd
commit
70557cd51c
2 changed files with 74 additions and 10 deletions
|
@ -146,9 +146,11 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0;
|
||||
|
||||
// If the view frustum has changed, since last time, then remove nodes that are out of view
|
||||
if ((sinceLastViewCulling >= VIEW_CULLING_RATE_IN_MILLISECONDS) && hasViewChanged()) {
|
||||
if ((sinceLastViewCulling >= std::max(_lastViewCullingElapsed,VIEW_CULLING_RATE_IN_MILLISECONDS)) && hasViewChanged()) {
|
||||
_lastViewCulling = start;
|
||||
removeOutOfView();
|
||||
double endViewCulling = usecTimestampNow();
|
||||
_lastViewCullingElapsed = (endViewCulling - start)/1000.0;
|
||||
}
|
||||
|
||||
if (_tree->isDirty()) {
|
||||
|
@ -294,7 +296,7 @@ void VoxelSystem::init() {
|
|||
_callsToTreesToArrays = 0;
|
||||
_setupNewVoxelsForDrawingLastFinished = 0;
|
||||
_setupNewVoxelsForDrawingLastElapsed = 0;
|
||||
_lastViewCulling = 0;
|
||||
_lastViewCullingElapsed = _lastViewCulling = 0;
|
||||
|
||||
// When we change voxels representations in the arrays, we'll update this
|
||||
_voxelsDirty = false;
|
||||
|
@ -583,17 +585,71 @@ void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) {
|
|||
setupNewVoxelsForDrawing();
|
||||
}
|
||||
|
||||
// combines the removeOutOfView args into a single class
|
||||
class removeOutOfViewArgs {
|
||||
public:
|
||||
VoxelSystem* thisVoxelSystem;
|
||||
VoxelNodeBag dontRecurseBag;
|
||||
unsigned long nodesScanned;
|
||||
unsigned long nodesRemoved;
|
||||
unsigned long nodesInside;
|
||||
unsigned long nodesIntersect;
|
||||
unsigned long nodesOutside;
|
||||
|
||||
removeOutOfViewArgs(VoxelSystem* voxelSystem) :
|
||||
thisVoxelSystem(voxelSystem),
|
||||
dontRecurseBag(),
|
||||
nodesScanned(0),
|
||||
nodesRemoved(0),
|
||||
nodesInside(0),
|
||||
nodesIntersect(0),
|
||||
nodesOutside(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
// "Remove" voxels from the tree that are not in view. We don't actually delete them,
|
||||
// we remove them from the tree and place them into a holding area for later deletion
|
||||
bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) {
|
||||
VoxelSystem* thisVoxelSystem = (VoxelSystem*) extraData;
|
||||
_nodeCount++;
|
||||
removeOutOfViewArgs* args = (removeOutOfViewArgs*)extraData;
|
||||
|
||||
// If our node was previously added to the don't recurse bag, then return false to
|
||||
// stop the further recursion. This means that the whole node and it's children are
|
||||
// known to be in view, so don't recurse them
|
||||
if (args->dontRecurseBag.contains(node)) {
|
||||
args->dontRecurseBag.remove(node);
|
||||
return false; // stop recursion
|
||||
}
|
||||
|
||||
VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
|
||||
args->nodesScanned++;
|
||||
// Need to operate on our child nodes, so we can remove them
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||
if (childNode && !childNode->isInView(*thisVoxelSystem->_viewFrustum)) {
|
||||
node->removeChildAtIndex(i);
|
||||
thisVoxelSystem->_removedVoxels.insert(childNode);
|
||||
if (childNode) {
|
||||
ViewFrustum::location inFrustum = childNode->inFrustum(*thisVoxelSystem->_viewFrustum);
|
||||
switch (inFrustum) {
|
||||
case ViewFrustum::OUTSIDE: {
|
||||
args->nodesOutside++;
|
||||
args->nodesRemoved++;
|
||||
node->removeChildAtIndex(i);
|
||||
thisVoxelSystem->_removedVoxels.insert(childNode);
|
||||
// by removing the child, it will not get recursed!
|
||||
} break;
|
||||
case ViewFrustum::INSIDE: {
|
||||
// if the child node is fully INSIDE the view, then there's no need to recurse it
|
||||
// because we know all it's children will also be in the view, so we want to
|
||||
// tell the caller to NOT recurse this child
|
||||
args->nodesInside++;
|
||||
args->dontRecurseBag.insert(childNode);
|
||||
} break;
|
||||
case ViewFrustum::INTERSECT: {
|
||||
// if the child node INTERSECTs the view, then we don't want to remove it because
|
||||
// it is at least partially in view. But we DO want to recurse the children because
|
||||
// some of them may not be in view... nothing specifically to do, just keep iterating
|
||||
// the children
|
||||
args->nodesIntersect++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; // keep going!
|
||||
|
@ -609,7 +665,14 @@ bool VoxelSystem::hasViewChanged() {
|
|||
}
|
||||
|
||||
void VoxelSystem::removeOutOfView() {
|
||||
PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()"); // would like to include removedCount, _nodeCount, _removedVoxels.count()
|
||||
_nodeCount = 0;
|
||||
_tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)this);
|
||||
PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()");
|
||||
removeOutOfViewArgs args(this);
|
||||
_tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);
|
||||
|
||||
if (_renderWarningsOn) {
|
||||
printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld bag.count()=%d \n",
|
||||
args.nodesScanned, args.nodesRemoved, args.nodesInside,
|
||||
args.nodesIntersect, args.nodesOutside, args.dontRecurseBag.count()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ private:
|
|||
double _setupNewVoxelsForDrawingLastElapsed;
|
||||
double _setupNewVoxelsForDrawingLastFinished;
|
||||
double _lastViewCulling;
|
||||
double _lastViewCullingElapsed;
|
||||
|
||||
GLuint _vboVerticesID;
|
||||
GLuint _vboNormalsID;
|
||||
|
|
Loading…
Reference in a new issue