Working on support for "spanners" (objects that span multiple octree cells).

This commit is contained in:
Andrzej Kapolka 2014-02-14 15:35:42 -08:00
parent 8b3356f819
commit 8920873d70
8 changed files with 164 additions and 1 deletions

View file

@ -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<SharedObjectSet>(name),
_metaObject(metaObject) {
}
bool SharedObjectSetAttribute::merge(void*& parent, void* children[]) const {
for (int i = 0; i < MERGE_COUNT; i++) {
if (!decodeInline<SharedObjectSet>(children[i]).isEmpty()) {
return false;
}
}
return true;
}

View file

@ -57,9 +57,12 @@ public:
/// Returns a reference to the attribute hash.
const QHash<QString, AttributePointer>& 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<QString, AttributePointer> _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<SharedObjectSet> {
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__) */

View file

@ -266,6 +266,9 @@ public:
template<class T> Bitstream& operator<<(const QList<T>& list);
template<class T> Bitstream& operator>>(QList<T>& list);
template<class T> Bitstream& operator<<(const QSet<T>& set);
template<class T> Bitstream& operator>>(QSet<T>& set);
template<class K, class V> Bitstream& operator<<(const QHash<K, V>& hash);
template<class K, class V> Bitstream& operator>>(QHash<K, V>& hash);
@ -348,6 +351,27 @@ template<class T> inline Bitstream& Bitstream::operator>>(QList<T>& list) {
return *this;
}
template<class T> inline Bitstream& Bitstream::operator<<(const QSet<T>& set) {
*this << set.size();
foreach (const T& entry, set) {
*this << entry;
}
return *this;
}
template<class T> inline Bitstream& Bitstream::operator>>(QSet<T>& 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<class K, class V> inline Bitstream& Bitstream::operator<<(const QHash<K, V>& hash) {
*this << hash.size();
for (typename QHash<K, V>::const_iterator it = hash.constBegin(); it != hash.constEnd(); it++) {

View file

@ -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;
}

View file

@ -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__) */

View file

@ -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 {
}

View file

@ -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__) */

View file

@ -11,6 +11,7 @@
#include <QMetaType>
#include <QObject>
#include <QSet>
#include <QWidget>
class QComboBox;
@ -144,6 +145,10 @@ typedef SharedObjectPointerTemplate<SharedObject> SharedObjectPointer;
Q_DECLARE_METATYPE(SharedObjectPointer)
typedef QSet<SharedObjectPointer> SharedObjectSet;
Q_DECLARE_METATYPE(SharedObjectSet)
/// Allows editing shared object instances.
class SharedObjectEditor : public QWidget {
Q_OBJECT