From 18cbb2d00f254593b1db520290fc598b6b60a52b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 12 Dec 2013 15:09:30 -0800 Subject: [PATCH] particle tree pruning on update --- .../octree-server/src/OctreePersistThread.cpp | 2 ++ libraries/octree/src/Octree.cpp | 25 +++++++++++-------- libraries/octree/src/OctreeElement.cpp | 6 +++-- libraries/particles/src/ParticleTree.cpp | 14 +++++++++++ libraries/particles/src/ParticleTree.h | 1 + libraries/particles/src/ParticleTreeElement.h | 3 ++- 6 files changed, 37 insertions(+), 14 deletions(-) diff --git a/libraries/octree-server/src/OctreePersistThread.cpp b/libraries/octree-server/src/OctreePersistThread.cpp index aba683e110..4361ae1044 100644 --- a/libraries/octree-server/src/OctreePersistThread.cpp +++ b/libraries/octree-server/src/OctreePersistThread.cpp @@ -68,7 +68,9 @@ bool OctreePersistThread::process() { usleep(USECS_TO_SLEEP); // do our updates then check to save... + _tree->lockForWrite(); _tree->update(); + _tree->unlock(); uint64_t now = usecTimestampNow(); uint64_t sinceLastSave = now - _lastCheck; diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 724a52808d..d10248d9e3 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -1083,19 +1083,22 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* node, for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { if (oneAtBit(childrenColoredBits, i)) { OctreeElement* childNode = node->getChildAtIndex(i); - continueThisLevel = childNode->appendElementData(packetData); - - if (!continueThisLevel) { - break; // no point in continuing - } - - bytesAtThisLevel += BYTES_PER_COLOR; // keep track of byte count for color + if (childNode) { + int bytesBeforeChild = packetData->getUncompressedSize(); + continueThisLevel = childNode->appendElementData(packetData); + int bytesAfterChild = packetData->getUncompressedSize(); + + if (!continueThisLevel) { + break; // no point in continuing + } + + bytesAtThisLevel += (bytesAfterChild - bytesBeforeChild); // keep track of byte count for this child - // don't need to check childNode here, because we can't get here with no childNode - if (params.stats) { - params.stats->colorSent(childNode); + // don't need to check childNode here, because we can't get here with no childNode + if (params.stats) { + params.stats->colorSent(childNode); + } } - } } } diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index 5a11e0ec5c..b7a791991b 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -196,7 +196,7 @@ void OctreeElement::calculateAABox() { void OctreeElement::deleteChildAtIndex(int childIndex) { OctreeElement* childAt = getChildAtIndex(childIndex); if (childAt) { -printf("deleteChildAtIndex()... about to call delete childAt=%p\n",childAt); + //printf("deleteChildAtIndex()... about to call delete childAt=%p\n",childAt); delete childAt; setChildAtIndex(childIndex, NULL); _isDirty = true; @@ -1292,7 +1292,9 @@ OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float float ourScale = getScale(); float halfOurScale = ourScale / 2.0f; - assert(s <= ourScale); // This should never happen + if(s > ourScale) { + printf("UNEXPECTED -- OctreeElement::getOrCreateChildElementAt() s=[%f] > ourScale=[%f] \n", s, ourScale); + } if (s > halfOurScale) { return this; diff --git a/libraries/particles/src/ParticleTree.cpp b/libraries/particles/src/ParticleTree.cpp index 152f1dec69..c1fd6d8bbb 100644 --- a/libraries/particles/src/ParticleTree.cpp +++ b/libraries/particles/src/ParticleTree.cpp @@ -169,6 +169,17 @@ bool ParticleTree::updateOperation(OctreeElement* element, void* extraData) { return true; } +bool ParticleTree::pruneOperation(OctreeElement* element, void* extraData) { + ParticleTreeElement* particleTreeElement = static_cast(element); + for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { + ParticleTreeElement* childAt = particleTreeElement->getChildAtIndex(i); + if (childAt && childAt->isLeaf() && !childAt->hasParticles()) { + particleTreeElement->deleteChildAtIndex(i); + } + } + return true; +} + void ParticleTree::update() { _isDirty = true; @@ -187,6 +198,9 @@ void ParticleTree::update() { storeParticle(args._movingParticles[i]); } } + + // prune the tree... + recurseTreeWithOperation(pruneOperation, NULL); } diff --git a/libraries/particles/src/ParticleTree.h b/libraries/particles/src/ParticleTree.h index 2491934252..9d7d4a98f8 100644 --- a/libraries/particles/src/ParticleTree.h +++ b/libraries/particles/src/ParticleTree.h @@ -53,6 +53,7 @@ private: static bool updateOperation(OctreeElement* element, void* extraData); static bool findAndUpdateOperation(OctreeElement* element, void* extraData); static bool findNearPointOperation(OctreeElement* element, void* extraData); + static bool pruneOperation(OctreeElement* element, void* extraData); void notifyNewlyCreatedParticle(const Particle& newParticle, Node* senderNode); diff --git a/libraries/particles/src/ParticleTreeElement.h b/libraries/particles/src/ParticleTreeElement.h index 292e0fe745..b513a4a860 100644 --- a/libraries/particles/src/ParticleTreeElement.h +++ b/libraries/particles/src/ParticleTreeElement.h @@ -71,9 +71,10 @@ public: /// shouldRender() state, the tree will remark elements as changed even in cases there the elements have not changed. virtual bool isRendered() const { return getShouldRender(); } - virtual bool deleteApproved() const { return (_particles.size() == 0); } + virtual bool deleteApproved() const { return !hasParticles(); } const std::vector& getParticles() const { return _particles; } + bool hasParticles() const { return _particles.size() > 0; } void update(ParticleTreeUpdateArgs& args); void setTree(ParticleTree* tree) { _myTree = tree; }