void MetavoxelNode::readDelta(const AttributePointer& attribute, const MetavoxelNode& reference, Bitstream& in) { clearChildren(attribute); bool leaf; in >> leaf; attribute->readDelta(in, _attributeValue, reference._attributeValue, leaf); if (!leaf) { if (reference.isLeaf()) { for (int i = 0; i < CHILD_COUNT; i++) { _children[i] = new MetavoxelNode(attribute); _children[i]->read(attribute, in); } } else { for (int i = 0; i < CHILD_COUNT; i++) { bool changed; in >> changed; if (changed) { _children[i] = new MetavoxelNode(attribute); _children[i]->readDelta(attribute, *reference._children[i], in); } else { _children[i] = reference._children[i]; _children[i]->incrementReferenceCount(); } } } } }
void MetavoxelNode::writeDelta(const AttributePointer& attribute, const MetavoxelNode& reference, Bitstream& out) const { bool leaf = isLeaf(); out << leaf; attribute->writeDelta(out, _attributeValue, reference._attributeValue, leaf); if (!leaf) { if (reference.isLeaf()) { for (int i = 0; i < CHILD_COUNT; i++) { _children[i]->write(attribute, out); } } else { for (int i = 0; i < CHILD_COUNT; i++) { if (_children[i] == reference._children[i]) { out << false; } else { out << true; _children[i]->writeDelta(attribute, *reference._children[i], out); } } } } }
void MetavoxelData::guide(MetavoxelVisitor& visitor) { // start with the root values/defaults (plus the guide attribute) const QVector<AttributePointer>& inputs = visitor.getInputs(); const QVector<AttributePointer>& outputs = visitor.getOutputs(); MetavoxelVisitation firstVisitation = { NULL, visitor, QVector<MetavoxelNode*>(inputs.size() + 1), QVector<MetavoxelNode*>(outputs.size()), { glm::vec3(_size, _size, _size) * -0.5f, _size, QVector<AttributeValue>(inputs.size() + 1), QVector<AttributeValue>(outputs.size()) } }; for (int i = 0; i < inputs.size(); i++) { MetavoxelNode* node = _roots.value(inputs.at(i)); firstVisitation.inputNodes[i] = node; firstVisitation.info.inputValues[i] = node ? node->getAttributeValue(inputs[i]) : inputs[i]; } AttributePointer guideAttribute = AttributeRegistry::getInstance()->getGuideAttribute(); MetavoxelNode* node = _roots.value(guideAttribute); firstVisitation.inputNodes.last() = node; firstVisitation.info.inputValues.last() = node ? node->getAttributeValue(guideAttribute) : guideAttribute; for (int i = 0; i < outputs.size(); i++) { MetavoxelNode* node = _roots.value(outputs.at(i)); firstVisitation.outputNodes[i] = node; } static_cast<MetavoxelGuide*>(firstVisitation.info.inputValues.last().getInlineValue< PolymorphicDataPointer>().data())->guide(firstVisitation); for (int i = 0; i < outputs.size(); i++) { AttributeValue& value = firstVisitation.info.outputValues[i]; if (!value.getAttribute()) { continue; } // replace the old node with the new MetavoxelNode*& node = _roots[value.getAttribute()]; if (node) { node->decrementReferenceCount(value.getAttribute()); } node = firstVisitation.outputNodes.at(i); if (node->isLeaf() && value.isDefault()) { // immediately remove the new node if redundant node->decrementReferenceCount(value.getAttribute()); _roots.remove(value.getAttribute()); } } }