More work on spanning objects.

This commit is contained in:
Andrzej Kapolka 2014-02-14 18:01:48 -08:00
parent 5b1229e1d0
commit 3e40927d3a
7 changed files with 156 additions and 21 deletions

View file

@ -94,14 +94,11 @@ MetavoxelEditor::MetavoxelEditor() :
valueLayout->addWidget(_valueArea = new QScrollArea());
_valueArea->setWidgetResizable(true);
BoxSetTool* boxSetTool = new BoxSetTool(this);
topLayout->addWidget(boxSetTool);
_toolBox->addItem("Set Value (Box)", QVariant::fromValue(boxSetTool));
GlobalSetTool* globalSetTool = new GlobalSetTool(this);
topLayout->addWidget(globalSetTool);
_toolBox->addItem("Set Value (Global)", QVariant::fromValue(globalSetTool));
addTool(new BoxSetTool(this));
addTool(new GlobalSetTool(this));
addTool(new InsertSpannerTool(this));
addTool(new RemoveSpannerTool(this));
updateAttributes();
connect(Application::getInstance(), SIGNAL(renderingInWorldInterface()), SLOT(render()));
@ -153,23 +150,35 @@ QVariant MetavoxelEditor::getValue() const {
bool MetavoxelEditor::eventFilter(QObject* watched, QEvent* event) {
// pass along to the active tool
return getActiveTool()->eventFilter(watched, event);
MetavoxelTool* tool = getActiveTool();
return tool && tool->eventFilter(watched, event);
}
void MetavoxelEditor::selectedAttributeChanged() {
_toolBox->clear();
QString selected = getSelectedAttribute();
if (selected.isNull()) {
_deleteAttribute->setEnabled(false);
_toolBox->setEnabled(false);
_value->setVisible(false);
return;
}
_deleteAttribute->setEnabled(true);
_toolBox->setEnabled(true);
AttributePointer attribute = AttributeRegistry::getInstance()->getAttribute(selected);
foreach (MetavoxelTool* tool, _tools) {
if (tool->appliesTo(attribute)) {
_toolBox->addItem(tool->objectName(), QVariant::fromValue(tool));
}
}
_value->setVisible(true);
if (_valueArea->widget()) {
delete _valueArea->widget();
}
QWidget* editor = AttributeRegistry::getInstance()->getAttribute(selected)->createEditor();
QWidget* editor = attribute->createEditor();
if (editor) {
_valueArea->setWidget(editor);
}
@ -231,9 +240,11 @@ void MetavoxelEditor::alignGridPosition() {
}
void MetavoxelEditor::updateTool() {
for (int i = 0; i < _toolBox->count(); i++) {
_toolBox->itemData(i).value<QWidget*>()->setVisible(i == _toolBox->currentIndex());
MetavoxelTool* active = getActiveTool();
foreach (MetavoxelTool* tool, _tools) {
tool->setVisible(tool == active);
}
_value->setVisible(active && active->getUsesValue());
}
const float GRID_BRIGHTNESS = 0.5f;
@ -248,7 +259,10 @@ void MetavoxelEditor::render() {
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
getActiveTool()->render();
MetavoxelTool* tool = getActiveTool();
if (tool) {
tool->render();
}
glLineWidth(1.0f);
@ -276,6 +290,11 @@ void MetavoxelEditor::render() {
glDepthMask(GL_TRUE);
}
void MetavoxelEditor::addTool(MetavoxelTool* tool) {
_tools.append(tool);
layout()->addWidget(tool);
}
void MetavoxelEditor::updateAttributes(const QString& select) {
// remember the selection in order to preserve it
QString selected = select.isNull() ? getSelectedAttribute() : select;
@ -296,26 +315,34 @@ void MetavoxelEditor::updateAttributes(const QString& select) {
}
MetavoxelTool* MetavoxelEditor::getActiveTool() const {
return static_cast<MetavoxelTool*>(_toolBox->itemData(_toolBox->currentIndex()).value<QObject*>());
int index = _toolBox->currentIndex();
return (index == -1) ? NULL : static_cast<MetavoxelTool*>(_toolBox->itemData(index).value<QObject*>());
}
ProgramObject MetavoxelEditor::_gridProgram;
MetavoxelTool::MetavoxelTool(MetavoxelEditor* editor) :
_editor(editor) {
MetavoxelTool::MetavoxelTool(MetavoxelEditor* editor, const QString& name, bool usesValue) :
_editor(editor),
_usesValue(usesValue) {
QVBoxLayout* layout = new QVBoxLayout();
setLayout(layout);
setObjectName(name);
setVisible(false);
}
bool MetavoxelTool::appliesTo(const AttributePointer& attribute) const {
// shared object sets are a special case
return !attribute->inherits("SharedObjectSetAttribute");
}
void MetavoxelTool::render() {
// nothing by default
}
BoxSetTool::BoxSetTool(MetavoxelEditor* editor) :
MetavoxelTool(editor) {
MetavoxelTool(editor, "Set Value (Box)") {
resetState();
}
@ -449,7 +476,7 @@ void BoxSetTool::applyValue(const glm::vec3& minimum, const glm::vec3& maximum)
}
GlobalSetTool::GlobalSetTool(MetavoxelEditor* editor) :
MetavoxelTool(editor) {
MetavoxelTool(editor, "Set Value (Global)") {
QPushButton* button = new QPushButton("Apply");
layout()->addWidget(button);
@ -465,3 +492,33 @@ void GlobalSetTool::apply() {
MetavoxelEditMessage message = { QVariant::fromValue(GlobalSetEdit(value)) };
Application::getInstance()->getMetavoxels()->applyEdit(message);
}
InsertSpannerTool::InsertSpannerTool(MetavoxelEditor* editor) :
MetavoxelTool(editor, "Insert Spanner") {
QPushButton* button = new QPushButton("Insert");
layout()->addWidget(button);
connect(button, SIGNAL(clicked()), SLOT(insert()));
}
bool InsertSpannerTool::appliesTo(const AttributePointer& attribute) const {
return attribute->inherits("SharedObjectSetAttribute");
}
void InsertSpannerTool::insert() {
AttributePointer attribute = AttributeRegistry::getInstance()->getAttribute(_editor->getSelectedAttribute());
if (!attribute) {
return;
}
SharedObjectPointer spanner = _editor->getValue().value<SharedObjectPointer>();
MetavoxelEditMessage message = { QVariant::fromValue(InsertSpannerEdit(attribute, spanner)) };
Application::getInstance()->getMetavoxels()->applyEdit(message);
}
RemoveSpannerTool::RemoveSpannerTool(MetavoxelEditor* editor) :
MetavoxelTool(editor, "Remove Spanner", false) {
}
bool RemoveSpannerTool::appliesTo(const AttributePointer& attribute) const {
return attribute->inherits("SharedObjectSetAttribute");
}

View file

@ -10,6 +10,7 @@
#define __interface__MetavoxelEditor__
#include <QDialog>
#include <QList>
#include "renderer/ProgramObject.h"
@ -53,6 +54,7 @@ private slots:
private:
void addTool(MetavoxelTool* tool);
void updateAttributes(const QString& select = QString());
MetavoxelTool* getActiveTool() const;
@ -63,6 +65,7 @@ private:
QDoubleSpinBox* _gridSpacing;
QDoubleSpinBox* _gridPosition;
QList<MetavoxelTool*> _tools;
QComboBox* _toolBox;
QGroupBox* _value;
@ -77,7 +80,11 @@ class MetavoxelTool : public QWidget {
public:
MetavoxelTool(MetavoxelEditor* editor);
MetavoxelTool(MetavoxelEditor* editor, const QString& name, bool usesValue = true);
bool getUsesValue() const { return _usesValue; }
virtual bool appliesTo(const AttributePointer& attribute) const;
/// Renders the tool's interface, if any.
virtual void render();
@ -85,6 +92,7 @@ public:
protected:
MetavoxelEditor* _editor;
bool _usesValue;
};
/// Allows setting the value of a region by dragging out a box.
@ -127,4 +135,30 @@ private slots:
void apply();
};
/// Allows inserting a spanner into the scene.
class InsertSpannerTool : public MetavoxelTool {
Q_OBJECT
public:
InsertSpannerTool(MetavoxelEditor* editor);
virtual bool appliesTo(const AttributePointer& attribute) const;
private slots:
void insert();
};
/// Allows removing a spanner from the scene.
class RemoveSpannerTool : public MetavoxelTool {
Q_OBJECT
public:
RemoveSpannerTool(MetavoxelEditor* editor);
virtual bool appliesTo(const AttributePointer& attribute) const;
};
#endif /* defined(__interface__MetavoxelEditor__) */

View file

@ -243,3 +243,7 @@ bool SharedObjectSetAttribute::merge(void*& parent, void* children[]) const {
}
return true;
}
QWidget* SharedObjectSetAttribute::createEditor(QWidget* parent) const {
return new SharedObjectEditor(_metaObject, parent);
}

View file

@ -299,6 +299,8 @@ public:
virtual bool merge(void*& parent, void* children[]) const;
virtual QWidget* createEditor(QWidget* parent = NULL) const;
private:
const QMetaObject* _metaObject;

View file

@ -88,6 +88,39 @@ void MetavoxelData::guide(MetavoxelVisitor& visitor) {
}
}
class InsertVisitor : public MetavoxelVisitor {
public:
InsertVisitor(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object);
virtual bool visit(MetavoxelInfo& info);
private:
const AttributePointer& _attribute;
const Box& _bounds;
const SharedObjectPointer& _object;
};
InsertVisitor::InsertVisitor(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object) :
MetavoxelVisitor(QVector<AttributePointer>() << attribute, QVector<AttributePointer>() << attribute),
_attribute(attribute),
_bounds(bounds),
_object(object) {
}
bool InsertVisitor::visit(MetavoxelInfo& info) {
return false;
}
void MetavoxelData::insert(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object) {
InsertVisitor visitor(attribute, bounds, object);
guide(visitor);
}
void MetavoxelData::remove(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object) {
}
const int X_MAXIMUM_FLAG = 1;
const int Y_MAXIMUM_FLAG = 2;
const int Z_MAXIMUM_FLAG = 4;

View file

@ -45,7 +45,11 @@ public:
/// Applies the specified visitor to the contained voxels.
void guide(MetavoxelVisitor& visitor);
void insert(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object);
void remove(const AttributePointer& attribute, const Box& bounds, const SharedObjectPointer& object);
/// Expands the tree, increasing its capacity in all dimensions.
void expand();
@ -249,7 +253,7 @@ class Spanner : public SharedObject {
public:
Spanner();
Q_INVOKABLE Spanner();
void setBounds(const Box& bounds);
const Box& getBounds() const { return _bounds; }

View file

@ -105,7 +105,8 @@ InsertSpannerEdit::InsertSpannerEdit(const AttributePointer& attribute, const Sh
spanner(spanner) {
}
void InsertSpannerEdit::apply(MetavoxelData& data) const {
void InsertSpannerEdit::apply(MetavoxelData& data) const {
data.insert(attribute, static_cast<Spanner*>(spanner.data())->getBounds(), spanner);
}
RemoveSpannerEdit::RemoveSpannerEdit(const AttributePointer& attribute, int id) :