From 88eeb17f28c21effa86121fbcb2ddedc0617fb1a Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 10 Dec 2013 17:53:11 -0800 Subject: [PATCH] More progress on metavoxels with generic attributes. --- interface/src/renderer/MetavoxelSystem.cpp | 18 ++++++- libraries/metavoxels/src/AttributeRegistry.h | 14 +++-- libraries/metavoxels/src/MetavoxelData.cpp | 54 ++++++++++++++------ libraries/metavoxels/src/MetavoxelData.h | 7 ++- 4 files changed, 72 insertions(+), 21 deletions(-) diff --git a/interface/src/renderer/MetavoxelSystem.cpp b/interface/src/renderer/MetavoxelSystem.cpp index ef6692c2d2..fea4c374f3 100644 --- a/interface/src/renderer/MetavoxelSystem.cpp +++ b/interface/src/renderer/MetavoxelSystem.cpp @@ -11,6 +11,22 @@ #include "MetavoxelSystem.h" void MetavoxelSystem::init() { - qDebug() << "Howdy hello\n"; + MetavoxelPath p1; + p1 += 0; + p1 += 1; + p1 += 2; + + AttributePointer blerp = AttributeRegistry::getInstance()->getAttribute("blerp"); + + void* foo = encodeInline(5.0f); + _data.setAttributeValue(p1, AttributeValue(blerp, &foo)); + + //p1 += 0; + + MetavoxelPath p2; + + AttributeValue value = _data.getAttributeValue(p2, blerp); + + qDebug("fliggedy bloo %g\n", decodeInline(value.getValue())); } diff --git a/libraries/metavoxels/src/AttributeRegistry.h b/libraries/metavoxels/src/AttributeRegistry.h index 1ccff349c9..5ec3f2533b 100644 --- a/libraries/metavoxels/src/AttributeRegistry.h +++ b/libraries/metavoxels/src/AttributeRegistry.h @@ -95,11 +95,19 @@ private: QString _name; }; +template inline void* encodeInline(const T& value) { + return *(void**)const_cast(&value); +} + +template inline T decodeInline(void* value) { + return *(T*)&value; +} + /// A simple attribute class that stores its values inline. template class InlineAttribute : public Attribute { public: - InlineAttribute(const QString& name, T defaultValue = T()) : Attribute(name), _defaultValue(*(void**)&defaultValue) { } + InlineAttribute(const QString& name, T defaultValue = T()) : Attribute(name), _defaultValue(encodeInline(defaultValue)) { } virtual void* create(void* const* copy = NULL) const { return (copy == NULL) ? _defaultValue : *copy; } virtual void destroy(void* value) const { /* no-op */ } @@ -121,10 +129,10 @@ private: template inline void* InlineAttribute::createAveraged(void* values[]) const { T total = T(); for (int i = 0; i < 8; i++) { - total += *(T*)(values + i); + total += decodeInline(values[i]); } total /= 8; - return *(void**)&total; + return encodeInline(total); } #endif /* defined(__interface__AttributeRegistry__) */ diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 41b2fd3317..acedea05d1 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -25,7 +25,7 @@ void MetavoxelData::setAttributeValue(const MetavoxelPath& path, const Attribute if (node == NULL) { node = new MetavoxelNode(attributeValue.getAttribute()); } - if (node->setAttributeValue(path, 0, attributeValue)) { + if (node->setAttributeValue(path, 0, attributeValue) && attributeValue.isDefault()) { node->destroy(attributeValue.getAttribute()); delete node; _roots.remove(attributeValue.getAttribute()); @@ -41,7 +41,7 @@ AttributeValue MetavoxelData::getAttributeValue(const MetavoxelPath& path, const int index = path[i]; MetavoxelNode* child = node->getChild(i); if (child == NULL) { - return AttributeValue(attribute); + return node->getAttributeValue(attribute); } node = child; } @@ -58,39 +58,53 @@ MetavoxelNode::MetavoxelNode(const AttributeValue& attributeValue) { bool MetavoxelNode::setAttributeValue(const MetavoxelPath& path, int index, const AttributeValue& attributeValue) { if (index == path.getSize()) { setAttributeValue(attributeValue); - return attributeValue.isDefault(); + return true; } int element = path[index]; if (_children[element] == NULL) { - _children[element] = new MetavoxelNode(attributeValue.getAttribute()); - } - if (_children[element]->setAttributeValue(path, index + 1, attributeValue)) { - _children[element]->destroy(attributeValue.getAttribute()); - delete _children[element]; - _children[element] = NULL; - if (allChildrenNull()) { - return true; + AttributeValue ownAttributeValue = getAttributeValue(attributeValue.getAttribute()); + for (int i = 0; i < CHILD_COUNT; i++) { + _children[i] = new MetavoxelNode(ownAttributeValue); } } + _children[element]->setAttributeValue(path, index + 1, attributeValue); + void* childValues[CHILD_COUNT]; + bool allLeaves = true; for (int i = 0; i < CHILD_COUNT; i++) { - childValues[i] = (_children[i] == NULL) ? attributeValue.getAttribute()->getDefaultValue() : - _children[i]->_attributeValue; + childValues[i] = _children[i]->_attributeValue; + allLeaves &= _children[i]->isLeaf(); } attributeValue.getAttribute()->destroy(_attributeValue); _attributeValue = attributeValue.getAttribute()->createAveraged(childValues); + + if (allLeaves && allChildrenEqual(attributeValue.getAttribute())) { + clearChildren(attributeValue.getAttribute()); + return true; + } + return false; } void MetavoxelNode::setAttributeValue(const AttributeValue& attributeValue) { attributeValue.getAttribute()->destroy(_attributeValue); _attributeValue = attributeValue.copy(); + clearChildren(attributeValue.getAttribute()); } AttributeValue MetavoxelNode::getAttributeValue(const AttributePointer& attribute) const { return AttributeValue(attribute, &_attributeValue); } +bool MetavoxelNode::isLeaf() const { + for (int i = 0; i < CHILD_COUNT; i++) { + if (_children[i]) { + return false; + } + } + return true; +} + void MetavoxelNode::destroy(const AttributePointer& attribute) { attribute->destroy(_attributeValue); for (int i = 0; i < CHILD_COUNT; i++) { @@ -101,15 +115,25 @@ void MetavoxelNode::destroy(const AttributePointer& attribute) { } } -bool MetavoxelNode::allChildrenNull() const { +bool MetavoxelNode::allChildrenEqual(const AttributePointer& attribute) const { for (int i = 0; i < CHILD_COUNT; i++) { - if (_children[i] != NULL) { + if (!attribute->equal(_attributeValue, _children[i]->_attributeValue)) { return false; } } return true; } +void MetavoxelNode::clearChildren(const AttributePointer& attribute) { + for (int i = 0; i < CHILD_COUNT; i++) { + if (_children[i]) { + _children[i]->destroy(attribute); + delete _children[i]; + _children[i] = NULL; + } + } +} + int MetavoxelPath::operator[](int index) const { return _array.at(index * BITS_PER_ELEMENT) | (_array.at(index * BITS_PER_ELEMENT + 1) << 1) | (_array.at(index * BITS_PER_ELEMENT + 2) << 2); diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index becdc62348..aafc0f6e44 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -51,7 +51,7 @@ public: /// Descends the voxel tree in order to set the value of a node. /// \param path the path to follow /// \param index the position in the path - /// \return whether or not the node is entirely equal to the default attribute, and can thus be collapsed + /// \return whether or not the node is entirely equal to the value bool setAttributeValue(const MetavoxelPath& path, int index, const AttributeValue& attributeValue); void setAttributeValue(const AttributeValue& attributeValue); @@ -61,12 +61,15 @@ public: MetavoxelNode* getChild(int index) const { return _children[index]; } void setChild(int index, MetavoxelNode* child) { _children[index] = child; } + bool isLeaf() const; + void destroy(const AttributePointer& attribute); private: Q_DISABLE_COPY(MetavoxelNode) - bool allChildrenNull() const; + bool allChildrenEqual(const AttributePointer& attribute) const; + void clearChildren(const AttributePointer& attribute); void* _attributeValue; MetavoxelNode* _children[CHILD_COUNT];