mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 07:37:20 +02:00
Working on performing the actual edit.
This commit is contained in:
parent
d082cfd705
commit
a3ffb1d8a3
8 changed files with 113 additions and 24 deletions
|
@ -145,6 +145,7 @@ public:
|
||||||
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
|
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
|
||||||
VoxelSystem* getVoxels() { return &_voxels; }
|
VoxelSystem* getVoxels() { return &_voxels; }
|
||||||
ParticleTreeRenderer* getParticles() { return &_particles; }
|
ParticleTreeRenderer* getParticles() { return &_particles; }
|
||||||
|
MetavoxelSystem* getMetavoxels() { return &_metavoxels; }
|
||||||
VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; }
|
VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; }
|
||||||
VoxelTree* getClipboard() { return &_clipboard; }
|
VoxelTree* getClipboard() { return &_clipboard; }
|
||||||
Environment* getEnvironment() { return &_environment; }
|
Environment* getEnvironment() { return &_environment; }
|
||||||
|
|
|
@ -151,7 +151,7 @@ MetavoxelSystem::PointVisitor::PointVisitor(QVector<Point>& points) :
|
||||||
_points(points) {
|
_points(points) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetavoxelSystem::PointVisitor::visit(const MetavoxelInfo& info) {
|
bool MetavoxelSystem::PointVisitor::visit(MetavoxelInfo& info) {
|
||||||
if (!info.isLeaf) {
|
if (!info.isLeaf) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
MetavoxelData& getData() { return _data; }
|
||||||
|
|
||||||
void processData(const QByteArray& data, const HifiSockAddr& sender);
|
void processData(const QByteArray& data, const HifiSockAddr& sender);
|
||||||
|
|
||||||
void simulate(float deltaTime);
|
void simulate(float deltaTime);
|
||||||
|
@ -60,7 +62,7 @@ private:
|
||||||
class PointVisitor : public MetavoxelVisitor {
|
class PointVisitor : public MetavoxelVisitor {
|
||||||
public:
|
public:
|
||||||
PointVisitor(QVector<Point>& points);
|
PointVisitor(QVector<Point>& points);
|
||||||
virtual bool visit(const MetavoxelInfo& info);
|
virtual bool visit(MetavoxelInfo& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<Point>& _points;
|
QVector<Point>& _points;
|
||||||
|
|
|
@ -333,9 +333,61 @@ void MetavoxelEditor::resetState() {
|
||||||
_height = 0.0f;
|
_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) {
|
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();
|
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;
|
ProgramObject MetavoxelEditor::_gridProgram;
|
||||||
|
|
|
@ -72,12 +72,12 @@ bool AttributeValue::operator==(void* other) const {
|
||||||
return _attribute && _attribute->equal(_value, other);
|
return _attribute && _attribute->equal(_value, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnedAttributeValue::OwnedAttributeValue(const AttributePointer& attribute) :
|
OwnedAttributeValue::OwnedAttributeValue(const AttributePointer& attribute, void* value) :
|
||||||
AttributeValue(attribute, attribute ? attribute->create() : NULL) {
|
AttributeValue(attribute, value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnedAttributeValue::OwnedAttributeValue(const AttributePointer& attribute, void* value) :
|
OwnedAttributeValue::OwnedAttributeValue(const AttributePointer& attribute) :
|
||||||
AttributeValue(attribute, attribute ? attribute->create(value) : NULL) {
|
AttributeValue(attribute, attribute ? attribute->create() : NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnedAttributeValue::OwnedAttributeValue(const AttributeValue& other) :
|
OwnedAttributeValue::OwnedAttributeValue(const AttributeValue& other) :
|
||||||
|
@ -95,7 +95,7 @@ OwnedAttributeValue& OwnedAttributeValue::operator=(const AttributeValue& other)
|
||||||
_attribute->destroy(_value);
|
_attribute->destroy(_value);
|
||||||
}
|
}
|
||||||
if ((_attribute = other.getAttribute())) {
|
if ((_attribute = other.getAttribute())) {
|
||||||
_value = _attribute->create(other.getValue());
|
_value = other.copy();
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,16 @@ void* QRgbAttribute::createFromScript(const QScriptValue& value, QScriptEngine*
|
||||||
return encodeInline((QRgb)value.toUInt32());
|
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 {
|
QWidget* QRgbAttribute::createEditor(QWidget* parent) const {
|
||||||
QRgbEditor* editor = new QRgbEditor(parent);
|
QRgbEditor* editor = new QRgbEditor(parent);
|
||||||
editor->setColor(_defaultValue);
|
editor->setColor(_defaultValue);
|
||||||
|
|
|
@ -118,11 +118,19 @@ protected:
|
||||||
class OwnedAttributeValue : public AttributeValue {
|
class OwnedAttributeValue : public AttributeValue {
|
||||||
public:
|
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);
|
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);
|
OwnedAttributeValue(const AttributeValue& other);
|
||||||
|
|
||||||
|
/// Destroys the current value, if any.
|
||||||
~OwnedAttributeValue();
|
~OwnedAttributeValue();
|
||||||
|
|
||||||
|
/// Destroys the current value, if any, and copies the specified other value.
|
||||||
OwnedAttributeValue& operator=(const AttributeValue& other);
|
OwnedAttributeValue& operator=(const AttributeValue& other);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,6 +167,8 @@ public:
|
||||||
|
|
||||||
virtual void* createFromScript(const QScriptValue& value, QScriptEngine* engine) const { return create(); }
|
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.
|
/// 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.
|
/// 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; }
|
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* createFromScript(const QScriptValue& value, QScriptEngine* engine) const;
|
||||||
|
|
||||||
|
virtual void* createFromVariant(const QVariant& value) const;
|
||||||
|
|
||||||
virtual QWidget* createEditor(QWidget* parent = NULL) const;
|
virtual QWidget* createEditor(QWidget* parent = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,16 +35,21 @@ void MetavoxelData::guide(MetavoxelVisitor& visitor) {
|
||||||
const QVector<AttributePointer>& inputs = visitor.getInputs();
|
const QVector<AttributePointer>& inputs = visitor.getInputs();
|
||||||
const QVector<AttributePointer>& outputs = visitor.getOutputs();
|
const QVector<AttributePointer>& outputs = visitor.getOutputs();
|
||||||
MetavoxelVisitation firstVisitation = { visitor, QVector<MetavoxelNode*>(inputs.size() + 1),
|
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++) {
|
for (int i = 0; i < inputs.size(); i++) {
|
||||||
MetavoxelNode* node = _roots.value(inputs[i]);
|
MetavoxelNode* node = _roots.value(inputs.at(i));
|
||||||
firstVisitation.nodes[i] = node;
|
firstVisitation.inputNodes[i] = node;
|
||||||
firstVisitation.info.inputValues[i] = node ? node->getAttributeValue(inputs[i]) : inputs[i];
|
firstVisitation.info.inputValues[i] = node ? node->getAttributeValue(inputs[i]) : inputs[i];
|
||||||
}
|
}
|
||||||
AttributePointer guideAttribute = AttributeRegistry::getInstance()->getGuideAttribute();
|
AttributePointer guideAttribute = AttributeRegistry::getInstance()->getGuideAttribute();
|
||||||
MetavoxelNode* node = _roots.value(guideAttribute);
|
MetavoxelNode* node = _roots.value(guideAttribute);
|
||||||
firstVisitation.nodes.last() = node;
|
firstVisitation.inputNodes.last() = node;
|
||||||
firstVisitation.info.inputValues.last() = node ? node->getAttributeValue(guideAttribute) : guideAttribute;
|
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<
|
static_cast<MetavoxelGuide*>(firstVisitation.info.inputValues.last().getInlineValue<
|
||||||
PolymorphicDataPointer>().data())->guide(firstVisitation);
|
PolymorphicDataPointer>().data())->guide(firstVisitation);
|
||||||
}
|
}
|
||||||
|
@ -384,20 +389,26 @@ const int Y_MAXIMUM_FLAG = 2;
|
||||||
const int Z_MAXIMUM_FLAG = 4;
|
const int Z_MAXIMUM_FLAG = 4;
|
||||||
|
|
||||||
void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
visitation.info.isLeaf = visitation.allNodesLeaves();
|
visitation.info.isLeaf = visitation.allInputNodesLeaves();
|
||||||
if (!visitation.visitor.visit(visitation.info)) {
|
if (!visitation.visitor.visit(visitation.info)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MetavoxelVisitation nextVisitation = { visitation.visitor, QVector<MetavoxelNode*>(visitation.nodes.size()),
|
MetavoxelVisitation nextVisitation = { visitation.visitor, QVector<MetavoxelNode*>(visitation.inputNodes.size()),
|
||||||
{ glm::vec3(), visitation.info.size * 0.5f, QVector<AttributeValue>(visitation.nodes.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 i = 0; i < MetavoxelNode::CHILD_COUNT; i++) {
|
||||||
for (int j = 0; j < visitation.nodes.size(); j++) {
|
for (int j = 0; j < visitation.inputNodes.size(); j++) {
|
||||||
MetavoxelNode* node = visitation.nodes.at(j);
|
MetavoxelNode* node = visitation.inputNodes.at(j);
|
||||||
MetavoxelNode* child = node ? node->getChild(i) : NULL;
|
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()) :
|
child->getAttributeValue(visitation.info.inputValues[j].getAttribute()) :
|
||||||
visitation.info.inputValues[j];
|
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(
|
nextVisitation.info.minimum = visitation.info.minimum + glm::vec3(
|
||||||
(i & X_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f,
|
(i & X_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f,
|
||||||
(i & Y_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 {
|
bool MetavoxelVisitation::allInputNodesLeaves() const {
|
||||||
foreach (MetavoxelNode* node, nodes) {
|
foreach (MetavoxelNode* node, inputNodes) {
|
||||||
if (node != NULL && !node->isLeaf()) {
|
if (node != NULL && !node->isLeaf()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ public:
|
||||||
/// Visits a metavoxel.
|
/// Visits a metavoxel.
|
||||||
/// \param info the metavoxel data
|
/// \param info the metavoxel data
|
||||||
/// \return if true, continue descending; if false, stop
|
/// \return if true, continue descending; if false, stop
|
||||||
virtual bool visit(const MetavoxelInfo& info) = 0;
|
virtual bool visit(MetavoxelInfo& info) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -221,10 +221,11 @@ class MetavoxelVisitation {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MetavoxelVisitor& visitor;
|
MetavoxelVisitor& visitor;
|
||||||
QVector<MetavoxelNode*> nodes;
|
QVector<MetavoxelNode*> inputNodes;
|
||||||
|
QVector<MetavoxelNode*> outputNodes;
|
||||||
MetavoxelInfo info;
|
MetavoxelInfo info;
|
||||||
|
|
||||||
bool allNodesLeaves() const;
|
bool allInputNodesLeaves() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__MetavoxelData__) */
|
#endif /* defined(__interface__MetavoxelData__) */
|
||||||
|
|
Loading…
Reference in a new issue