More work on spanners.

This commit is contained in:
Andrzej Kapolka 2014-02-19 15:25:21 -08:00
parent a8d0aa6d17
commit 25ae81e2de
8 changed files with 102 additions and 26 deletions

View file

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

View file

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

View file

@ -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<AttributePointer>() << attribute, QVector<AttributePointer>() << 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;

View file

@ -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<AttributeValue> inputValues;
QVector<AttributeValue> outputValues;
bool isLeaf;
Box getBounds() const { return Box(minimum, minimum + glm::vec3(size, size, size)); }
};
/// Interface for visitors to metavoxels.

View file

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

View file

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

View file

@ -21,9 +21,6 @@
#include <QVBoxLayout>
#include <QtDebug>
#include <HifiSockAddr.h>
#include <PacketHeaders.h>
#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());

View file

@ -13,10 +13,8 @@
#include <QComboBox>
#include <QSharedPointer>
#include <QUrl>
#include <QUuid>
#include <QWidget>
#include <NodeList.h>
#include <RegisteredMetaTypes.h>
#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)