History

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)

ZappoMan committed 13 years ago

Commit 70557cd1 parent 66e416d2 files · +74 −10Browse files

Showing the changes to interface/src/VoxelSystem.cpp (1 of 2 files). Show all

Unified · Split

interface/src/VoxelSystem.cpp+73−10
@@ -146,9 +146,11 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 145 unmodified lines
146 double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0;146 double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0;
147 147
148 // If the view frustum has changed, since last time, then remove nodes that are out of view148 // If the view frustum has changed, since last time, then remove nodes that are out of view
149 if ((sinceLastViewCulling >= VIEW_CULLING_RATE_IN_MILLISECONDS) && hasViewChanged()) {149 if ((sinceLastViewCulling >= std::max(_lastViewCullingElapsed,VIEW_CULLING_RATE_IN_MILLISECONDS)) && hasViewChanged()) {
150 _lastViewCulling = start;150 _lastViewCulling = start;
151 removeOutOfView();151 removeOutOfView();
152 double endViewCulling = usecTimestampNow();
153 _lastViewCullingElapsed = (endViewCulling - start)/1000.0;
152 } 154 }
153 155
154 if (_tree->isDirty()) {156 if (_tree->isDirty()) {
@@ -294,7 +296,7 @@ void VoxelSystem::init() { · 139 unmodified lines
294 _callsToTreesToArrays = 0;296 _callsToTreesToArrays = 0;
295 _setupNewVoxelsForDrawingLastFinished = 0;297 _setupNewVoxelsForDrawingLastFinished = 0;
296 _setupNewVoxelsForDrawingLastElapsed = 0;298 _setupNewVoxelsForDrawingLastElapsed = 0;
297 _lastViewCulling = 0;299 _lastViewCullingElapsed = _lastViewCulling = 0;
298 300
299 // When we change voxels representations in the arrays, we'll update this301 // When we change voxels representations in the arrays, we'll update this
300 _voxelsDirty = false;302 _voxelsDirty = false;
@@ -583,17 +585,71 @@ void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) { · 282 unmodified lines
583 setupNewVoxelsForDrawing();585 setupNewVoxelsForDrawing();
584}586}
585 587
588// combines the removeOutOfView args into a single class
589class removeOutOfViewArgs {
590public:
591 VoxelSystem* thisVoxelSystem;
592 VoxelNodeBag dontRecurseBag;
593 unsigned long nodesScanned;
594 unsigned long nodesRemoved;
595 unsigned long nodesInside;
596 unsigned long nodesIntersect;
597 unsigned long nodesOutside;
598
599 removeOutOfViewArgs(VoxelSystem* voxelSystem) :
600 thisVoxelSystem(voxelSystem),
601 dontRecurseBag(),
602 nodesScanned(0),
603 nodesRemoved(0),
604 nodesInside(0),
605 nodesIntersect(0),
606 nodesOutside(0)
607 { }
608};
609
586// "Remove" voxels from the tree that are not in view. We don't actually delete them,610// "Remove" voxels from the tree that are not in view. We don't actually delete them,
587// we remove them from the tree and place them into a holding area for later deletion611// we remove them from the tree and place them into a holding area for later deletion
588bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) {612bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) {
589 VoxelSystem* thisVoxelSystem = (VoxelSystem*) extraData;613 removeOutOfViewArgs* args = (removeOutOfViewArgs*)extraData;
590 _nodeCount++;614
615 // If our node was previously added to the don't recurse bag, then return false to
616 // stop the further recursion. This means that the whole node and it's children are
617 // known to be in view, so don't recurse them
618 if (args->dontRecurseBag.contains(node)) {
619 args->dontRecurseBag.remove(node);
620 return false; // stop recursion
621 }
622
623 VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
624 args->nodesScanned++;
591 // Need to operate on our child nodes, so we can remove them625 // Need to operate on our child nodes, so we can remove them
592 for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {626 for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
593 VoxelNode* childNode = node->getChildAtIndex(i);627 VoxelNode* childNode = node->getChildAtIndex(i);
594 if (childNode && !childNode->isInView(*thisVoxelSystem->_viewFrustum)) {628 if (childNode) {
595 node->removeChildAtIndex(i);629 ViewFrustum::location inFrustum = childNode->inFrustum(*thisVoxelSystem->_viewFrustum);
596 thisVoxelSystem->_removedVoxels.insert(childNode);630 switch (inFrustum) {
631 case ViewFrustum::OUTSIDE: {
632 args->nodesOutside++;
633 args->nodesRemoved++;
634 node->removeChildAtIndex(i);
635 thisVoxelSystem->_removedVoxels.insert(childNode);
636 // by removing the child, it will not get recursed!
637 } break;
638 case ViewFrustum::INSIDE: {
639 // if the child node is fully INSIDE the view, then there's no need to recurse it
640 // because we know all it's children will also be in the view, so we want to
641 // tell the caller to NOT recurse this child
642 args->nodesInside++;
643 args->dontRecurseBag.insert(childNode);
644 } break;
645 case ViewFrustum::INTERSECT: {
646 // if the child node INTERSECTs the view, then we don't want to remove it because
647 // it is at least partially in view. But we DO want to recurse the children because
648 // some of them may not be in view... nothing specifically to do, just keep iterating
649 // the children
650 args->nodesIntersect++;
651 } break;
652 }
597 }653 }
598 }654 }
599 return true; // keep going!655 return true; // keep going!
@@ -609,7 +665,14 @@ bool VoxelSystem::hasViewChanged() { · 9 unmodified lines
609}665}
610 666
611void VoxelSystem::removeOutOfView() {667void VoxelSystem::removeOutOfView() {
612 PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()"); // would like to include removedCount, _nodeCount, _removedVoxels.count()668 PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()");
613 _nodeCount = 0;669 removeOutOfViewArgs args(this);
614 _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)this);670 _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);
671
672 if (_renderWarningsOn) {
673 printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld bag.count()=%d \n",
674 args.nodesScanned, args.nodesRemoved, args.nodesInside,
675 args.nodesIntersect, args.nodesOutside, args.dontRecurseBag.count()
676 );
677 }
615}678}