Working on performing the actual edit.

This commit is contained in:
Andrzej Kapolka 2014-01-22 19:17:48 -08:00
parent d082cfd705
commit a3ffb1d8a3
8 changed files with 113 additions and 24 deletions

View file

@ -145,6 +145,7 @@ public:
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
VoxelSystem* getVoxels() { return &_voxels; }
ParticleTreeRenderer* getParticles() { return &_particles; }
MetavoxelSystem* getMetavoxels() { return &_metavoxels; }
VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; }
VoxelTree* getClipboard() { return &_clipboard; }
Environment* getEnvironment() { return &_environment; }

View file

@ -151,7 +151,7 @@ MetavoxelSystem::PointVisitor::PointVisitor(QVector<Point>& points) :
_points(points) {
}
bool MetavoxelSystem::PointVisitor::visit(const MetavoxelInfo& info) {
bool MetavoxelSystem::PointVisitor::visit(MetavoxelInfo& info) {
if (!info.isLeaf) {
return true;
}

View file

@ -34,6 +34,8 @@ public:
void init();
MetavoxelData& getData() { return _data; }
void processData(const QByteArray& data, const HifiSockAddr& sender);
void simulate(float deltaTime);
@ -60,7 +62,7 @@ private:
class PointVisitor : public MetavoxelVisitor {
public:
PointVisitor(QVector<Point>& points);
virtual bool visit(const MetavoxelInfo& info);
virtual bool visit(MetavoxelInfo& info);
private:
QVector<Point>& _points;

View file

@ -333,9 +333,61 @@ void MetavoxelEditor::resetState() {
_height = 0.0f;
}
class Applier : public MetavoxelVisitor {
public:
Applier(const glm::vec3& minimum, const glm::vec3& maximum, float granularity, const AttributeValue& value);
virtual bool visit(MetavoxelInfo& info);
protected:
glm::vec3 _minimum;
glm::vec3 _maximum;
float _granularity;
AttributeValue _value;
};
Applier::Applier(const glm::vec3& minimum, const glm::vec3& maximum, float granularity, const AttributeValue& value) :
MetavoxelVisitor(QVector<AttributePointer>(), QVector<AttributePointer>() << value.getAttribute()),
_minimum(minimum),
_maximum(maximum),
_granularity(granularity),
_value(value) {
}
bool Applier::visit(MetavoxelInfo& info) {
// find the intersection between volume and voxel
glm::vec3 minimum = glm::max(info.minimum, _minimum);
glm::vec3 maximum = glm::min(info.minimum + glm::vec3(info.size, info.size, info.size), _maximum);
glm::vec3 size = maximum - minimum;
if (size.x <= 0.0f || size.y <= 0.0f || size.z <= 0.0f) {
return false; // disjoint
}
float volume = (size.x * size.y * size.z) / (info.size * info.size * info.size);
if (volume >= 1.0f) {
info.outputValues[0] = _value;
return false; // entirely contained
}
if (info.size <= _granularity) {
if (volume > 0.5f) {
info.outputValues[0] = _value;
}
return false; // reached granularity limit; take best guess
}
return true; // subdivide
}
void MetavoxelEditor::applyValue(const glm::vec3& minimum, const glm::vec3& maximum) {
AttributePointer attribute = AttributeRegistry::getInstance()->getAttribute(getSelectedAttribute());
if (!attribute) {
return;
}
QWidget* editor = _value->layout()->itemAt(0)->widget();
QVariant value = editor->metaObject()->userProperty().read(editor);
OwnedAttributeValue value(attribute, attribute->createFromVariant(editor->metaObject()->userProperty().read(editor)));
Applier applier(minimum, maximum, _gridSpacing->value(), value);
Application::getInstance()->getMetavoxels()->getData().guide(applier);
}
ProgramObject MetavoxelEditor::_gridProgram;

View file

@ -72,12 +72,12 @@ bool AttributeValue::operator==(void* other) const {
return _attribute && _attribute->equal(_value, other);
}
OwnedAttributeValue::OwnedAttributeValue(const AttributePointer& attribute) :
AttributeValue(attribute, attribute ? attribute->create() : NULL) {
OwnedAttributeValue::OwnedAttributeValue(const AttributePointer& attribute, void* value) :
AttributeValue(attribute, value) {
}
OwnedAttributeValue::OwnedAttributeValue(const AttributePointer& attribute, void* value) :
AttributeValue(attribute, attribute ? attribute->create(value) : NULL) {
OwnedAttributeValue::OwnedAttributeValue(const AttributePointer& attribute) :
AttributeValue(attribute, attribute ? attribute->create() : NULL) {
}
OwnedAttributeValue::OwnedAttributeValue(const AttributeValue& other) :
@ -95,7 +95,7 @@ OwnedAttributeValue& OwnedAttributeValue::operator=(const AttributeValue& other)
_attribute->destroy(_value);
}
if ((_attribute = other.getAttribute())) {
_value = _attribute->create(other.getValue());
_value = other.copy();
}
return *this;
}
@ -135,6 +135,16 @@ void* QRgbAttribute::createFromScript(const QScriptValue& value, QScriptEngine*
return encodeInline((QRgb)value.toUInt32());
}
void* QRgbAttribute::createFromVariant(const QVariant& value) const {
switch (value.userType()) {
case QMetaType::QColor:
return encodeInline(value.value<QColor>().rgba());
default:
return encodeInline((QRgb)value.toUInt());
}
}
QWidget* QRgbAttribute::createEditor(QWidget* parent) const {
QRgbEditor* editor = new QRgbEditor(parent);
editor->setColor(_defaultValue);

View file

@ -118,11 +118,19 @@ protected:
class OwnedAttributeValue : public AttributeValue {
public:
OwnedAttributeValue(const AttributePointer& attribute = AttributePointer());
/// Assumes ownership of the specified value. It will be destroyed when this is destroyed or reassigned.
OwnedAttributeValue(const AttributePointer& attribute, void* value);
/// Creates an owned attribute with a copy of the specified attribute's default value.
OwnedAttributeValue(const AttributePointer& attribute = AttributePointer());
/// Creates an owned attribute with a copy of the specified other value.
OwnedAttributeValue(const AttributeValue& other);
/// Destroys the current value, if any.
~OwnedAttributeValue();
/// Destroys the current value, if any, and copies the specified other value.
OwnedAttributeValue& operator=(const AttributeValue& other);
};
@ -159,6 +167,8 @@ public:
virtual void* createFromScript(const QScriptValue& value, QScriptEngine* engine) const { return create(); }
virtual void* createFromVariant(const QVariant& value) const { return create(); }
/// Creates a widget to use to edit values of this attribute, or returns NULL if the attribute isn't editable.
/// The widget should have a single "user" property that will be used to get/set the value.
virtual QWidget* createEditor(QWidget* parent = NULL) const { return NULL; }
@ -232,6 +242,8 @@ public:
virtual void* createFromScript(const QScriptValue& value, QScriptEngine* engine) const;
virtual void* createFromVariant(const QVariant& value) const;
virtual QWidget* createEditor(QWidget* parent = NULL) const;
};

View file

@ -35,16 +35,21 @@ void MetavoxelData::guide(MetavoxelVisitor& visitor) {
const QVector<AttributePointer>& inputs = visitor.getInputs();
const QVector<AttributePointer>& outputs = visitor.getOutputs();
MetavoxelVisitation firstVisitation = { visitor, QVector<MetavoxelNode*>(inputs.size() + 1),
{ glm::vec3(), TOP_LEVEL_SIZE, QVector<AttributeValue>(inputs.size() + 1), QVector<AttributeValue>(outputs.size()) } };
QVector<MetavoxelNode*>(outputs.size()), { glm::vec3(), TOP_LEVEL_SIZE,
QVector<AttributeValue>(inputs.size() + 1), QVector<AttributeValue>(outputs.size()) } };
for (int i = 0; i < inputs.size(); i++) {
MetavoxelNode* node = _roots.value(inputs[i]);
firstVisitation.nodes[i] = node;
MetavoxelNode* node = _roots.value(inputs.at(i));
firstVisitation.inputNodes[i] = node;
firstVisitation.info.inputValues[i] = node ? node->getAttributeValue(inputs[i]) : inputs[i];
}
AttributePointer guideAttribute = AttributeRegistry::getInstance()->getGuideAttribute();
MetavoxelNode* node = _roots.value(guideAttribute);
firstVisitation.nodes.last() = node;
firstVisitation.inputNodes.last() = node;
firstVisitation.info.inputValues.last() = node ? node->getAttributeValue(guideAttribute) : guideAttribute;
for (int i = 0; i < outputs.size(); i++) {
MetavoxelNode* node = _roots.value(outputs.at(i));
firstVisitation.outputNodes[i] = node;
}
static_cast<MetavoxelGuide*>(firstVisitation.info.inputValues.last().getInlineValue<
PolymorphicDataPointer>().data())->guide(firstVisitation);
}
@ -384,20 +389,26 @@ const int Y_MAXIMUM_FLAG = 2;
const int Z_MAXIMUM_FLAG = 4;
void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
visitation.info.isLeaf = visitation.allNodesLeaves();
visitation.info.isLeaf = visitation.allInputNodesLeaves();
if (!visitation.visitor.visit(visitation.info)) {
return;
}
MetavoxelVisitation nextVisitation = { visitation.visitor, QVector<MetavoxelNode*>(visitation.nodes.size()),
{ glm::vec3(), visitation.info.size * 0.5f, QVector<AttributeValue>(visitation.nodes.size()) } };
MetavoxelVisitation nextVisitation = { visitation.visitor, QVector<MetavoxelNode*>(visitation.inputNodes.size()),
QVector<MetavoxelNode*>(visitation.outputNodes.size()), { glm::vec3(), visitation.info.size * 0.5f,
QVector<AttributeValue>(visitation.inputNodes.size()), QVector<AttributeValue>(visitation.outputNodes.size()) } };
for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) {
for (int j = 0; j < visitation.nodes.size(); j++) {
MetavoxelNode* node = visitation.nodes.at(j);
for (int j = 0; j < visitation.inputNodes.size(); j++) {
MetavoxelNode* node = visitation.inputNodes.at(j);
MetavoxelNode* child = node ? node->getChild(i) : NULL;
nextVisitation.info.inputValues[j] = ((nextVisitation.nodes[j] = child)) ?
nextVisitation.info.inputValues[j] = ((nextVisitation.inputNodes[j] = child)) ?
child->getAttributeValue(visitation.info.inputValues[j].getAttribute()) :
visitation.info.inputValues[j];
}
for (int j = 0; j < visitation.outputNodes.size(); j++) {
MetavoxelNode* node = visitation.outputNodes.at(j);
MetavoxelNode* child = node ? node->getChild(i) : NULL;
nextVisitation.outputNodes[j] = child;
}
nextVisitation.info.minimum = visitation.info.minimum + glm::vec3(
(i & X_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f,
(i & Y_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f,
@ -505,8 +516,8 @@ void ScriptedMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
}
}
bool MetavoxelVisitation::allNodesLeaves() const {
foreach (MetavoxelNode* node, nodes) {
bool MetavoxelVisitation::allInputNodesLeaves() const {
foreach (MetavoxelNode* node, inputNodes) {
if (node != NULL && !node->isLeaf()) {
return false;
}

View file

@ -159,7 +159,7 @@ public:
/// Visits a metavoxel.
/// \param info the metavoxel data
/// \return if true, continue descending; if false, stop
virtual bool visit(const MetavoxelInfo& info) = 0;
virtual bool visit(MetavoxelInfo& info) = 0;
protected:
@ -221,10 +221,11 @@ class MetavoxelVisitation {
public:
MetavoxelVisitor& visitor;
QVector<MetavoxelNode*> nodes;
QVector<MetavoxelNode*> inputNodes;
QVector<MetavoxelNode*> outputNodes;
MetavoxelInfo info;
bool allNodesLeaves() const;
bool allInputNodesLeaves() const;
};
#endif /* defined(__interface__MetavoxelData__) */