diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 4d9c45ed6c..598d8ea722 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -55,6 +55,7 @@ void MetavoxelServer::run() { _persister = new MetavoxelPersister(this); QThread* persistenceThread = new QThread(this); _persister->moveToThread(persistenceThread); + _persister->connect(persistenceThread, SIGNAL(finished()), SLOT(deleteLater())); persistenceThread->start(); // queue up the load diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index 64b2646261..670f0be389 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -213,7 +213,11 @@ void Attribute::writeMetavoxelDelta(const MetavoxelNode& root, const MetavoxelNo } void Attribute::readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state) { - data.getRoot(state.attribute)->readSubdivision(state); + // copy if changed + MetavoxelNode* root = data.getRoot(state.attribute); + if (root->readSubdivision(state)) { + data.setRoot(state.attribute, new MetavoxelNode(state.attribute, root)); + } } void Attribute::writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) { diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 1362731a8a..72d5392a39 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -603,12 +603,18 @@ void MetavoxelData::writeDelta(const MetavoxelData& reference, const MetavoxelLO } } -MetavoxelNode* MetavoxelData::createRoot(const AttributePointer& attribute) { - MetavoxelNode*& root = _roots[attribute]; - if (root) { - root->decrementReferenceCount(attribute); +void MetavoxelData::setRoot(const AttributePointer& attribute, MetavoxelNode* root) { + MetavoxelNode*& rootReference = _roots[attribute]; + if (rootReference) { + rootReference->decrementReferenceCount(attribute); } - return root = new MetavoxelNode(attribute); + rootReference = root; +} + +MetavoxelNode* MetavoxelData::createRoot(const AttributePointer& attribute) { + MetavoxelNode* root = new MetavoxelNode(attribute); + setRoot(attribute, root); + return root; } bool MetavoxelData::deepEquals(const MetavoxelData& other, const MetavoxelLOD& lod) const { @@ -843,10 +849,12 @@ void MetavoxelNode::readDelta(const MetavoxelNode& reference, MetavoxelStreamSta _children[i] = new MetavoxelNode(state.attribute); _children[i]->readDelta(*reference._children[i], nextState); } else { - _children[i] = reference._children[i]; - _children[i]->incrementReferenceCount(); - if (nextState.becameSubdivided()) { - _children[i]->readSubdivision(nextState); + if (nextState.becameSubdivided() && reference._children[i]->readSubdivision(nextState)) { + _children[i] = new MetavoxelNode(state.attribute, reference._children[i]); + + } else { + _children[i] = reference._children[i]; + _children[i]->incrementReferenceCount(); } } } @@ -888,7 +896,7 @@ void MetavoxelNode::writeDelta(const MetavoxelNode& reference, MetavoxelStreamSt } } -void MetavoxelNode::readSubdivision(MetavoxelStreamState& state) { +bool MetavoxelNode::readSubdivision(MetavoxelStreamState& state) { bool leaf; bool subdivideReference = state.shouldSubdivideReference(); if (!subdivideReference) { @@ -897,7 +905,7 @@ void MetavoxelNode::readSubdivision(MetavoxelStreamState& state) { leaf = isLeaf(); } if (leaf) { - clearChildren(state.attribute); + return clearChildren(state.attribute); } else { MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute, @@ -909,13 +917,22 @@ void MetavoxelNode::readSubdivision(MetavoxelStreamState& state) { _children[i] = new MetavoxelNode(state.attribute); _children[i]->read(nextState); } + return true; + } else { + bool changed = false; for (int i = 0; i < CHILD_COUNT; i++) { nextState.setMinimum(state.minimum, i); if (nextState.becameSubdivided()) { - _children[i]->readSubdivision(nextState); + if (_children[i]->readSubdivision(nextState)) { + MetavoxelNode* oldNode = _children[i]; + _children[i] = new MetavoxelNode(state.attribute, oldNode); + oldNode->decrementReferenceCount(state.attribute); + changed = true; + } } } + return changed; } } } @@ -1042,13 +1059,16 @@ void MetavoxelNode::destroy(const AttributePointer& attribute) { } } -void MetavoxelNode::clearChildren(const AttributePointer& attribute) { +bool MetavoxelNode::clearChildren(const AttributePointer& attribute) { + bool cleared = false; for (int i = 0; i < CHILD_COUNT; i++) { if (_children[i]) { _children[i]->decrementReferenceCount(attribute); _children[i] = NULL; + cleared = true; } } + return cleared; } bool MetavoxelNode::deepEquals(const AttributePointer& attribute, const MetavoxelNode& other, diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index f558bf8e80..ac8f0cc023 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -118,7 +118,8 @@ public: void writeDelta(const MetavoxelData& reference, const MetavoxelLOD& referenceLOD, Bitstream& out, const MetavoxelLOD& lod) const; - MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); } + void setRoot(const AttributePointer& attribute, MetavoxelNode* root); + MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); } MetavoxelNode* createRoot(const AttributePointer& attribute); /// Performs a deep comparison between this data and the specified other (as opposed to the == operator, which does a @@ -200,7 +201,7 @@ public: void readDelta(const MetavoxelNode& reference, MetavoxelStreamState& state); void writeDelta(const MetavoxelNode& reference, MetavoxelStreamState& state) const; - void readSubdivision(MetavoxelStreamState& state); + bool readSubdivision(MetavoxelStreamState& state); void writeSubdivision(MetavoxelStreamState& state) const; void writeSpanners(MetavoxelStreamState& state) const; @@ -216,7 +217,7 @@ public: void destroy(const AttributePointer& attribute); - void clearChildren(const AttributePointer& attribute); + bool clearChildren(const AttributePointer& attribute); /// Performs a deep comparison between this and the specified other node. bool deepEquals(const AttributePointer& attribute, const MetavoxelNode& other,