From 8920873d705acbb236d4e70828a22e000694ded0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 14 Feb 2014 15:35:42 -0800 Subject: [PATCH] Working on support for "spanners" (objects that span multiple octree cells). --- .../metavoxels/src/AttributeRegistry.cpp | 16 +++++++++ libraries/metavoxels/src/AttributeRegistry.h | 25 +++++++++++++- libraries/metavoxels/src/Bitstream.h | 24 ++++++++++++++ libraries/metavoxels/src/MetavoxelData.cpp | 20 +++++++++++ libraries/metavoxels/src/MetavoxelData.h | 27 +++++++++++++++ .../metavoxels/src/MetavoxelMessages.cpp | 15 +++++++++ libraries/metavoxels/src/MetavoxelMessages.h | 33 +++++++++++++++++++ libraries/metavoxels/src/SharedObject.h | 5 +++ 8 files changed, 164 insertions(+), 1 deletion(-) diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index 8483174dac..3cde1ce961 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -13,6 +13,7 @@ REGISTER_META_OBJECT(QRgbAttribute) REGISTER_META_OBJECT(SharedObjectAttribute) +REGISTER_META_OBJECT(SharedObjectSetAttribute) AttributeRegistry* AttributeRegistry::getInstance() { static AttributeRegistry registry; @@ -22,6 +23,7 @@ AttributeRegistry* AttributeRegistry::getInstance() { AttributeRegistry::AttributeRegistry() : _guideAttribute(registerAttribute(new SharedObjectAttribute("guide", &MetavoxelGuide::staticMetaObject, SharedObjectPointer(new DefaultMetavoxelGuide())))), + _spannersAttribute(registerAttribute(new SharedObjectSetAttribute("spanners", &Spanner::staticMetaObject))), _colorAttribute(registerAttribute(new QRgbAttribute("color"))), _normalAttribute(registerAttribute(new QRgbAttribute("normal", qRgb(0, 127, 0)))) { } @@ -227,3 +229,17 @@ QWidget* SharedObjectAttribute::createEditor(QWidget* parent) const { editor->setObject(_defaultValue); return editor; } + +SharedObjectSetAttribute::SharedObjectSetAttribute(const QString& name, const QMetaObject* metaObject) : + InlineAttribute(name), + _metaObject(metaObject) { +} + +bool SharedObjectSetAttribute::merge(void*& parent, void* children[]) const { + for (int i = 0; i < MERGE_COUNT; i++) { + if (!decodeInline(children[i]).isEmpty()) { + return false; + } + } + return true; +} diff --git a/libraries/metavoxels/src/AttributeRegistry.h b/libraries/metavoxels/src/AttributeRegistry.h index 1235cefbb5..ebcfb0c8d9 100644 --- a/libraries/metavoxels/src/AttributeRegistry.h +++ b/libraries/metavoxels/src/AttributeRegistry.h @@ -57,9 +57,12 @@ public: /// Returns a reference to the attribute hash. const QHash& getAttributes() const { return _attributes; } - /// Returns a reference to the standard PolymorphicDataPointer "guide" attribute. + /// Returns a reference to the standard SharedObjectPointer "guide" attribute. const AttributePointer& getGuideAttribute() const { return _guideAttribute; } + /// Returns a reference to the standard SharedObjectSet "spanners" attribute. + const AttributePointer& getSpannersAttribute() const { return _spannersAttribute; } + /// Returns a reference to the standard QRgb "color" attribute. const AttributePointer& getColorAttribute() const { return _colorAttribute; } @@ -72,6 +75,7 @@ private: QHash _attributes; AttributePointer _guideAttribute; + AttributePointer _spannersAttribute; AttributePointer _colorAttribute; AttributePointer _normalAttribute; }; @@ -281,4 +285,23 @@ private: const QMetaObject* _metaObject; }; +/// An attribute that takes the form of a set of shared objects. +class SharedObjectSetAttribute : public InlineAttribute { + Q_OBJECT + Q_PROPERTY(const QMetaObject* metaObject MEMBER _metaObject) + +public: + + Q_INVOKABLE SharedObjectSetAttribute(const QString& name = QString(), + const QMetaObject* metaObject = &SharedObject::staticMetaObject); + + const QMetaObject* getMetaObject() const { return _metaObject; } + + virtual bool merge(void*& parent, void* children[]) const; + +private: + + const QMetaObject* _metaObject; +}; + #endif /* defined(__interface__AttributeRegistry__) */ diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index 87ee66c661..9a3ef95d96 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -266,6 +266,9 @@ public: template Bitstream& operator<<(const QList& list); template Bitstream& operator>>(QList& list); + template Bitstream& operator<<(const QSet& set); + template Bitstream& operator>>(QSet& set); + template Bitstream& operator<<(const QHash& hash); template Bitstream& operator>>(QHash& hash); @@ -348,6 +351,27 @@ template inline Bitstream& Bitstream::operator>>(QList& list) { return *this; } +template inline Bitstream& Bitstream::operator<<(const QSet& set) { + *this << set.size(); + foreach (const T& entry, set) { + *this << entry; + } + return *this; +} + +template inline Bitstream& Bitstream::operator>>(QSet& set) { + int size; + *this >> size; + set.clear(); + set.reserve(size); + for (int i = 0; i < size; i++) { + T entry; + *this >> entry; + set.insert(entry); + } + return *this; +} + template inline Bitstream& Bitstream::operator<<(const QHash& hash) { *this << hash.size(); for (typename QHash::const_iterator it = hash.constBegin(); it != hash.constEnd(); it++) { diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 6296b93693..5f400ef517 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -18,6 +18,7 @@ REGISTER_META_OBJECT(MetavoxelGuide) REGISTER_META_OBJECT(DefaultMetavoxelGuide) REGISTER_META_OBJECT(ScriptedMetavoxelGuide) REGISTER_META_OBJECT(ThrobbingMetavoxelGuide) +REGISTER_META_OBJECT(Spanner) MetavoxelData::MetavoxelData() : _size(1.0f) { } @@ -673,3 +674,22 @@ AttributeValue MetavoxelVisitation::getInheritedOutputValue(int index) const { return AttributeValue(visitor.getOutputs().at(index)); } +Spanner::Spanner() : _lastVisit(0) { +} + +void Spanner::setBounds(const Box& bounds) { + if (_bounds == bounds) { + return; + } + emit boundsWillChange(); + emit boundsChanged(_bounds = bounds); +} + +bool Spanner::testAndSetVisited(int visit) { + if (_lastVisit == visit) { + return false; + } + _lastVisit = visit; + return true; +} + diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index 51cdd6cf64..4b001e2e33 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -242,4 +242,31 @@ public: AttributeValue getInheritedOutputValue(int index) const; }; +/// An object that spans multiple octree cells. +class Spanner : public SharedObject { + Q_OBJECT + Q_PROPERTY(Box bounds MEMBER _bounds WRITE setBounds NOTIFY boundsChanged) + +public: + + Spanner(); + + void setBounds(const Box& bounds); + const Box& getBounds() const { return _bounds; } + + /// Checks whether we've visited this object on the current traversal. If we have, returns false. + /// If we haven't, sets the last visit identifier and returns true. + bool testAndSetVisited(int visit); + +signals: + + void boundsWillChange(); + void boundsChanged(const Box& bounds); + +private: + + Box _bounds; + int _lastVisit; ///< the identifier of the last visit +}; + #endif /* defined(__interface__MetavoxelData__) */ diff --git a/libraries/metavoxels/src/MetavoxelMessages.cpp b/libraries/metavoxels/src/MetavoxelMessages.cpp index 9f3ccedc0a..36f0fcc10a 100644 --- a/libraries/metavoxels/src/MetavoxelMessages.cpp +++ b/libraries/metavoxels/src/MetavoxelMessages.cpp @@ -100,3 +100,18 @@ void GlobalSetEdit::apply(MetavoxelData& data) const { data.guide(visitor); } +InsertSpannerEdit::InsertSpannerEdit(const AttributePointer& attribute, const SharedObjectPointer& spanner) : + attribute(attribute), + spanner(spanner) { +} + +void InsertSpannerEdit::apply(MetavoxelData& data) const { +} + +RemoveSpannerEdit::RemoveSpannerEdit(const AttributePointer& attribute, int id) : + attribute(attribute), + id(id) { +} + +void RemoveSpannerEdit::apply(MetavoxelData& data) const { +} diff --git a/libraries/metavoxels/src/MetavoxelMessages.h b/libraries/metavoxels/src/MetavoxelMessages.h index 165accbbb1..65bee27d7d 100644 --- a/libraries/metavoxels/src/MetavoxelMessages.h +++ b/libraries/metavoxels/src/MetavoxelMessages.h @@ -116,4 +116,37 @@ public: DECLARE_STREAMABLE_METATYPE(GlobalSetEdit) +/// An edit that inserts a spanner into the tree. +class InsertSpannerEdit : public MetavoxelEdit { + STREAMABLE + +public: + + STREAM AttributePointer attribute; + STREAM SharedObjectPointer spanner; + + InsertSpannerEdit(const AttributePointer& attribute = AttributePointer(), + const SharedObjectPointer& spanner = SharedObjectPointer()); + + virtual void apply(MetavoxelData& data) const; +}; + +DECLARE_STREAMABLE_METATYPE(InsertSpannerEdit) + +/// An edit that removes a a spanner from the tree. +class RemoveSpannerEdit : public MetavoxelEdit { + STREAMABLE + +public: + + STREAM AttributePointer attribute; + STREAM int id; + + RemoveSpannerEdit(const AttributePointer& attribute = AttributePointer(), int id = 0); + + virtual void apply(MetavoxelData& data) const; +}; + +DECLARE_STREAMABLE_METATYPE(RemoveSpannerEdit) + #endif /* defined(__interface__MetavoxelMessages__) */ diff --git a/libraries/metavoxels/src/SharedObject.h b/libraries/metavoxels/src/SharedObject.h index b62b88d2ee..5a33b64e3d 100644 --- a/libraries/metavoxels/src/SharedObject.h +++ b/libraries/metavoxels/src/SharedObject.h @@ -11,6 +11,7 @@ #include #include +#include #include class QComboBox; @@ -144,6 +145,10 @@ typedef SharedObjectPointerTemplate SharedObjectPointer; Q_DECLARE_METATYPE(SharedObjectPointer) +typedef QSet SharedObjectSet; + +Q_DECLARE_METATYPE(SharedObjectSet) + /// Allows editing shared object instances. class SharedObjectEditor : public QWidget { Q_OBJECT