void MetavoxelData::expand() { for (QHash<AttributePointer, MetavoxelNode*>::iterator it = _roots.begin(); it != _roots.end(); it++) { MetavoxelNode* newParent = new MetavoxelNode(it.key()); for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) { MetavoxelNode* newChild = new MetavoxelNode(it.key()); newParent->setChild(i, newChild); int index = getOppositeIndex(i); if (it.value()->isLeaf()) { newChild->setChild(index, new MetavoxelNode(it.value()->getAttributeValue(it.key()))); } else { MetavoxelNode* grandchild = it.value()->getChild(i); grandchild->incrementReferenceCount(); newChild->setChild(index, grandchild); } for (int j = 1; j < MetavoxelNode::CHILD_COUNT; j++) { MetavoxelNode* newGrandchild = new MetavoxelNode(it.key()); newChild->setChild((index + j) % MetavoxelNode::CHILD_COUNT, newGrandchild); } newChild->mergeChildren(it.key()); } newParent->mergeChildren(it.key()); it.value()->decrementReferenceCount(it.key()); it.value() = newParent; } _size *= 2.0f; }
void Attribute::readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state) { // copy if changed MetavoxelNode* oldRoot = data.getRoot(state.base.attribute); MetavoxelNode* newRoot = oldRoot->readSubdivision(state); if (newRoot != oldRoot) { data.setRoot(state.base.attribute, newRoot); } }
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 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); } }
MetavoxelNode* Attribute::expandMetavoxelRoot(const MetavoxelNode& root) { AttributePointer attribute(this); MetavoxelNode* newParent = new MetavoxelNode(attribute); for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) { MetavoxelNode* newChild = new MetavoxelNode(attribute); newParent->setChild(i, newChild); int index = MetavoxelNode::getOppositeChildIndex(i); if (root.isLeaf()) { newChild->setChild(index, new MetavoxelNode(root.getAttributeValue(attribute))); } else { MetavoxelNode* grandchild = root.getChild(i); grandchild->incrementReferenceCount(); newChild->setChild(index, grandchild); } for (int j = 1; j < MetavoxelNode::CHILD_COUNT; j++) { MetavoxelNode* newGrandchild = new MetavoxelNode(attribute); newChild->setChild((index + j) % MetavoxelNode::CHILD_COUNT, newGrandchild); } newChild->mergeChildren(attribute); } newParent->mergeChildren(attribute); return newParent; }
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()); } } }
bool Attribute::metavoxelRootsEqual(const MetavoxelNode& firstRoot, const MetavoxelNode& secondRoot, const glm::vec3& minimum, float size, const MetavoxelLOD& lod) { return firstRoot.deepEquals(this, secondRoot, minimum, size, lod); }
void Attribute::writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) { root.writeSubdivision(state); }
void Attribute::writeMetavoxelDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state) { root.writeDelta(reference, state); }
void Attribute::writeMetavoxelRoot(const MetavoxelNode& root, MetavoxelStreamState& state) { root.write(state); }
void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) { visitation.info.isLeaf = visitation.allInputNodesLeaves(); bool keepGoing = visitation.visitor.visit(visitation.info); for (int i = 0; i < visitation.outputNodes.size(); i++) { AttributeValue& value = visitation.info.outputValues[i]; if (!value.getAttribute()) { continue; } MetavoxelNode*& node = visitation.outputNodes[i]; if (node && node->isLeaf() && value.getAttribute()->equal(value.getValue(), node->getAttributeValue())) { // "set" to same value; disregard value = AttributeValue(); } else { node = new MetavoxelNode(value); } } if (!keepGoing) { return; } MetavoxelVisitation nextVisitation = { &visitation, visitation.visitor, QVector<MetavoxelNode*>(visitation.inputNodes.size()), QVector<MetavoxelNode*>(visitation.outputNodes.size()), { glm::vec3(), visitation.info.size * 0.5f, QVector<AttributeValue>(visitation.inputNodes.size()), QVector<AttributeValue>(visitation.outputNodes.size()) } }; for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) { for (int j = 0; j < visitation.inputNodes.size(); j++) { MetavoxelNode* node = visitation.inputNodes.at(j); MetavoxelNode* child = node ? node->getChild(i) : NULL; nextVisitation.info.inputValues[j] = ((nextVisitation.inputNodes[j] = child)) ? child->getAttributeValue(visitation.info.inputValues[j].getAttribute()) : visitation.info.inputValues[j]; } for (int j = 0; j < visitation.outputNodes.size(); j++) { MetavoxelNode* node = visitation.outputNodes.at(j); MetavoxelNode* child = node ? node->getChild(i) : NULL; nextVisitation.outputNodes[j] = child; } nextVisitation.info.minimum = visitation.info.minimum + glm::vec3( (i & X_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f, (i & Y_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f, (i & Z_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f); static_cast<MetavoxelGuide*>(nextVisitation.info.inputValues.last().getInlineValue< PolymorphicDataPointer>().data())->guide(nextVisitation); for (int j = 0; j < nextVisitation.outputNodes.size(); j++) { AttributeValue& value = nextVisitation.info.outputValues[j]; if (!value.getAttribute()) { continue; } // replace the child AttributeValue& parentValue = visitation.info.outputValues[j]; if (!parentValue.getAttribute()) { // shallow-copy the parent node on first change parentValue = value; MetavoxelNode*& node = visitation.outputNodes[j]; if (node) { node = new MetavoxelNode(value.getAttribute(), node); } else { // create leaf with inherited value node = new MetavoxelNode(visitation.getInheritedOutputValue(j)); } } MetavoxelNode* node = visitation.outputNodes.at(j); MetavoxelNode* child = node->getChild(i); if (child) { child->decrementReferenceCount(value.getAttribute()); } else { // it's a leaf; we need to split it up AttributeValue nodeValue = node->getAttributeValue(value.getAttribute()); for (int k = 1; k < MetavoxelNode::CHILD_COUNT; k++) { node->setChild((i + k) % MetavoxelNode::CHILD_COUNT, new MetavoxelNode(nodeValue)); } } node->setChild(i, nextVisitation.outputNodes.at(j)); value = AttributeValue(); } } for (int i = 0; i < visitation.outputNodes.size(); i++) { AttributeValue& value = visitation.info.outputValues[i]; if (value.getAttribute()) { MetavoxelNode* node = visitation.outputNodes.at(i); node->mergeChildren(value.getAttribute()); value = node->getAttributeValue(value.getAttribute()); } } }