Showing the changes to interface/src/VoxelSystem.cpp (1 of 24 files). Show all
Unified · Split
| @@ -139,22 +139,22 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 138 unmodified lines | |||
| 139 | double start = usecTimestampNow(); | 139 | double start = usecTimestampNow(); |
| 140 | double sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000.0; | 140 | double sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000.0; |
| 141 | 141 | ||
| 142 | if (sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed,SIXTY_FPS_IN_MILLISECONDS)) { | 142 | if (sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) { |
| 143 | return; // bail early, it hasn't been long enough since the last time we ran | 143 | return; // bail early, it hasn't been long enough since the last time we ran |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0; | 146 | double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0; |
| 147 | |||
| 148 | // If the view frustum has changed, since last time, then remove nodes that are out of view | 147 | // 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()) { | 148 | if ((sinceLastViewCulling >= std::max(_lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) && hasViewChanged()) { |
| 150 | _lastViewCulling = start; | 149 | _lastViewCulling = start; |
| 151 | removeOutOfView(); | 150 | removeOutOfView(); |
| 151 | double endViewCulling = usecTimestampNow(); | ||
| 152 | _lastViewCullingElapsed = (endViewCulling - start) / 1000.0; | ||
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | if (_tree->isDirty()) { | 155 | if (_tree->isDirty()) { |
| 155 | PerformanceWarning warn(_renderWarningsOn, "calling... newTreeToArrays()"); | 156 | PerformanceWarning warn(_renderWarningsOn, "calling... newTreeToArrays()"); |
| 156 | _callsToTreesToArrays++; | 157 | _callsToTreesToArrays++; |
| 157 | |||
| 158 | if (_alwaysRenderFullVBO) { | 158 | if (_alwaysRenderFullVBO) { |
| 159 | _voxelsInWriteArrays = 0; // reset our VBO | 159 | _voxelsInWriteArrays = 0; // reset our VBO |
| 160 | } | 160 | } |
| @@ -171,7 +171,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 10 unmodified lines | |||
| 171 | copyWrittenDataToReadArrays(); | 171 | copyWrittenDataToReadArrays(); |
| 172 | 172 | ||
| 173 | double end = usecTimestampNow(); | 173 | double end = usecTimestampNow(); |
| 174 | double elapsedmsec = (end - start)/1000.0; | 174 | double elapsedmsec = (end - start) / 1000.0; |
| 175 | _setupNewVoxelsForDrawingLastFinished = end; | 175 | _setupNewVoxelsForDrawingLastFinished = end; |
| 176 | _setupNewVoxelsForDrawingLastElapsed = elapsedmsec; | 176 | _setupNewVoxelsForDrawingLastElapsed = elapsedmsec; |
| 177 | } | 177 | } |
| @@ -220,6 +220,11 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { · 42 unmodified lines | |||
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | int VoxelSystem::newway__updateNodeInArray(VoxelNode* node) { | 222 | int VoxelSystem::newway__updateNodeInArray(VoxelNode* node) { |
| 223 | // If we've run out of room, then just bail... | ||
| 224 | if (_voxelsInWriteArrays >= MAX_VOXELS_PER_SYSTEM) { | ||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 223 | if (node->getShouldRender()) { | 228 | if (node->getShouldRender()) { |
| 224 | glm::vec3 startVertex = node->getCorner(); | 229 | glm::vec3 startVertex = node->getCorner(); |
| 225 | float voxelScale = node->getScale(); | 230 | float voxelScale = node->getScale(); |
| @@ -294,7 +299,7 @@ void VoxelSystem::init() { · 68 unmodified lines | |||
| 294 | _callsToTreesToArrays = 0; | 299 | _callsToTreesToArrays = 0; |
| 295 | _setupNewVoxelsForDrawingLastFinished = 0; | 300 | _setupNewVoxelsForDrawingLastFinished = 0; |
| 296 | _setupNewVoxelsForDrawingLastElapsed = 0; | 301 | _setupNewVoxelsForDrawingLastElapsed = 0; |
| 297 | _lastViewCulling = 0; | 302 | _lastViewCullingElapsed = _lastViewCulling = 0; |
| 298 | 303 | ||
| 299 | // When we change voxels representations in the arrays, we'll update this | 304 | // When we change voxels representations in the arrays, we'll update this |
| 300 | _voxelsDirty = false; | 305 | _voxelsDirty = false; |
| @@ -583,17 +588,71 @@ void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) { · 282 unmodified lines | |||
| 583 | setupNewVoxelsForDrawing(); | 588 | setupNewVoxelsForDrawing(); |
| 584 | } | 589 | } |
| 585 | 590 | ||
| 591 | // combines the removeOutOfView args into a single class | ||
| 592 | class removeOutOfViewArgs { | ||
| 593 | public: | ||
| 594 | VoxelSystem* thisVoxelSystem; | ||
| 595 | VoxelNodeBag dontRecurseBag; | ||
| 596 | unsigned long nodesScanned; | ||
| 597 | unsigned long nodesRemoved; | ||
| 598 | unsigned long nodesInside; | ||
| 599 | unsigned long nodesIntersect; | ||
| 600 | unsigned long nodesOutside; | ||
| 601 | |||
| 602 | removeOutOfViewArgs(VoxelSystem* voxelSystem) : | ||
| 603 | thisVoxelSystem(voxelSystem), | ||
| 604 | dontRecurseBag(), | ||
| 605 | nodesScanned(0), | ||
| 606 | nodesRemoved(0), | ||
| 607 | nodesInside(0), | ||
| 608 | nodesIntersect(0), | ||
| 609 | nodesOutside(0) | ||
| 610 | { } | ||
| 611 | }; | ||
| 612 | |||
| 586 | // "Remove" voxels from the tree that are not in view. We don't actually delete them, | 613 | // "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 deletion | 614 | // we remove them from the tree and place them into a holding area for later deletion |
| 588 | bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) { | 615 | bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) { |
| 589 | VoxelSystem* thisVoxelSystem = (VoxelSystem*) extraData; | 616 | removeOutOfViewArgs* args = (removeOutOfViewArgs*)extraData; |
| 590 | _nodeCount++; | 617 | |
| 618 | // If our node was previously added to the don't recurse bag, then return false to | ||
| 619 | // stop the further recursion. This means that the whole node and it's children are | ||
| 620 | // known to be in view, so don't recurse them | ||
| 621 | if (args->dontRecurseBag.contains(node)) { | ||
| 622 | args->dontRecurseBag.remove(node); | ||
| 623 | return false; // stop recursion | ||
| 624 | } | ||
| 625 | |||
| 626 | VoxelSystem* thisVoxelSystem = args->thisVoxelSystem; | ||
| 627 | args->nodesScanned++; | ||
| 591 | // Need to operate on our child nodes, so we can remove them | 628 | // Need to operate on our child nodes, so we can remove them |
| 592 | for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { | 629 | for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { |
| 593 | VoxelNode* childNode = node->getChildAtIndex(i); | 630 | VoxelNode* childNode = node->getChildAtIndex(i); |
| 594 | if (childNode && !childNode->isInView(*thisVoxelSystem->_viewFrustum)) { | 631 | if (childNode) { |
| 595 | node->removeChildAtIndex(i); | 632 | ViewFrustum::location inFrustum = childNode->inFrustum(*thisVoxelSystem->_viewFrustum); |
| 596 | thisVoxelSystem->_removedVoxels.insert(childNode); | 633 | switch (inFrustum) { |
| 634 | case ViewFrustum::OUTSIDE: { | ||
| 635 | args->nodesOutside++; | ||
| 636 | args->nodesRemoved++; | ||
| 637 | node->removeChildAtIndex(i); | ||
| 638 | thisVoxelSystem->_removedVoxels.insert(childNode); | ||
| 639 | // by removing the child, it will not get recursed! | ||
| 640 | } break; | ||
| 641 | case ViewFrustum::INSIDE: { | ||
| 642 | // if the child node is fully INSIDE the view, then there's no need to recurse it | ||
| 643 | // because we know all it's children will also be in the view, so we want to | ||
| 644 | // tell the caller to NOT recurse this child | ||
| 645 | args->nodesInside++; | ||
| 646 | args->dontRecurseBag.insert(childNode); | ||
| 647 | } break; | ||
| 648 | case ViewFrustum::INTERSECT: { | ||
| 649 | // if the child node INTERSECTs the view, then we don't want to remove it because | ||
| 650 | // it is at least partially in view. But we DO want to recurse the children because | ||
| 651 | // some of them may not be in view... nothing specifically to do, just keep iterating | ||
| 652 | // the children | ||
| 653 | args->nodesIntersect++; | ||
| 654 | } break; | ||
| 655 | } | ||
| 597 | } | 656 | } |
| 598 | } | 657 | } |
| 599 | return true; // keep going! | 658 | return true; // keep going! |
| @@ -609,9 +668,16 @@ bool VoxelSystem::hasViewChanged() { · 9 unmodified lines | |||
| 609 | } | 668 | } |
| 610 | 669 | ||
| 611 | void VoxelSystem::removeOutOfView() { | 670 | void VoxelSystem::removeOutOfView() { |
| 612 | PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()"); // would like to include removedCount, _nodeCount, _removedVoxels.count() | 671 | PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()"); |
| 613 | _nodeCount = 0; | 672 | removeOutOfViewArgs args(this); |
| 614 | _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)this); | 673 | _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args); |
| 674 | |||
| 675 | if (_renderWarningsOn) { | ||
| 676 | printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld bag.count()=%d \n", | ||
| 677 | args.nodesScanned, args.nodesRemoved, args.nodesInside, | ||
| 678 | args.nodesIntersect, args.nodesOutside, args.dontRecurseBag.count() | ||
| 679 | ); | ||
| 680 | } | ||
| 615 | } | 681 | } |
| 616 | 682 | ||
| 617 | bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance) { | 683 | bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance) { |