From 96302ca271bdf0c66d29e29756b2db4d9f99e1b4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 5 Aug 2014 14:10:39 -0700 Subject: [PATCH] Provide for custom expansion according to attribute, tweak spanner attribute. --- .../metavoxels/src/AttributeRegistry.cpp | 47 +++++++++++++++++++ libraries/metavoxels/src/AttributeRegistry.h | 6 +++ libraries/metavoxels/src/MetavoxelData.cpp | 30 +++--------- libraries/metavoxels/src/MetavoxelData.h | 2 + 4 files changed, 61 insertions(+), 24 deletions(-) diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index 40b6195ada..9f656ef5d3 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -242,6 +242,30 @@ bool Attribute::metavoxelRootsEqual(const MetavoxelNode& firstRoot, const Metavo return firstRoot.deepEquals(this, secondRoot, minimum, size, lod); } +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; +} + FloatAttribute::FloatAttribute(const QString& name, float defaultValue) : SimpleInlineAttribute(name, defaultValue) { } @@ -809,6 +833,29 @@ bool SharedObjectSetAttribute::deepEqual(void* first, void* second) const { return setsEqual(decodeInline(first), decodeInline(second)); } +MetavoxelNode* SharedObjectSetAttribute::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(root.getAttributeValue(attribute)); + newParent->setChild(i, newChild); + if (root.isLeaf()) { + continue; + } + MetavoxelNode* grandchild = root.getChild(i); + grandchild->incrementReferenceCount(); + int index = MetavoxelNode::getOppositeChildIndex(i); + 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; +} + bool SharedObjectSetAttribute::merge(void*& parent, void* children[], bool postRead) const { for (int i = 0; i < MERGE_COUNT; i++) { if (!decodeInline(children[i]).isEmpty()) { diff --git a/libraries/metavoxels/src/AttributeRegistry.h b/libraries/metavoxels/src/AttributeRegistry.h index 767ebf6527..5d973341ad 100644 --- a/libraries/metavoxels/src/AttributeRegistry.h +++ b/libraries/metavoxels/src/AttributeRegistry.h @@ -238,6 +238,10 @@ public: virtual bool metavoxelRootsEqual(const MetavoxelNode& firstRoot, const MetavoxelNode& secondRoot, const glm::vec3& minimum, float size, const MetavoxelLOD& lod); + /// Expands the specified root, doubling its size in each dimension. + /// \return a new node representing the result + virtual MetavoxelNode* expandMetavoxelRoot(const MetavoxelNode& root); + /// Merges the value of a parent and its children. /// \param postRead whether or not the merge is happening after a read /// \return whether or not the children and parent values are all equal @@ -511,6 +515,8 @@ public: virtual bool deepEqual(void* first, void* second) const; + virtual MetavoxelNode* expandMetavoxelRoot(const MetavoxelNode& root); + virtual bool merge(void*& parent, void* children[], bool postRead = false) const; virtual AttributeValue inherit(const AttributeValue& parentValue) const; diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index a0b1f1efb0..3607441461 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -512,33 +512,11 @@ void MetavoxelData::set(const glm::vec3& minimum, const MetavoxelData& data, boo } } -static int getOppositeIndex(int index) { - return index ^ MAXIMUM_FLAG_MASK; -} - void MetavoxelData::expand() { for (QHash::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()); + MetavoxelNode* newNode = it.key()->expandMetavoxelRoot(*it.value()); it.value()->decrementReferenceCount(it.key()); - it.value() = newParent; + it.value() = newNode; } _size *= 2.0f; } @@ -823,6 +801,10 @@ void MetavoxelStreamState::setMinimum(const glm::vec3& lastMinimum, int index) { minimum = getNextMinimum(lastMinimum, size, index); } +int MetavoxelNode::getOppositeChildIndex(int index) { + return index ^ MAXIMUM_FLAG_MASK; +} + MetavoxelNode::MetavoxelNode(const AttributeValue& attributeValue, const MetavoxelNode* copyChildren) : _referenceCount(1) { diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index 24eb09763c..9e5b2f04d1 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -197,6 +197,8 @@ public: static const int CHILD_COUNT = 8; + static int getOppositeChildIndex(int index); + MetavoxelNode(const AttributeValue& attributeValue, const MetavoxelNode* copyChildren = NULL); MetavoxelNode(const AttributePointer& attribute, const MetavoxelNode* copy);