diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 1005da8850..5ee098a775 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -149,7 +149,12 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { void VoxelSystem::setupNewVoxelsForDrawing() { double start = usecTimestampNow(); - _voxelsUpdated = newTreeToArrays(_tree->rootNode); + if (_tree->isDirty()) { + _voxelsUpdated = newTreeToArrays(_tree->rootNode); + _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean + } else { + _voxelsUpdated = 0; + } if (_voxelsUpdated) { _voxelsDirty=true; } @@ -248,8 +253,8 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { _voxelsInArrays++; // our know vertices in the arrays } voxelsUpdated++; - node->clearDirtyBit(); } + node->clearDirtyBit(); // always clear the dirty bit, even if it doesn't need to be rendered return voxelsUpdated; } diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 776aec7a9a..80da795fe1 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -143,6 +143,8 @@ void VoxelNode::setFalseColored(bool isFalseColored) { void VoxelNode::setColor(const nodeColor& color) { if (_trueColor[0] != color[0] || _trueColor[1] != color[1] || _trueColor[2] != color[2]) { + //printLog("VoxelNode::setColor() was: (%d,%d,%d) is: (%d,%d,%d)\n", + // _trueColor[0],_trueColor[1],_trueColor[2],color[0],color[1],color[2]); memcpy(&_trueColor,&color,sizeof(nodeColor)); if (!_falseColored) { memcpy(&_currentColor,&color,sizeof(nodeColor)); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index ba13ee1c28..f781c16b0d 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -35,7 +35,8 @@ VoxelTree::VoxelTree() : voxelsBytesRead(0), voxelsCreatedStats(100), voxelsColoredStats(100), - voxelsBytesReadStats(100) { + voxelsBytesReadStats(100), + _isDirty(true) { rootNode = new VoxelNode(); rootNode->octalCode = new unsigned char[1]; @@ -127,10 +128,13 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, // check the colors mask to see if we have a child to color in if (oneAtBit(*nodeData, i)) { // create the child if it doesn't exist - if (destinationNode->children[i] == NULL) { + if (!destinationNode->children[i]) { destinationNode->addChildAtIndex(i); - this->voxelsCreated++; - this->voxelsCreatedStats.updateAverage(1); + if (destinationNode->isDirty()) { + _isDirty = true; + } + voxelsCreated++; + voxelsCreatedStats.updateAverage(1); } // pull the color for this child @@ -138,6 +142,9 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, memcpy(newColor, nodeData + bytesRead, 3); newColor[3] = 1; destinationNode->children[i]->setColor(newColor); + if (destinationNode->children[i]->isDirty()) { + _isDirty = true; + } this->voxelsColored++; this->voxelsColoredStats.updateAverage(1); @@ -146,6 +153,9 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, } // average node's color based on color of children destinationNode->setColorFromAverageOfChildren(); + if (destinationNode->isDirty()) { + _isDirty = true; + } // give this destination node the child mask from the packet unsigned char childMask = *(nodeData + bytesRead); @@ -157,9 +167,12 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, // check the exists mask to see if we have a child to traverse into if (oneAtBit(childMask, childIndex)) { - if (destinationNode->children[childIndex] == NULL) { + if (!destinationNode->children[childIndex]) { // add a child at that index, if it doesn't exist destinationNode->addChildAtIndex(childIndex); + if (destinationNode->isDirty()) { + _isDirty = true; + } this->voxelsCreated++; this->voxelsCreatedStats.updateAverage(this->voxelsCreated); } @@ -193,6 +206,9 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, int bufferSizeByt // Note: we need to create this node relative to root, because we're assuming that the bitstream for the initial // octal code is always relative to root! bitstreamRootNode = createMissingNode(rootNode, (unsigned char*) bitstreamAt); + if (bitstreamRootNode->isDirty()) { + _isDirty = true; + } } int octalCodeBytes = bytesRequiredForCodeLength(*bitstreamAt); diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 7f5a6b866b..1209868c62 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -54,6 +54,9 @@ public: VoxelNodeBag& bag); int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag); + + bool isDirty() const { return _isDirty; }; + void clearDirtyBit() { _isDirty = false; }; private: int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, @@ -68,6 +71,8 @@ private: VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode); VoxelNode* createMissingNode(VoxelNode* lastParentNode, unsigned char* deepestCodeToCreate); int readNodeData(VoxelNode *destinationNode, unsigned char* nodeData, int bufferSizeBytes); + + bool _isDirty; }; int boundaryDistanceForRenderLevel(unsigned int renderLevel);