From 25ae81e2deff52e8e18653b3abf94ba5dd37fca1 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 19 Feb 2014 15:25:21 -0800 Subject: [PATCH] More work on spanners. --- interface/src/ui/MetavoxelEditor.cpp | 30 +++++++++++++++++++ interface/src/ui/MetavoxelEditor.h | 17 +++++++++++ libraries/metavoxels/src/MetavoxelData.cpp | 17 +++++++++++ libraries/metavoxels/src/MetavoxelData.h | 4 +++ .../metavoxels/src/MetavoxelMessages.cpp | 8 +++++ libraries/metavoxels/src/MetavoxelMessages.h | 17 ++++++++++- libraries/metavoxels/src/MetavoxelUtil.cpp | 23 ++++---------- libraries/metavoxels/src/MetavoxelUtil.h | 12 +++----- 8 files changed, 102 insertions(+), 26 deletions(-) diff --git a/interface/src/ui/MetavoxelEditor.cpp b/interface/src/ui/MetavoxelEditor.cpp index 5c099e3e41..87510e9347 100644 --- a/interface/src/ui/MetavoxelEditor.cpp +++ b/interface/src/ui/MetavoxelEditor.cpp @@ -99,6 +99,7 @@ MetavoxelEditor::MetavoxelEditor() : addTool(new GlobalSetTool(this)); addTool(new InsertSpannerTool(this)); addTool(new RemoveSpannerTool(this)); + addTool(new ClearSpannersTool(this)); updateAttributes(); @@ -566,3 +567,32 @@ RemoveSpannerTool::RemoveSpannerTool(MetavoxelEditor* editor) : bool RemoveSpannerTool::appliesTo(const AttributePointer& attribute) const { return attribute->inherits("SharedObjectSetAttribute"); } + +bool RemoveSpannerTool::eventFilter(QObject* watched, QEvent* event) { + if (event->type() == QEvent::MouseButtonPress) { + + return true; + } + return false; +} + +ClearSpannersTool::ClearSpannersTool(MetavoxelEditor* editor) : + MetavoxelTool(editor, "Clear Spanners", false) { + + QPushButton* button = new QPushButton("Clear"); + layout()->addWidget(button); + connect(button, SIGNAL(clicked()), SLOT(clear())); +} + +bool ClearSpannersTool::appliesTo(const AttributePointer& attribute) const { + return attribute->inherits("SharedObjectSetAttribute"); +} + +void ClearSpannersTool::clear() { + AttributePointer attribute = AttributeRegistry::getInstance()->getAttribute(_editor->getSelectedAttribute()); + if (!attribute) { + return; + } + MetavoxelEditMessage message = { QVariant::fromValue(ClearSpannersEdit(attribute)) }; + Application::getInstance()->getMetavoxels()->applyEdit(message); +} diff --git a/interface/src/ui/MetavoxelEditor.h b/interface/src/ui/MetavoxelEditor.h index e213be8d2c..1bccfae9f5 100644 --- a/interface/src/ui/MetavoxelEditor.h +++ b/interface/src/ui/MetavoxelEditor.h @@ -168,6 +168,23 @@ public: RemoveSpannerTool(MetavoxelEditor* editor); virtual bool appliesTo(const AttributePointer& attribute) const; + + virtual bool eventFilter(QObject* watched, QEvent* event); +}; + +/// Allows removing all spanners from the scene. +class ClearSpannersTool : public MetavoxelTool { + Q_OBJECT + +public: + + ClearSpannersTool(MetavoxelEditor* editor); + + virtual bool appliesTo(const AttributePointer& attribute) const; + +private slots: + + void clear(); }; #endif /* defined(__interface__MetavoxelEditor__) */ diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index c8c3dbf577..dbe5b3a21d 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -100,6 +100,7 @@ private: const AttributePointer& _attribute; const Box& _bounds; + float _longestSide; const SharedObjectPointer& _object; }; @@ -107,14 +108,27 @@ InsertVisitor::InsertVisitor(const AttributePointer& attribute, const Box& bound MetavoxelVisitor(QVector() << attribute, QVector() << attribute), _attribute(attribute), _bounds(bounds), + _longestSide(bounds.getLongestSide()), _object(object) { } bool InsertVisitor::visit(MetavoxelInfo& info) { + Box bounds = info.getBounds(); + if (!bounds.intersects(_bounds)) { + return false; + } + if (info.size > _longestSide) { + return true; + } + info.outputValues[0] = AttributeValue(_attribute); return false; } void MetavoxelData::insert(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object) { + // expand to fit the entire bounds + while (!getBounds().contains(bounds)) { + expand(); + } InsertVisitor visitor(attribute, bounds, object); guide(visitor); } @@ -122,6 +136,9 @@ void MetavoxelData::insert(const AttributePointer& attribute, const Box& bounds, void MetavoxelData::remove(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object) { } +void MetavoxelData::clear(const AttributePointer& attribute) { +} + const int X_MAXIMUM_FLAG = 1; const int Y_MAXIMUM_FLAG = 2; const int Z_MAXIMUM_FLAG = 4; diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index b06825ca70..3b6637d2f9 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -51,6 +51,8 @@ public: void remove(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object); + void clear(const AttributePointer& attribute); + /// Expands the tree, increasing its capacity in all dimensions. void expand(); @@ -128,6 +130,8 @@ public: QVector inputValues; QVector outputValues; bool isLeaf; + + Box getBounds() const { return Box(minimum, minimum + glm::vec3(size, size, size)); } }; /// Interface for visitors to metavoxels. diff --git a/libraries/metavoxels/src/MetavoxelMessages.cpp b/libraries/metavoxels/src/MetavoxelMessages.cpp index 56336ffa16..3b41a2e891 100644 --- a/libraries/metavoxels/src/MetavoxelMessages.cpp +++ b/libraries/metavoxels/src/MetavoxelMessages.cpp @@ -116,3 +116,11 @@ RemoveSpannerEdit::RemoveSpannerEdit(const AttributePointer& attribute, int id) void RemoveSpannerEdit::apply(MetavoxelData& data) const { } + +ClearSpannersEdit::ClearSpannersEdit(const AttributePointer& attribute) : + attribute(attribute) { +} + +void ClearSpannersEdit::apply(MetavoxelData& data) const { + data.clear(attribute); +} diff --git a/libraries/metavoxels/src/MetavoxelMessages.h b/libraries/metavoxels/src/MetavoxelMessages.h index 65bee27d7d..d6f07c2966 100644 --- a/libraries/metavoxels/src/MetavoxelMessages.h +++ b/libraries/metavoxels/src/MetavoxelMessages.h @@ -133,7 +133,7 @@ public: DECLARE_STREAMABLE_METATYPE(InsertSpannerEdit) -/// An edit that removes a a spanner from the tree. +/// An edit that removes a spanner from the tree. class RemoveSpannerEdit : public MetavoxelEdit { STREAMABLE @@ -149,4 +149,19 @@ public: DECLARE_STREAMABLE_METATYPE(RemoveSpannerEdit) +/// An edit that clears all spanners from the tree. +class ClearSpannersEdit : public MetavoxelEdit { + STREAMABLE + +public: + + STREAM AttributePointer attribute; + + ClearSpannersEdit(const AttributePointer& attribute = AttributePointer()); + + virtual void apply(MetavoxelData& data) const; +}; + +DECLARE_STREAMABLE_METATYPE(ClearSpannersEdit) + #endif /* defined(__interface__MetavoxelMessages__) */ diff --git a/libraries/metavoxels/src/MetavoxelUtil.cpp b/libraries/metavoxels/src/MetavoxelUtil.cpp index 16f561638b..2e93fb1804 100644 --- a/libraries/metavoxels/src/MetavoxelUtil.cpp +++ b/libraries/metavoxels/src/MetavoxelUtil.cpp @@ -21,9 +21,6 @@ #include #include -#include -#include - #include "MetavoxelUtil.h" #include "ScriptCache.h" @@ -143,20 +140,6 @@ static QItemEditorCreatorBase* qUrlEditorCreator = createQUrlEditorCreator(); static QItemEditorCreatorBase* vec3EditorCreator = createVec3EditorCreator(); static QItemEditorCreatorBase* parameterizedURLEditorCreator = createParameterizedURLEditorCreator(); -QUuid readSessionID(const QByteArray& data, const SharedNodePointer& sendingNode, int& headerPlusIDSize) { - // get the header size - int headerSize = numBytesForPacketHeader(data); - - // read the session id - const int UUID_BYTES = 16; - headerPlusIDSize = headerSize + UUID_BYTES; - if (data.size() < headerPlusIDSize) { - qWarning() << "Metavoxel data too short [size=" << data.size() << ", sendingNode=" << sendingNode << "]\n"; - return QUuid(); - } - return QUuid::fromRfc4122(QByteArray::fromRawData(data.constData() + headerSize, UUID_BYTES)); -} - QByteArray signal(const char* signature) { static QByteArray prototype = SIGNAL(dummyMethod()); QByteArray signal = prototype; @@ -173,6 +156,12 @@ bool Box::contains(const Box& other) const { other.minimum.z >= minimum.z && other.maximum.z <= maximum.z; } +bool Box::intersects(const Box& other) const { + return other.maximum.x >= minimum.x && other.minimum.x <= maximum.x && + other.maximum.y >= minimum.y && other.minimum.y <= maximum.y && + other.maximum.z >= minimum.z && other.minimum.z <= maximum.z; +} + QMetaObjectEditor::QMetaObjectEditor(QWidget* parent) : QWidget(parent) { QVBoxLayout* layout = new QVBoxLayout(); layout->setContentsMargins(QMargins()); diff --git a/libraries/metavoxels/src/MetavoxelUtil.h b/libraries/metavoxels/src/MetavoxelUtil.h index 19fd41e826..4b3fb43523 100644 --- a/libraries/metavoxels/src/MetavoxelUtil.h +++ b/libraries/metavoxels/src/MetavoxelUtil.h @@ -13,10 +13,8 @@ #include #include #include -#include #include -#include #include #include "Bitstream.h" @@ -25,14 +23,8 @@ class QByteArray; class QDoubleSpinBox; class QPushButton; -class HifiSockAddr; class NetworkProgram; -/// Reads and returns the session ID from a datagram. -/// \param[out] headerPlusIDSize the size of the header (including the session ID) within the data -/// \return the session ID, or a null ID if invalid (in which case a warning will be logged) -QUuid readSessionID(const QByteArray& data, const SharedNodePointer& sendingNode, int& headerPlusIDSize); - /// Performs the runtime equivalent of Qt's SIGNAL macro, which is to attach a prefix to the signature. QByteArray signal(const char* signature); @@ -48,6 +40,10 @@ public: Box(const glm::vec3& minimum = glm::vec3(), const glm::vec3& maximum = glm::vec3()); bool contains(const Box& other) const; + + bool intersects(const Box& other) const; + + float getLongestSide() const { return qMax(qMax(maximum.x - minimum.x, maximum.y - minimum.y), maximum.z - minimum.z); } }; DECLARE_STREAMABLE_METATYPE(Box)