From 34cebc36c75024e06c6410ffd5e6b46360615c30 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 11 Jul 2013 09:11:09 -0700 Subject: [PATCH] short circuit node recursion for delta sending --- libraries/voxels/src/VoxelTree.cpp | 26 +++++++++++++++++++------- voxel-server/src/VoxelNodeData.cpp | 7 +++++-- voxel-server/src/VoxelNodeData.h | 1 + voxel-server/src/main.cpp | 4 +++- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 70bca504cb..3be28e9b93 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1182,7 +1182,26 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp if (!node->isInView(*params.viewFrustum)) { return bytesAtThisLevel; } + + // Ok, we are in view, but if we're in delta mode, then we also want to make sure we weren't already in view + // because we don't send nodes from the previously know in view frustum. + bool wasInView = false; + + if (params.deltaViewFrustum && params.lastViewFrustum) { + ViewFrustum::location location = node->inFrustum(*params.lastViewFrustum); + + // If we're a leaf, then either intersect or inside is considered "formerly in view" + if (node->isLeaf()) { + wasInView = location != ViewFrustum::OUTSIDE; + } else { + wasInView = location == ViewFrustum::INSIDE; + } + } + // If we were in view, then bail out early! + if (wasInView) { + return bytesAtThisLevel; + } // If the user also asked for occlusion culling, check if this node is occluded, but only if it's not a leaf. // leaf occlusion is handled down below when we check child nodes @@ -1200,16 +1219,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp CoverageMapStorageResult result = params.map->checkMap(voxelPolygon, false); delete voxelPolygon; // cleanup if (result == OCCLUDED) { - //node->printDebugDetails("upper section, non-Leaf is occluded!! node="); - //args->nonLeavesOccluded++; - - //args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1); - //args->totalVoxels += (subArgs.voxelsTouched - 1); - return bytesAtThisLevel; } } else { - //node->printDebugDetails("upper section, shadow Not in view node="); // If this shadow wasn't "all in view" then we ignored it for occlusion culling, but // we do need to clean up memory and proceed as normal... delete voxelPolygon; diff --git a/voxel-server/src/VoxelNodeData.cpp b/voxel-server/src/VoxelNodeData.cpp index f2cce906cf..a9fc4a8620 100644 --- a/voxel-server/src/VoxelNodeData.cpp +++ b/voxel-server/src/VoxelNodeData.cpp @@ -17,7 +17,8 @@ VoxelNodeData::VoxelNodeData(Node* owningNode) : _voxelPacketAvailableBytes(MAX_VOXEL_PACKET_SIZE), _maxSearchLevel(1), _maxLevelReachedInLastSearch(1), - _lastTimeBagEmpty(0) + _lastTimeBagEmpty(0), + _viewFrustumChanging(false) { _voxelPacket = new unsigned char[MAX_VOXEL_PACKET_SIZE]; _voxelPacketAt = _voxelPacket; @@ -27,7 +28,8 @@ VoxelNodeData::VoxelNodeData(Node* owningNode) : void VoxelNodeData::resetVoxelPacket() { - _voxelPacket[0] = getWantColor() ? PACKET_HEADER_VOXEL_DATA : PACKET_HEADER_VOXEL_DATA_MONOCHROME; + bool wantColor = getWantColor(); + _voxelPacket[0] = wantColor ? PACKET_HEADER_VOXEL_DATA : PACKET_HEADER_VOXEL_DATA_MONOCHROME; _voxelPacketAt = &_voxelPacket[1]; _voxelPacketAvailableBytes = MAX_VOXEL_PACKET_SIZE - 1; _voxelPacketWaiting = false; @@ -63,6 +65,7 @@ bool VoxelNodeData::updateCurrentViewFrustum() { _currentViewFrustum.calculate(); currentViewFrustumChanged = true; } + _viewFrustumChanging = currentViewFrustumChanged; return currentViewFrustumChanged; } diff --git a/voxel-server/src/VoxelNodeData.h b/voxel-server/src/VoxelNodeData.h index bb30372f35..66fa096a3a 100644 --- a/voxel-server/src/VoxelNodeData.h +++ b/voxel-server/src/VoxelNodeData.h @@ -67,6 +67,7 @@ private: ViewFrustum _currentViewFrustum; ViewFrustum _lastKnownViewFrustum; long long _lastTimeBagEmpty; + bool _viewFrustumChanging; }; diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index e71e456359..b6a3833275 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -128,6 +128,8 @@ void deepestLevelVoxelDistributor(NodeList* nodeList, // FOR NOW... node tells us if it wants to receive only view frustum deltas bool wantDelta = viewFrustumChanged && nodeData->getWantDelta(); + bool wantColor = nodeData->getWantColor(); + const ViewFrustum* lastViewFrustum = wantDelta ? &nodeData->getLastKnownViewFrustum() : NULL; if (::debugVoxelSending) { @@ -227,7 +229,7 @@ void deepestLevelVoxelDistributor(NodeList* nodeList, bool wantOcclusionCulling = nodeData->getWantOcclusionCulling(); CoverageMap* coverageMap = wantOcclusionCulling ? &nodeData->map : IGNORE_COVERAGE_MAP; - EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), nodeData->getWantColor(), + EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor, WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum, wantOcclusionCulling, coverageMap);