mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 12:42:58 +02:00
Working on voxelizing spanners.
This commit is contained in:
parent
249e9f0e33
commit
5934a7fbea
8 changed files with 220 additions and 88 deletions
|
@ -4,22 +4,22 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Application</name>
|
<name>Application</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="1368"/>
|
<location filename="src/Application.cpp" line="1380"/>
|
||||||
<source>Export Voxels</source>
|
<source>Export Voxels</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="1369"/>
|
<location filename="src/Application.cpp" line="1381"/>
|
||||||
<source>Sparse Voxel Octree Files (*.svo)</source>
|
<source>Sparse Voxel Octree Files (*.svo)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="3596"/>
|
<location filename="src/Application.cpp" line="3597"/>
|
||||||
<source>Open Script</source>
|
<source>Open Script</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="3597"/>
|
<location filename="src/Application.cpp" line="3598"/>
|
||||||
<source>JavaScript Files (*.js)</source>
|
<source>JavaScript Files (*.js)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -113,18 +113,18 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Menu</name>
|
<name>Menu</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="455"/>
|
<location filename="src/Menu.cpp" line="457"/>
|
||||||
<source>Open .ini config file</source>
|
<source>Open .ini config file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="457"/>
|
<location filename="src/Menu.cpp" line="459"/>
|
||||||
<location filename="src/Menu.cpp" line="469"/>
|
<location filename="src/Menu.cpp" line="471"/>
|
||||||
<source>Text files (*.ini)</source>
|
<source>Text files (*.ini)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="467"/>
|
<location filename="src/Menu.cpp" line="469"/>
|
||||||
<source>Save .ini config file</source>
|
<source>Save .ini config file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -168,7 +168,9 @@ void MetavoxelSystem::maybeAttachClient(const SharedNodePointer& node) {
|
||||||
MetavoxelSystem::SimulateVisitor::SimulateVisitor(QVector<Point>& points) :
|
MetavoxelSystem::SimulateVisitor::SimulateVisitor(QVector<Point>& points) :
|
||||||
SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(),
|
SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(),
|
||||||
QVector<AttributePointer>() << AttributeRegistry::getInstance()->getColorAttribute() <<
|
QVector<AttributePointer>() << AttributeRegistry::getInstance()->getColorAttribute() <<
|
||||||
AttributeRegistry::getInstance()->getNormalAttribute()),
|
AttributeRegistry::getInstance()->getNormalAttribute() <<
|
||||||
|
AttributeRegistry::getInstance()->getSpannerColorAttribute() <<
|
||||||
|
AttributeRegistry::getInstance()->getSpannerNormalAttribute()),
|
||||||
_points(points) {
|
_points(points) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,11 +188,36 @@ int MetavoxelSystem::SimulateVisitor::visit(MetavoxelInfo& info) {
|
||||||
QRgb color = info.inputValues.at(0).getInlineValue<QRgb>();
|
QRgb color = info.inputValues.at(0).getInlineValue<QRgb>();
|
||||||
QRgb normal = info.inputValues.at(1).getInlineValue<QRgb>();
|
QRgb normal = info.inputValues.at(1).getInlineValue<QRgb>();
|
||||||
quint8 alpha = qAlpha(color);
|
quint8 alpha = qAlpha(color);
|
||||||
if (alpha > 0) {
|
if (info.inputValues.at(4).getAttribute()) {
|
||||||
Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size),
|
if (alpha > 0) {
|
||||||
{ quint8(qRed(color)), quint8(qGreen(color)), quint8(qBlue(color)), alpha },
|
Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size),
|
||||||
{ quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } };
|
{ quint8(qRed(color)), quint8(qGreen(color)), quint8(qBlue(color)), alpha },
|
||||||
_points.append(point);
|
{ quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } };
|
||||||
|
_points.append(point);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QRgb spannerColor = info.inputValues.at(2).getInlineValue<QRgb>();
|
||||||
|
QRgb spannerNormal = info.inputValues.at(3).getInlineValue<QRgb>();
|
||||||
|
quint8 spannerAlpha = qAlpha(spannerColor);
|
||||||
|
if (spannerAlpha > 0) {
|
||||||
|
if (alpha > 0) {
|
||||||
|
Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size),
|
||||||
|
{ quint8(qRed(spannerColor)), quint8(qGreen(spannerColor)), quint8(qBlue(spannerColor)), spannerAlpha },
|
||||||
|
{ quint8(qRed(spannerNormal)), quint8(qGreen(spannerNormal)), quint8(qBlue(spannerNormal)) } };
|
||||||
|
_points.append(point);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size),
|
||||||
|
{ quint8(qRed(spannerColor)), quint8(qGreen(spannerColor)), quint8(qBlue(spannerColor)), spannerAlpha },
|
||||||
|
{ quint8(qRed(spannerNormal)), quint8(qGreen(spannerNormal)), quint8(qBlue(spannerNormal)) } };
|
||||||
|
_points.append(point);
|
||||||
|
}
|
||||||
|
} else if (alpha > 0) {
|
||||||
|
Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size),
|
||||||
|
{ quint8(qRed(color)), quint8(qGreen(color)), quint8(qBlue(color)), alpha },
|
||||||
|
{ quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } };
|
||||||
|
_points.append(point);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return STOP_RECURSION;
|
return STOP_RECURSION;
|
||||||
}
|
}
|
||||||
|
|
|
@ -655,6 +655,5 @@ bool SetSpannerTool::appliesTo(const AttributePointer& attribute) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SetSpannerTool::createEdit(const AttributePointer& attribute, const SharedObjectPointer& spanner) {
|
QVariant SetSpannerTool::createEdit(const AttributePointer& attribute, const SharedObjectPointer& spanner) {
|
||||||
static_cast<Spanner*>(spanner.data())->setGranularity(_editor->getGridSpacing());
|
|
||||||
return QVariant::fromValue(SetSpannerEdit(spanner));
|
return QVariant::fromValue(SetSpannerEdit(spanner));
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,9 @@ AttributeRegistry::AttributeRegistry() :
|
||||||
SharedObjectPointer(new DefaultMetavoxelGuide())))),
|
SharedObjectPointer(new DefaultMetavoxelGuide())))),
|
||||||
_spannersAttribute(registerAttribute(new SpannerSetAttribute("spanners", &Spanner::staticMetaObject))),
|
_spannersAttribute(registerAttribute(new SpannerSetAttribute("spanners", &Spanner::staticMetaObject))),
|
||||||
_colorAttribute(registerAttribute(new QRgbAttribute("color"))),
|
_colorAttribute(registerAttribute(new QRgbAttribute("color"))),
|
||||||
_normalAttribute(registerAttribute(new PackedNormalAttribute("normal", qRgb(0, 127, 0)))) {
|
_normalAttribute(registerAttribute(new PackedNormalAttribute("normal", qRgb(0, 127, 0)))),
|
||||||
|
_spannerColorAttribute(registerAttribute(new QRgbAttribute("spannerColor"))),
|
||||||
|
_spannerNormalAttribute(registerAttribute(new PackedNormalAttribute("spannerNormal", qRgb(0, 127, 0)))) {
|
||||||
|
|
||||||
// our baseline LOD threshold is for voxels; spanners are a different story
|
// our baseline LOD threshold is for voxels; spanners are a different story
|
||||||
const float SPANNER_LOD_THRESHOLD_MULTIPLIER = 4.0f;
|
const float SPANNER_LOD_THRESHOLD_MULTIPLIER = 4.0f;
|
||||||
|
@ -92,6 +94,10 @@ bool AttributeValue::isDefault() const {
|
||||||
return !_attribute || _attribute->equal(_value, _attribute->getDefaultValue());
|
return !_attribute || _attribute->equal(_value, _attribute->getDefaultValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttributeValue AttributeValue::split() const {
|
||||||
|
return _attribute ? _attribute->split(*this) : AttributeValue();
|
||||||
|
}
|
||||||
|
|
||||||
bool AttributeValue::operator==(const AttributeValue& other) const {
|
bool AttributeValue::operator==(const AttributeValue& other) const {
|
||||||
return _attribute == other._attribute && (!_attribute || _attribute->equal(_value, other._value));
|
return _attribute == other._attribute && (!_attribute || _attribute->equal(_value, other._value));
|
||||||
}
|
}
|
||||||
|
@ -130,6 +136,14 @@ OwnedAttributeValue::~OwnedAttributeValue() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OwnedAttributeValue::mix(const AttributeValue& first, const AttributeValue& second, float alpha) {
|
||||||
|
if (_attribute) {
|
||||||
|
_attribute->destroy(_value);
|
||||||
|
}
|
||||||
|
_attribute = first.getAttribute();
|
||||||
|
_value = _attribute->mix(first.getValue(), second.getValue(), alpha);
|
||||||
|
}
|
||||||
|
|
||||||
OwnedAttributeValue& OwnedAttributeValue::operator=(const AttributeValue& other) {
|
OwnedAttributeValue& OwnedAttributeValue::operator=(const AttributeValue& other) {
|
||||||
if (_attribute) {
|
if (_attribute) {
|
||||||
_attribute->destroy(_value);
|
_attribute->destroy(_value);
|
||||||
|
@ -206,6 +220,16 @@ bool QRgbAttribute::merge(void*& parent, void* children[]) const {
|
||||||
return allChildrenEqual;
|
return allChildrenEqual;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* QRgbAttribute::mix(void* first, void* second, float alpha) const {
|
||||||
|
QRgb firstValue = decodeInline<QRgb>(first);
|
||||||
|
QRgb secondValue = decodeInline<QRgb>(second);
|
||||||
|
return encodeInline(qRgba(
|
||||||
|
glm::mix((float)qRed(firstValue), (float)qRed(secondValue), alpha),
|
||||||
|
glm::mix((float)qGreen(firstValue), (float)qGreen(secondValue), alpha),
|
||||||
|
glm::mix((float)qBlue(firstValue), (float)qBlue(secondValue), alpha),
|
||||||
|
glm::mix((float)qAlpha(firstValue), (float)qAlpha(secondValue), alpha)));
|
||||||
|
}
|
||||||
|
|
||||||
void* QRgbAttribute::createFromScript(const QScriptValue& value, QScriptEngine* engine) const {
|
void* QRgbAttribute::createFromScript(const QScriptValue& value, QScriptEngine* engine) const {
|
||||||
return encodeInline((QRgb)value.toUInt32());
|
return encodeInline((QRgb)value.toUInt32());
|
||||||
}
|
}
|
||||||
|
@ -232,21 +256,23 @@ PackedNormalAttribute::PackedNormalAttribute(const QString& name, QRgb defaultVa
|
||||||
|
|
||||||
bool PackedNormalAttribute::merge(void*& parent, void* children[]) const {
|
bool PackedNormalAttribute::merge(void*& parent, void* children[]) const {
|
||||||
QRgb firstValue = decodeInline<QRgb>(children[0]);
|
QRgb firstValue = decodeInline<QRgb>(children[0]);
|
||||||
int totalRed = (char)qRed(firstValue);
|
glm::vec3 total = unpackNormal(firstValue);
|
||||||
int totalGreen = (char)qGreen(firstValue);
|
|
||||||
int totalBlue = (char)qBlue(firstValue);
|
|
||||||
bool allChildrenEqual = true;
|
bool allChildrenEqual = true;
|
||||||
for (int i = 1; i < Attribute::MERGE_COUNT; i++) {
|
for (int i = 1; i < Attribute::MERGE_COUNT; i++) {
|
||||||
QRgb value = decodeInline<QRgb>(children[i]);
|
QRgb value = decodeInline<QRgb>(children[i]);
|
||||||
totalRed += (char)qRed(value);
|
total += unpackNormal(value);
|
||||||
totalGreen += (char)qGreen(value);
|
|
||||||
totalBlue += (char)qBlue(value);
|
|
||||||
allChildrenEqual &= (firstValue == value);
|
allChildrenEqual &= (firstValue == value);
|
||||||
}
|
}
|
||||||
parent = encodeInline(packNormal(glm::normalize(glm::vec3(totalRed, totalGreen, totalBlue))));
|
parent = encodeInline(packNormal(glm::normalize(total)));
|
||||||
return allChildrenEqual;
|
return allChildrenEqual;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* PackedNormalAttribute::mix(void* first, void* second, float alpha) const {
|
||||||
|
glm::vec3 firstNormal = unpackNormal(decodeInline<QRgb>(first));
|
||||||
|
glm::vec3 secondNormal = unpackNormal(decodeInline<QRgb>(second));
|
||||||
|
return encodeInline(packNormal(glm::normalize(glm::mix(firstNormal, secondNormal, alpha))));
|
||||||
|
}
|
||||||
|
|
||||||
const float CHAR_SCALE = 127.0f;
|
const float CHAR_SCALE = 127.0f;
|
||||||
const float INVERSE_CHAR_SCALE = 1.0f / CHAR_SCALE;
|
const float INVERSE_CHAR_SCALE = 1.0f / CHAR_SCALE;
|
||||||
|
|
||||||
|
@ -290,6 +316,10 @@ bool SharedObjectAttribute::merge(void*& parent, void* children[]) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttributeValue SharedObjectSetAttribute::split(const AttributeValue& parent) const {
|
||||||
|
return AttributeValue();
|
||||||
|
}
|
||||||
|
|
||||||
void* SharedObjectAttribute::createFromVariant(const QVariant& value) const {
|
void* SharedObjectAttribute::createFromVariant(const QVariant& value) const {
|
||||||
return create(encodeInline(value.value<SharedObjectPointer>()));
|
return create(encodeInline(value.value<SharedObjectPointer>()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,9 +71,15 @@ public:
|
||||||
/// Returns a reference to the standard QRgb "color" attribute.
|
/// Returns a reference to the standard QRgb "color" attribute.
|
||||||
const AttributePointer& getColorAttribute() const { return _colorAttribute; }
|
const AttributePointer& getColorAttribute() const { return _colorAttribute; }
|
||||||
|
|
||||||
/// Returns a reference to the standard QRgb "normal" attribute.
|
/// Returns a reference to the standard packed normal "normal" attribute.
|
||||||
const AttributePointer& getNormalAttribute() const { return _normalAttribute; }
|
const AttributePointer& getNormalAttribute() const { return _normalAttribute; }
|
||||||
|
|
||||||
|
/// Returns a reference to the standard QRgb "spannerColor" attribute.
|
||||||
|
const AttributePointer& getSpannerColorAttribute() const { return _spannerColorAttribute; }
|
||||||
|
|
||||||
|
/// Returns a reference to the standard packed normal "spannerNormal" attribute.
|
||||||
|
const AttributePointer& getSpannerNormalAttribute() const { return _spannerNormalAttribute; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static QScriptValue getAttribute(QScriptContext* context, QScriptEngine* engine);
|
static QScriptValue getAttribute(QScriptContext* context, QScriptEngine* engine);
|
||||||
|
@ -83,6 +89,8 @@ private:
|
||||||
AttributePointer _spannersAttribute;
|
AttributePointer _spannersAttribute;
|
||||||
AttributePointer _colorAttribute;
|
AttributePointer _colorAttribute;
|
||||||
AttributePointer _normalAttribute;
|
AttributePointer _normalAttribute;
|
||||||
|
AttributePointer _spannerColorAttribute;
|
||||||
|
AttributePointer _spannerNormalAttribute;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Converts a value to a void pointer.
|
/// Converts a value to a void pointer.
|
||||||
|
@ -107,13 +115,14 @@ public:
|
||||||
|
|
||||||
template<class T> void setInlineValue(T value) { _value = encodeInline(value); }
|
template<class T> void setInlineValue(T value) { _value = encodeInline(value); }
|
||||||
template<class T> T getInlineValue() const { return decodeInline<T>(_value); }
|
template<class T> T getInlineValue() const { return decodeInline<T>(_value); }
|
||||||
|
template<class T> T getSafeInlineValue() const { return _attribute ? decodeInline<T>(_value) : T(); }
|
||||||
template<class T> T* getPointerValue() const { return static_cast<T*>(_value); }
|
|
||||||
|
|
||||||
void* copy() const;
|
void* copy() const;
|
||||||
|
|
||||||
bool isDefault() const;
|
bool isDefault() const;
|
||||||
|
|
||||||
|
AttributeValue split() const;
|
||||||
|
|
||||||
bool operator==(const AttributeValue& other) const;
|
bool operator==(const AttributeValue& other) const;
|
||||||
bool operator==(void* other) const;
|
bool operator==(void* other) const;
|
||||||
|
|
||||||
|
@ -145,6 +154,9 @@ public:
|
||||||
/// Destroys the current value, if any.
|
/// Destroys the current value, if any.
|
||||||
~OwnedAttributeValue();
|
~OwnedAttributeValue();
|
||||||
|
|
||||||
|
/// Sets this attribute to a mix of the first and second provided.
|
||||||
|
void mix(const AttributeValue& first, const AttributeValue& second, float alpha);
|
||||||
|
|
||||||
/// Destroys the current value, if any, and copies the specified other value.
|
/// Destroys the current value, if any, and copies the specified other value.
|
||||||
OwnedAttributeValue& operator=(const AttributeValue& other);
|
OwnedAttributeValue& operator=(const AttributeValue& other);
|
||||||
|
|
||||||
|
@ -196,6 +208,12 @@ public:
|
||||||
/// \return whether or not the children and parent values are all equal
|
/// \return whether or not the children and parent values are all equal
|
||||||
virtual bool merge(void*& parent, void* children[]) const = 0;
|
virtual bool merge(void*& parent, void* children[]) const = 0;
|
||||||
|
|
||||||
|
/// Returns the attribute value to pass to children below leaves (either the parent, or the default, or a null value).
|
||||||
|
virtual AttributeValue split(const AttributeValue& parent) const { return parent; }
|
||||||
|
|
||||||
|
/// Mixes the first and the second, returning a new value with the result.
|
||||||
|
virtual void* mix(void* first, void* second, float alpha) const = 0;
|
||||||
|
|
||||||
virtual void* getDefaultValue() const = 0;
|
virtual void* getDefaultValue() const = 0;
|
||||||
|
|
||||||
virtual void* createFromScript(const QScriptValue& value, QScriptEngine* engine) const { return create(); }
|
virtual void* createFromScript(const QScriptValue& value, QScriptEngine* engine) const { return create(); }
|
||||||
|
@ -225,6 +243,8 @@ public:
|
||||||
|
|
||||||
virtual bool equal(void* first, void* second) const { return decodeInline<T>(first) == decodeInline<T>(second); }
|
virtual bool equal(void* first, void* second) const { return decodeInline<T>(first) == decodeInline<T>(second); }
|
||||||
|
|
||||||
|
virtual void* mix(void* first, void* second, float alpha) const { return create(alpha < 0.5f ? first : second); }
|
||||||
|
|
||||||
virtual void* getDefaultValue() const { return encodeInline(_defaultValue); }
|
virtual void* getDefaultValue() const { return encodeInline(_defaultValue); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -245,27 +265,6 @@ template<class T, int bits> inline void InlineAttribute<T, bits>::write(Bitstrea
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides merging using the =, ==, += and /= operators.
|
|
||||||
template<class T, int bits = 32> class SimpleInlineAttribute : public InlineAttribute<T, bits> {
|
|
||||||
public:
|
|
||||||
|
|
||||||
SimpleInlineAttribute(const QString& name, T defaultValue = T()) : InlineAttribute<T, bits>(name, defaultValue) { }
|
|
||||||
|
|
||||||
virtual bool merge(void*& parent, void* children[]) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, int bits> inline bool SimpleInlineAttribute<T, bits>::merge(void*& parent, void* children[]) const {
|
|
||||||
T& merged = *(T*)&parent;
|
|
||||||
merged = decodeInline<T>(children[0]);
|
|
||||||
bool allChildrenEqual = true;
|
|
||||||
for (int i = 1; i < Attribute::MERGE_COUNT; i++) {
|
|
||||||
merged += decodeInline<T>(children[i]);
|
|
||||||
allChildrenEqual &= (decodeInline<T>(children[0]) == decodeInline<T>(children[i]));
|
|
||||||
}
|
|
||||||
merged /= Attribute::MERGE_COUNT;
|
|
||||||
return allChildrenEqual;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides appropriate averaging for RGBA values.
|
/// Provides appropriate averaging for RGBA values.
|
||||||
class QRgbAttribute : public InlineAttribute<QRgb> {
|
class QRgbAttribute : public InlineAttribute<QRgb> {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -277,6 +276,8 @@ public:
|
||||||
|
|
||||||
virtual bool merge(void*& parent, void* children[]) const;
|
virtual bool merge(void*& parent, void* children[]) const;
|
||||||
|
|
||||||
|
virtual void* mix(void* first, void* second, float alpha) const;
|
||||||
|
|
||||||
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 void* createFromVariant(const QVariant& value) const;
|
||||||
|
@ -293,6 +294,8 @@ public:
|
||||||
Q_INVOKABLE PackedNormalAttribute(const QString& name = QString(), QRgb defaultValue = QRgb());
|
Q_INVOKABLE PackedNormalAttribute(const QString& name = QString(), QRgb defaultValue = QRgb());
|
||||||
|
|
||||||
virtual bool merge(void*& parent, void* children[]) const;
|
virtual bool merge(void*& parent, void* children[]) const;
|
||||||
|
|
||||||
|
virtual void* mix(void* first, void* second, float alpha) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Packs a normal into an RGB value.
|
/// Packs a normal into an RGB value.
|
||||||
|
@ -343,6 +346,8 @@ public:
|
||||||
|
|
||||||
virtual bool merge(void*& parent, void* children[]) const;
|
virtual bool merge(void*& parent, void* children[]) const;
|
||||||
|
|
||||||
|
virtual AttributeValue split(const AttributeValue& parent) const;
|
||||||
|
|
||||||
virtual QWidget* createEditor(QWidget* parent = NULL) const;
|
virtual QWidget* createEditor(QWidget* parent = NULL) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -169,7 +169,7 @@ template<SpannerUpdateFunction F> int SpannerUpdateVisitor<F>::visit(MetavoxelIn
|
||||||
if (info.size > _longestSide) {
|
if (info.size > _longestSide) {
|
||||||
return DEFAULT_ORDER;
|
return DEFAULT_ORDER;
|
||||||
}
|
}
|
||||||
SharedObjectSet set = info.inputValues.at(0).getInlineValue<SharedObjectSet>();
|
SharedObjectSet set = info.inputValues.at(0).getSafeInlineValue<SharedObjectSet>();
|
||||||
F(set, _object);
|
F(set, _object);
|
||||||
info.outputValues[0] = AttributeValue(_attribute, encodeInline(set));
|
info.outputValues[0] = AttributeValue(_attribute, encodeInline(set));
|
||||||
return STOP_RECURSION;
|
return STOP_RECURSION;
|
||||||
|
@ -177,7 +177,7 @@ template<SpannerUpdateFunction F> int SpannerUpdateVisitor<F>::visit(MetavoxelIn
|
||||||
|
|
||||||
void MetavoxelData::insert(const AttributePointer& attribute, const SharedObjectPointer& object) {
|
void MetavoxelData::insert(const AttributePointer& attribute, const SharedObjectPointer& object) {
|
||||||
Spanner* spanner = static_cast<Spanner*>(object.data());
|
Spanner* spanner = static_cast<Spanner*>(object.data());
|
||||||
insert(attribute, spanner->getBounds(), spanner->getGranularity(), object);
|
insert(attribute, spanner->getBounds(), spanner->getPlacementGranularity(), object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelData::insert(const AttributePointer& attribute, const Box& bounds,
|
void MetavoxelData::insert(const AttributePointer& attribute, const Box& bounds,
|
||||||
|
@ -192,7 +192,7 @@ void MetavoxelData::insert(const AttributePointer& attribute, const Box& bounds,
|
||||||
|
|
||||||
void MetavoxelData::remove(const AttributePointer& attribute, const SharedObjectPointer& object) {
|
void MetavoxelData::remove(const AttributePointer& attribute, const SharedObjectPointer& object) {
|
||||||
Spanner* spanner = static_cast<Spanner*>(object.data());
|
Spanner* spanner = static_cast<Spanner*>(object.data());
|
||||||
remove(attribute, spanner->getBounds(), spanner->getGranularity(), object);
|
remove(attribute, spanner->getBounds(), spanner->getPlacementGranularity(), object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelData::remove(const AttributePointer& attribute, const Box& bounds,
|
void MetavoxelData::remove(const AttributePointer& attribute, const Box& bounds,
|
||||||
|
@ -203,7 +203,7 @@ void MetavoxelData::remove(const AttributePointer& attribute, const Box& bounds,
|
||||||
|
|
||||||
void MetavoxelData::toggle(const AttributePointer& attribute, const SharedObjectPointer& object) {
|
void MetavoxelData::toggle(const AttributePointer& attribute, const SharedObjectPointer& object) {
|
||||||
Spanner* spanner = static_cast<Spanner*>(object.data());
|
Spanner* spanner = static_cast<Spanner*>(object.data());
|
||||||
toggle(attribute, spanner->getBounds(), spanner->getGranularity(), object);
|
toggle(attribute, spanner->getBounds(), spanner->getPlacementGranularity(), object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelData::toggle(const AttributePointer& attribute, const Box& bounds,
|
void MetavoxelData::toggle(const AttributePointer& attribute, const Box& bounds,
|
||||||
|
@ -875,7 +875,7 @@ void SpannerVisitor::prepare() {
|
||||||
|
|
||||||
int SpannerVisitor::visit(MetavoxelInfo& info) {
|
int SpannerVisitor::visit(MetavoxelInfo& info) {
|
||||||
for (int i = _inputs.size() - _spannerInputCount; i < _inputs.size(); i++) {
|
for (int i = _inputs.size() - _spannerInputCount; i < _inputs.size(); i++) {
|
||||||
foreach (const SharedObjectPointer& object, info.inputValues.at(i).getInlineValue<SharedObjectSet>()) {
|
foreach (const SharedObjectPointer& object, info.inputValues.at(i).getSafeInlineValue<SharedObjectSet>()) {
|
||||||
Spanner* spanner = static_cast<Spanner*>(object.data());
|
Spanner* spanner = static_cast<Spanner*>(object.data());
|
||||||
if (spanner->testAndSetVisited()) {
|
if (spanner->testAndSetVisited()) {
|
||||||
if (!visit(spanner)) {
|
if (!visit(spanner)) {
|
||||||
|
@ -927,7 +927,7 @@ bool operator<(const SpannerDistance& first, const SpannerDistance& second) {
|
||||||
int RaySpannerIntersectionVisitor::visit(MetavoxelInfo& info, float distance) {
|
int RaySpannerIntersectionVisitor::visit(MetavoxelInfo& info, float distance) {
|
||||||
QVarLengthArray<SpannerDistance, 4> spannerDistances;
|
QVarLengthArray<SpannerDistance, 4> spannerDistances;
|
||||||
for (int i = _inputs.size() - _spannerInputCount; i < _inputs.size(); i++) {
|
for (int i = _inputs.size() - _spannerInputCount; i < _inputs.size(); i++) {
|
||||||
foreach (const SharedObjectPointer& object, info.inputValues.at(i).getInlineValue<SharedObjectSet>()) {
|
foreach (const SharedObjectPointer& object, info.inputValues.at(i).getSafeInlineValue<SharedObjectSet>()) {
|
||||||
Spanner* spanner = static_cast<Spanner*>(object.data());
|
Spanner* spanner = static_cast<Spanner*>(object.data());
|
||||||
if (spanner->testAndSetVisited()) {
|
if (spanner->testAndSetVisited()) {
|
||||||
SpannerDistance spannerDistance = { spanner };
|
SpannerDistance spannerDistance = { spanner };
|
||||||
|
@ -991,7 +991,7 @@ bool DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
MetavoxelNode* child = (node && (visitation.info.size >= lodBase *
|
MetavoxelNode* child = (node && (visitation.info.size >= lodBase *
|
||||||
parentValue.getAttribute()->getLODThresholdMultiplier())) ? node->getChild(index) : NULL;
|
parentValue.getAttribute()->getLODThresholdMultiplier())) ? node->getChild(index) : NULL;
|
||||||
nextVisitation.info.inputValues[j] = ((nextVisitation.inputNodes[j] = child)) ?
|
nextVisitation.info.inputValues[j] = ((nextVisitation.inputNodes[j] = child)) ?
|
||||||
child->getAttributeValue(parentValue.getAttribute()) : parentValue;
|
child->getAttributeValue(parentValue.getAttribute()) : parentValue.split();
|
||||||
}
|
}
|
||||||
for (int j = 0; j < visitation.outputNodes.size(); j++) {
|
for (int j = 0; j < visitation.outputNodes.size(); j++) {
|
||||||
MetavoxelNode* node = visitation.outputNodes.at(j);
|
MetavoxelNode* node = visitation.outputNodes.at(j);
|
||||||
|
@ -1202,11 +1202,13 @@ AttributeValue MetavoxelVisitation::getInheritedOutputValue(int index) const {
|
||||||
return AttributeValue(visitor.getOutputs().at(index));
|
return AttributeValue(visitor.getOutputs().at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
const float DEFAULT_GRANULARITY = 0.01f;
|
const float DEFAULT_PLACEMENT_GRANULARITY = 0.01f;
|
||||||
|
const float DEFAULT_VOXELIZATION_GRANULARITY = powf(2.0f, -3.0f);
|
||||||
|
|
||||||
Spanner::Spanner() :
|
Spanner::Spanner() :
|
||||||
_renderer(NULL),
|
_renderer(NULL),
|
||||||
_granularity(DEFAULT_GRANULARITY),
|
_placementGranularity(DEFAULT_PLACEMENT_GRANULARITY),
|
||||||
|
_voxelizationGranularity(DEFAULT_VOXELIZATION_GRANULARITY),
|
||||||
_lastVisit(0) {
|
_lastVisit(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,10 +1225,19 @@ const QVector<AttributePointer>& Spanner::getAttributes() const {
|
||||||
return emptyVector;
|
return emptyVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QVector<AttributePointer>& Spanner::getVoxelizedAttributes() const {
|
||||||
|
static QVector<AttributePointer> emptyVector;
|
||||||
|
return emptyVector;
|
||||||
|
}
|
||||||
|
|
||||||
bool Spanner::getAttributeValues(MetavoxelInfo& info) const {
|
bool Spanner::getAttributeValues(MetavoxelInfo& info) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Spanner::blendAttributeValues(MetavoxelInfo& info) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Spanner::testAndSetVisited() {
|
bool Spanner::testAndSetVisited() {
|
||||||
if (_lastVisit == _visit) {
|
if (_lastVisit == _visit) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1320,6 +1331,13 @@ const QVector<AttributePointer>& Sphere::getAttributes() const {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QVector<AttributePointer>& Sphere::getVoxelizedAttributes() const {
|
||||||
|
static QVector<AttributePointer> attributes = QVector<AttributePointer>() <<
|
||||||
|
AttributeRegistry::getInstance()->getSpannerColorAttribute() <<
|
||||||
|
AttributeRegistry::getInstance()->getSpannerNormalAttribute();
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
bool Sphere::getAttributeValues(MetavoxelInfo& info) const {
|
bool Sphere::getAttributeValues(MetavoxelInfo& info) const {
|
||||||
// bounds check
|
// bounds check
|
||||||
Box bounds = info.getBounds();
|
Box bounds = info.getBounds();
|
||||||
|
@ -1339,7 +1357,7 @@ bool Sphere::getAttributeValues(MetavoxelInfo& info) const {
|
||||||
getNormal(info);
|
getNormal(info);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (info.size <= getGranularity()) {
|
if (info.size <= getVoxelizationGranularity()) {
|
||||||
// best guess
|
// best guess
|
||||||
if (pointsWithin > 0) {
|
if (pointsWithin > 0) {
|
||||||
info.outputValues[0] = AttributeValue(getAttributes().at(0), encodeInline<QRgb>(qRgba(
|
info.outputValues[0] = AttributeValue(getAttributes().at(0), encodeInline<QRgb>(qRgba(
|
||||||
|
@ -1351,6 +1369,41 @@ bool Sphere::getAttributeValues(MetavoxelInfo& info) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sphere::blendAttributeValues(MetavoxelInfo& info) const {
|
||||||
|
// bounds check
|
||||||
|
Box bounds = info.getBounds();
|
||||||
|
if (!getBounds().intersects(bounds)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// count the points inside the sphere
|
||||||
|
int pointsWithin = 0;
|
||||||
|
for (int i = 0; i < Box::VERTEX_COUNT; i++) {
|
||||||
|
if (glm::distance(bounds.getVertex(i), getTranslation()) <= getScale()) {
|
||||||
|
pointsWithin++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pointsWithin == Box::VERTEX_COUNT) {
|
||||||
|
// entirely contained
|
||||||
|
info.outputValues[0] = AttributeValue(getAttributes().at(0), encodeInline<QRgb>(_color.rgba()));
|
||||||
|
info.outputValues[1] = getNormal(info);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (info.size <= getVoxelizationGranularity()) {
|
||||||
|
// best guess
|
||||||
|
if (pointsWithin > 0) {
|
||||||
|
int oldAlpha = qAlpha(info.inputValues.at(0).getInlineValue<QRgb>());
|
||||||
|
int newAlpha = _color.alpha() * pointsWithin / Box::VERTEX_COUNT;
|
||||||
|
float combinedAlpha = (float)newAlpha / (oldAlpha + newAlpha);
|
||||||
|
info.outputValues[0].mix(info.inputValues.at(0), AttributeValue(getAttributes().at(0),
|
||||||
|
encodeInline<QRgb>(qRgba(_color.red(), _color.green(), _color.blue(),
|
||||||
|
_color.alpha() * pointsWithin / Box::VERTEX_COUNT))), combinedAlpha);
|
||||||
|
info.outputValues[1].mix(info.inputValues.at(1), getNormal(info), combinedAlpha);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Sphere::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
|
bool Sphere::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
|
||||||
return findRaySphereIntersection(origin, direction, getTranslation(), getScale(), distance);
|
return findRaySphereIntersection(origin, direction, getTranslation(), getScale(), distance);
|
||||||
}
|
}
|
||||||
|
@ -1364,7 +1417,7 @@ void Sphere::updateBounds() {
|
||||||
setBounds(Box(getTranslation() - extent, getTranslation() + extent));
|
setBounds(Box(getTranslation() - extent, getTranslation() + extent));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sphere::getNormal(MetavoxelInfo& info) const {
|
AttributeValue Sphere::getNormal(MetavoxelInfo& info) const {
|
||||||
glm::vec3 normal = info.getCenter() - getTranslation();
|
glm::vec3 normal = info.getCenter() - getTranslation();
|
||||||
float length = glm::length(normal);
|
float length = glm::length(normal);
|
||||||
QRgb color;
|
QRgb color;
|
||||||
|
@ -1379,7 +1432,7 @@ void Sphere::getNormal(MetavoxelInfo& info) const {
|
||||||
const QRgb DEFAULT_NORMAL = 0x007F00;
|
const QRgb DEFAULT_NORMAL = 0x007F00;
|
||||||
color = DEFAULT_NORMAL;
|
color = DEFAULT_NORMAL;
|
||||||
}
|
}
|
||||||
info.outputValues[1] = AttributeValue(getAttributes().at(1), encodeInline<QRgb>(color));
|
return AttributeValue(getAttributes().at(1), encodeInline<QRgb>(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticModel::StaticModel() {
|
StaticModel::StaticModel() {
|
||||||
|
|
|
@ -408,8 +408,9 @@ public:
|
||||||
class Spanner : public SharedObject {
|
class Spanner : public SharedObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(Box bounds MEMBER _bounds WRITE setBounds NOTIFY boundsChanged DESIGNABLE false)
|
Q_PROPERTY(Box bounds MEMBER _bounds WRITE setBounds NOTIFY boundsChanged DESIGNABLE false)
|
||||||
Q_PROPERTY(float granularity MEMBER _granularity DESIGNABLE false)
|
Q_PROPERTY(float placementGranularity MEMBER _placementGranularity DESIGNABLE false)
|
||||||
|
Q_PROPERTY(float voxelizationGranularity MEMBER _voxelizationGranularity DESIGNABLE false)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Increments the value of the global visit counter.
|
/// Increments the value of the global visit counter.
|
||||||
|
@ -420,16 +421,26 @@ public:
|
||||||
void setBounds(const Box& bounds);
|
void setBounds(const Box& bounds);
|
||||||
const Box& getBounds() const { return _bounds; }
|
const Box& getBounds() const { return _bounds; }
|
||||||
|
|
||||||
void setGranularity(float granularity) { _granularity = granularity; }
|
void setPlacementGranularity(float granularity) { _placementGranularity = granularity; }
|
||||||
float getGranularity() const { return _granularity; }
|
float getPlacementGranularity() const { return _placementGranularity; }
|
||||||
|
|
||||||
|
void setVoxelizationGranularity(float granularity) { _voxelizationGranularity = granularity; }
|
||||||
|
float getVoxelizationGranularity() const { return _voxelizationGranularity; }
|
||||||
|
|
||||||
/// Returns a reference to the list of attributes associated with this spanner.
|
/// Returns a reference to the list of attributes associated with this spanner.
|
||||||
virtual const QVector<AttributePointer>& getAttributes() const;
|
virtual const QVector<AttributePointer>& getAttributes() const;
|
||||||
|
|
||||||
|
/// Returns a reference to the list of corresponding attributes that we voxelize the spanner into.
|
||||||
|
virtual const QVector<AttributePointer>& getVoxelizedAttributes() const;
|
||||||
|
|
||||||
/// Sets the attribute values associated with this spanner in the supplied info.
|
/// Sets the attribute values associated with this spanner in the supplied info.
|
||||||
/// \return true to recurse, false to stop
|
/// \return true to recurse, false to stop
|
||||||
virtual bool getAttributeValues(MetavoxelInfo& info) const;
|
virtual bool getAttributeValues(MetavoxelInfo& info) const;
|
||||||
|
|
||||||
|
/// Blends the attribute values associated with this spanner into the supplied info.
|
||||||
|
/// \return true to recurse, false to stop
|
||||||
|
virtual bool blendAttributeValues(MetavoxelInfo& info) const;
|
||||||
|
|
||||||
/// Checks whether we've visited this object on the current traversal. If we have, returns false.
|
/// Checks whether we've visited this object on the current traversal. If we have, returns false.
|
||||||
/// If we haven't, sets the last visit identifier and returns true.
|
/// If we haven't, sets the last visit identifier and returns true.
|
||||||
bool testAndSetVisited();
|
bool testAndSetVisited();
|
||||||
|
@ -455,7 +466,8 @@ protected:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Box _bounds;
|
Box _bounds;
|
||||||
float _granularity;
|
float _placementGranularity;
|
||||||
|
float _voxelizationGranularity;
|
||||||
int _lastVisit; ///< the identifier of the last visit
|
int _lastVisit; ///< the identifier of the last visit
|
||||||
|
|
||||||
static int _visit; ///< the global visit counter
|
static int _visit; ///< the global visit counter
|
||||||
|
@ -521,7 +533,9 @@ public:
|
||||||
const QColor& getColor() const { return _color; }
|
const QColor& getColor() const { return _color; }
|
||||||
|
|
||||||
virtual const QVector<AttributePointer>& getAttributes() const;
|
virtual const QVector<AttributePointer>& getAttributes() const;
|
||||||
|
virtual const QVector<AttributePointer>& getVoxelizedAttributes() const;
|
||||||
virtual bool getAttributeValues(MetavoxelInfo& info) const;
|
virtual bool getAttributeValues(MetavoxelInfo& info) const;
|
||||||
|
virtual bool blendAttributeValues(MetavoxelInfo& info) const;
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -538,7 +552,7 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void getNormal(MetavoxelInfo& info) const;
|
AttributeValue getNormal(MetavoxelInfo& info) const;
|
||||||
|
|
||||||
QColor _color;
|
QColor _color;
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,8 +104,33 @@ InsertSpannerEdit::InsertSpannerEdit(const AttributePointer& attribute, const Sh
|
||||||
spanner(spanner) {
|
spanner(spanner) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SetSpannerEditVisitor : public MetavoxelVisitor {
|
||||||
|
public:
|
||||||
|
|
||||||
|
SetSpannerEditVisitor(const QVector<AttributePointer>& attributes, Spanner* spanner);
|
||||||
|
|
||||||
|
virtual int visit(MetavoxelInfo& info);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Spanner* _spanner;
|
||||||
|
};
|
||||||
|
|
||||||
|
SetSpannerEditVisitor::SetSpannerEditVisitor(const QVector<AttributePointer>& attributes, Spanner* spanner) :
|
||||||
|
MetavoxelVisitor(attributes, attributes),
|
||||||
|
_spanner(spanner) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetSpannerEditVisitor::visit(MetavoxelInfo& info) {
|
||||||
|
return _spanner->blendAttributeValues(info) ? DEFAULT_ORDER : STOP_RECURSION;
|
||||||
|
}
|
||||||
|
|
||||||
void InsertSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
void InsertSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
||||||
data.insert(attribute, spanner);
|
data.insert(attribute, this->spanner);
|
||||||
|
|
||||||
|
Spanner* spanner = static_cast<Spanner*>(this->spanner.data());
|
||||||
|
SetSpannerEditVisitor visitor(spanner->getVoxelizedAttributes(), spanner);
|
||||||
|
data.guide(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveSpannerEdit::RemoveSpannerEdit(const AttributePointer& attribute, int id) :
|
RemoveSpannerEdit::RemoveSpannerEdit(const AttributePointer& attribute, int id) :
|
||||||
|
@ -130,27 +155,6 @@ void ClearSpannersEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& o
|
||||||
data.clear(attribute);
|
data.clear(attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SetSpannerEditVisitor : public MetavoxelVisitor {
|
|
||||||
public:
|
|
||||||
|
|
||||||
SetSpannerEditVisitor(Spanner* spanner);
|
|
||||||
|
|
||||||
virtual int visit(MetavoxelInfo& info);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Spanner* _spanner;
|
|
||||||
};
|
|
||||||
|
|
||||||
SetSpannerEditVisitor::SetSpannerEditVisitor(Spanner* spanner) :
|
|
||||||
MetavoxelVisitor(spanner->getAttributes(), spanner->getAttributes()),
|
|
||||||
_spanner(spanner) {
|
|
||||||
}
|
|
||||||
|
|
||||||
int SetSpannerEditVisitor::visit(MetavoxelInfo& info) {
|
|
||||||
return _spanner->getAttributeValues(info) ? DEFAULT_ORDER : STOP_RECURSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSpannerEdit::SetSpannerEdit(const SharedObjectPointer& spanner) :
|
SetSpannerEdit::SetSpannerEdit(const SharedObjectPointer& spanner) :
|
||||||
spanner(spanner) {
|
spanner(spanner) {
|
||||||
}
|
}
|
||||||
|
@ -163,6 +167,6 @@ void SetSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& obje
|
||||||
data.expand();
|
data.expand();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetSpannerEditVisitor visitor(spanner);
|
SetSpannerEditVisitor visitor(spanner->getAttributes(), spanner);
|
||||||
data.guide(visitor);
|
data.guide(visitor);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue