diff --git a/libraries/voxels/src/VoxelSceneStats.cpp b/libraries/voxels/src/VoxelSceneStats.cpp index 254f099e3f..7d91a363c5 100644 --- a/libraries/voxels/src/VoxelSceneStats.cpp +++ b/libraries/voxels/src/VoxelSceneStats.cpp @@ -68,17 +68,8 @@ void VoxelSceneStats::reset() { _leavesDidntFit = 0; _colorBitsWritten = 0; - _internalColorBitsWritten = 0; - _leavesColorBitsWritten = 0; - _existsBitsWritten = 0; - _internalExistsBitsWritten = 0; - _leavesExistsBitsWritten = 0; - _existsInPacketBitsWritten = 0; - _internalExistsInPacketBitsWritten = 0; - _leavesExistsInPacketBitsWritten = 0; - } void VoxelSceneStats::packetSent(int bytes) { @@ -158,33 +149,27 @@ void VoxelSceneStats::didntFit(const VoxelNode* node) { } } -void VoxelSceneStats::colorBitsWritten(const VoxelNode* node) { +void VoxelSceneStats::colorBitsWritten() { _colorBitsWritten++; - if (node->isLeaf()) { - _leavesColorBitsWritten++; - } else { - _internalColorBitsWritten++; - } } -void VoxelSceneStats::existsBitsWritten(const VoxelNode* node) { +void VoxelSceneStats::existsBitsWritten() { _existsBitsWritten++; - if (node->isLeaf()) { - _leavesExistsBitsWritten++; - } else { - _internalExistsBitsWritten++; - } } -void VoxelSceneStats::existsInPacketBitsWritten(const VoxelNode* node) { +void VoxelSceneStats::existsInPacketBitsWritten() { _existsInPacketBitsWritten++; - if (node->isLeaf()) { - _leavesExistsInPacketBitsWritten++; - } else { - _internalExistsInPacketBitsWritten++; - } } +void VoxelSceneStats::childBitsRemoved(bool includesExistsBits, bool includesColors) { + _existsInPacketBitsWritten--; + if (includesExistsBits) { + _existsBitsWritten--; + } + if (includesColors) { + _colorBitsWritten--; + } +} void VoxelSceneStats::printDebugDetails() { @@ -227,12 +212,6 @@ void VoxelSceneStats::printDebugDetails() { qDebug(" internal : %lu\n", _internalDidntFit ); qDebug(" leaves : %lu\n", _leavesDidntFit ); qDebug(" color bits : %lu\n", _colorBitsWritten ); - qDebug(" internal : %lu\n", _internalColorBitsWritten ); - qDebug(" leaves : %lu\n", _leavesColorBitsWritten ); qDebug(" exists bits : %lu\n", _existsBitsWritten ); - qDebug(" internal : %lu\n", _internalExistsBitsWritten); - qDebug(" leaves : %lu\n", _leavesExistsBitsWritten ); - qDebug(" in packet bit : %lu\n", _existsInPacketBitsWritten ); - qDebug(" internal : %lu\n", _internalExistsInPacketBitsWritten); - qDebug(" leaves : %lu\n", _leavesExistsInPacketBitsWritten ); + qDebug(" in packet bit : %lu\n", _existsInPacketBitsWritten); } diff --git a/libraries/voxels/src/VoxelSceneStats.h b/libraries/voxels/src/VoxelSceneStats.h index 29461996b3..526d7f38a6 100644 --- a/libraries/voxels/src/VoxelSceneStats.h +++ b/libraries/voxels/src/VoxelSceneStats.h @@ -31,9 +31,10 @@ public: void skippedOccluded(const VoxelNode* node); void colorSent(const VoxelNode* node); void didntFit(const VoxelNode* node); - void colorBitsWritten(const VoxelNode* node); - void existsBitsWritten(const VoxelNode* node); - void existsInPacketBitsWritten(const VoxelNode* node); + void colorBitsWritten(); + void existsBitsWritten(); + void existsInPacketBitsWritten(); + void childBitsRemoved(bool includesExistsBits, bool includesColors); private: // scene timing data in usecs @@ -75,24 +76,19 @@ private: unsigned long _leavesDidntFit; unsigned long _colorBitsWritten; - unsigned long _internalColorBitsWritten; - unsigned long _leavesColorBitsWritten; - unsigned long _existsBitsWritten; - unsigned long _internalExistsBitsWritten; - unsigned long _leavesExistsBitsWritten; - unsigned long _existsInPacketBitsWritten; - unsigned long _internalExistsInPacketBitsWritten; - unsigned long _leavesExistsInPacketBitsWritten; - unsigned long total; - unsigned long internalOutOfView; - unsigned long internalOccluded; - unsigned long internalDirty; - unsigned long leavesOutOfView; - unsigned long leavesOccluded; - unsigned long leavesDirty; + // Accounting Notes: + // + // 1) number of voxels sent can be calculated as _colorSent + _colorBitsWritten. This works because each internal + // node in a packet will have a _colorBitsWritten included for it and each "leaf" in the packet will have a + // _colorSent written for it. Note that these "leaf" nodes in the packets may not be actual leaves in the full + // tree, because LOD may cause us to send an average color for an internal node instead of recursing deeper to + // the leaves. + // + // 2) the stats balance if: _traversed = all skipped + all sent + // // scene network related data unsigned int _packets; diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 13e55bea0f..2939cd3258 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1302,7 +1302,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp // track some stats if (params.stats) { - if (!shouldRender) { + if (!shouldRender && childNode->isLeaf()) { params.stats->skippedDistance(childNode); } if (childIsOccluded) { @@ -1352,7 +1352,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp writeToThisLevelBuffer += sizeof(childrenColoredBits); // move the pointer bytesAtThisLevel += sizeof(childrenColoredBits); // keep track of byte count if (params.stats) { - params.stats->colorBitsWritten(node); + params.stats->colorBitsWritten(); } // write the color data... @@ -1379,7 +1379,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp writeToThisLevelBuffer += sizeof(childrenExistInTreeBits); // move the pointer bytesAtThisLevel += sizeof(childrenExistInTreeBits); // keep track of byte count if (params.stats) { - params.stats->existsBitsWritten(node); + params.stats->existsBitsWritten(); } } @@ -1388,7 +1388,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp writeToThisLevelBuffer += sizeof(childrenExistInPacketBits); // move the pointer bytesAtThisLevel += sizeof(childrenExistInPacketBits); // keep track of byte count if (params.stats) { - params.stats->existsInPacketBitsWritten(node); + params.stats->existsInPacketBitsWritten(); } // We only need to keep digging, if there is at least one child that is inView, and not a leaf. @@ -1467,7 +1467,12 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp // so, if the child returns 2 bytes out, we can actually consider that an empty tree also!! // // we can make this act like no bytes out, by just resetting the bytes out in this case - if (params.includeColor && childTreeBytesOut == 2) { + if (params.includeColor && !params.includeExistsBits && childTreeBytesOut == 2) { + childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees + } + // If we've asked for existBits, this is also true, except that the tree will output 3 bytes + // NOTE: does this introduce a problem with detecting deletion?? + if (params.includeColor && params.includeExistsBits && childTreeBytesOut == 3) { childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees } @@ -1482,6 +1487,11 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp childrenExistInPacketBits -= (1 << (7 - originalIndex)); // repair the child exists mask *childExistsPlaceHolder = childrenExistInPacketBits; + + if (params.stats) { + params.stats->childBitsRemoved(params.includeExistsBits, params.includeColor); + } + // Note: no need to move the pointer, cause we already stored this } // end if (childTreeBytesOut == 0) } // end if (oneAtBit(childrenExistInPacketBits, originalIndex)) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 770a22bd23..92c835d776 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -143,6 +143,7 @@ void deepestLevelVoxelDistributor(NodeList* nodeList, } nodeList->getNodeSocket()->send(node->getActiveSocket(), nodeData->getPacket(), nodeData->getPacketLength()); + nodeData->stats.packetSent(nodeData->getPacketLength()); trueBytesSent += nodeData->getPacketLength(); truePacketsSent++; nodeData->resetVoxelPacket(); @@ -261,7 +262,6 @@ void deepestLevelVoxelDistributor(NodeList* nodeList, } else { nodeList->getNodeSocket()->send(node->getActiveSocket(), nodeData->getPacket(), nodeData->getPacketLength()); - nodeData->stats.packetSent(nodeData->getPacketLength()); trueBytesSent += nodeData->getPacketLength(); truePacketsSent++;