void MetavoxelData::write(Bitstream& out) const { out << _size; out << _roots.size(); for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) { out.getAttributeStreamer() << it.key(); it.value()->write(it.key(), out); } }
void MetavoxelData::readDelta(const MetavoxelData& reference, Bitstream& in) { // shallow copy the reference *this = reference; bool changed; in >> changed; if (!changed) { return; } bool sizeChanged; in >> sizeChanged; if (sizeChanged) { float size; in >> size; while (_size < size) { expand(); } } int changedCount; in >> changedCount; for (int i = 0; i < changedCount; i++) { AttributePointer attribute; in.getAttributeStreamer() >> attribute; MetavoxelNode*& root = _roots[attribute]; if (root) { MetavoxelNode* oldRoot = root; root = new MetavoxelNode(attribute); root->readDelta(attribute, *oldRoot, in); oldRoot->decrementReferenceCount(attribute); } else { root = new MetavoxelNode(attribute); root->read(attribute, in); } } int removedCount; in >> removedCount; for (int i = 0; i < removedCount; i++) { AttributePointer attribute; in.getAttributeStreamer() >> attribute; _roots.take(attribute)->decrementReferenceCount(attribute); } }
void MetavoxelData::read(Bitstream& in) { // clear out any existing roots decrementRootReferenceCounts(); _roots.clear(); in >> _size; // read in the new roots int rootCount; in >> rootCount; for (int i = 0; i < rootCount; i++) { AttributePointer attribute; in.getAttributeStreamer() >> attribute; MetavoxelNode*& root = _roots[attribute]; root = new MetavoxelNode(attribute); root->read(attribute, in); } }
void MetavoxelData::writeDelta(const MetavoxelData& reference, Bitstream& out) const { // first things first: there might be no change whatsoever if (_size == reference._size && _roots == reference._roots) { out << false; return; } out << true; // compare the size; if changed (rare), we must compare to the expanded reference const MetavoxelData* expandedReference = &reference; if (_size == reference._size) { out << false; } else { out << true; out << _size; MetavoxelData* expanded = new MetavoxelData(reference); while (expanded->_size < _size) { expanded->expand(); } expandedReference = expanded; } // count the number of roots added/changed, then write int changedCount = 0; for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) { MetavoxelNode* referenceRoot = expandedReference->_roots.value(it.key()); if (it.value() != referenceRoot) { changedCount++; } } out << changedCount; for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) { MetavoxelNode* referenceRoot = expandedReference->_roots.value(it.key()); if (it.value() != referenceRoot) { out.getAttributeStreamer() << it.key(); if (referenceRoot) { it.value()->writeDelta(it.key(), *referenceRoot, out); } else { it.value()->write(it.key(), out); } } } // same with nodes removed int removedCount = 0; for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = expandedReference->_roots.constBegin(); it != expandedReference->_roots.constEnd(); it++) { if (!_roots.contains(it.key())) { removedCount++; } } out << removedCount; for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = expandedReference->_roots.constBegin(); it != expandedReference->_roots.constEnd(); it++) { if (!_roots.contains(it.key())) { out.getAttributeStreamer() << it.key(); } } // delete the expanded reference if we had to expand if (expandedReference != &reference) { delete expandedReference; } }