mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 22:28:37 +02:00
More set/blend bits.
This commit is contained in:
parent
40844d2000
commit
3a44a846ed
6 changed files with 96 additions and 19 deletions
|
@ -144,6 +144,14 @@ void OwnedAttributeValue::mix(const AttributeValue& first, const AttributeValue&
|
||||||
_value = _attribute->mix(first.getValue(), second.getValue(), alpha);
|
_value = _attribute->mix(first.getValue(), second.getValue(), alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OwnedAttributeValue::blend(const AttributeValue& source, const AttributeValue& dest) {
|
||||||
|
if (_attribute) {
|
||||||
|
_attribute->destroy(_value);
|
||||||
|
}
|
||||||
|
_attribute = source.getAttribute();
|
||||||
|
_value = _attribute->blend(source.getValue(), dest.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
OwnedAttributeValue& OwnedAttributeValue::operator=(const AttributeValue& other) {
|
OwnedAttributeValue& OwnedAttributeValue::operator=(const AttributeValue& other) {
|
||||||
if (_attribute) {
|
if (_attribute) {
|
||||||
_attribute->destroy(_value);
|
_attribute->destroy(_value);
|
||||||
|
@ -243,6 +251,19 @@ void* QRgbAttribute::mix(void* first, void* second, float alpha) const {
|
||||||
glm::mix((float)qAlpha(firstValue), (float)qAlpha(secondValue), alpha)));
|
glm::mix((float)qAlpha(firstValue), (float)qAlpha(secondValue), alpha)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float EIGHT_BIT_MAXIMUM = 255.0f;
|
||||||
|
|
||||||
|
void* QRgbAttribute::blend(void* source, void* dest) const {
|
||||||
|
QRgb sourceValue = decodeInline<QRgb>(source);
|
||||||
|
QRgb destValue = decodeInline<QRgb>(dest);
|
||||||
|
float alpha = qAlpha(sourceValue) / EIGHT_BIT_MAXIMUM;
|
||||||
|
return encodeInline(qRgba(
|
||||||
|
glm::mix((float)qRed(destValue), (float)qRed(sourceValue), alpha),
|
||||||
|
glm::mix((float)qGreen(destValue), (float)qGreen(sourceValue), alpha),
|
||||||
|
glm::mix((float)qBlue(destValue), (float)qBlue(sourceValue), alpha),
|
||||||
|
glm::mix((float)qAlpha(destValue), (float)qAlpha(sourceValue), 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());
|
||||||
}
|
}
|
||||||
|
@ -287,6 +308,13 @@ void* PackedNormalAttribute::mix(void* first, void* second, float alpha) const {
|
||||||
return encodeInline(packNormal(glm::normalize(glm::mix(firstNormal, secondNormal, alpha))));
|
return encodeInline(packNormal(glm::normalize(glm::mix(firstNormal, secondNormal, alpha))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* PackedNormalAttribute::blend(void* source, void* dest) const {
|
||||||
|
QRgb sourceValue = decodeInline<QRgb>(source);
|
||||||
|
QRgb destValue = decodeInline<QRgb>(dest);
|
||||||
|
float alpha = qAlpha(sourceValue) / EIGHT_BIT_MAXIMUM;
|
||||||
|
return encodeInline(packNormal(glm::normalize(glm::mix(unpackNormal(destValue), unpackNormal(sourceValue), 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;
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,9 @@ public:
|
||||||
/// Sets this attribute to a mix of the first and second provided.
|
/// Sets this attribute to a mix of the first and second provided.
|
||||||
void mix(const AttributeValue& first, const AttributeValue& second, float alpha);
|
void mix(const AttributeValue& first, const AttributeValue& second, float alpha);
|
||||||
|
|
||||||
|
/// Sets this attribute to a blend of the source and destination.
|
||||||
|
void blend(const AttributeValue& source, const AttributeValue& dest);
|
||||||
|
|
||||||
/// 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);
|
||||||
|
|
||||||
|
@ -218,6 +221,9 @@ public:
|
||||||
/// Mixes the first and the second, returning a new value with the result.
|
/// 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* mix(void* first, void* second, float alpha) const = 0;
|
||||||
|
|
||||||
|
/// Blends the source with the destination, returning a new value with the result.
|
||||||
|
virtual void* blend(void* source, void* dest) 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(); }
|
||||||
|
@ -249,6 +255,8 @@ public:
|
||||||
|
|
||||||
virtual void* mix(void* first, void* second, float alpha) const { return create(alpha < 0.5f ? first : second); }
|
virtual void* mix(void* first, void* second, float alpha) const { return create(alpha < 0.5f ? first : second); }
|
||||||
|
|
||||||
|
virtual void* blend(void* source, void* dest) const { return create(source); }
|
||||||
|
|
||||||
virtual void* getDefaultValue() const { return encodeInline(_defaultValue); }
|
virtual void* getDefaultValue() const { return encodeInline(_defaultValue); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -315,6 +323,8 @@ public:
|
||||||
|
|
||||||
virtual void* mix(void* first, void* second, float alpha) const;
|
virtual void* mix(void* first, void* second, float alpha) const;
|
||||||
|
|
||||||
|
virtual void* blend(void* source, void* dest) 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;
|
||||||
|
@ -333,6 +343,8 @@ public:
|
||||||
virtual bool merge(void*& parent, void* children[], bool postRead = false) const;
|
virtual bool merge(void*& parent, void* children[], bool postRead = false) const;
|
||||||
|
|
||||||
virtual void* mix(void* first, void* second, float alpha) const;
|
virtual void* mix(void* first, void* second, float alpha) const;
|
||||||
|
|
||||||
|
virtual void* blend(void* source, void* dest) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Packs a normal into an RGB value.
|
/// Packs a normal into an RGB value.
|
||||||
|
|
|
@ -336,17 +336,41 @@ static glm::vec3 getNextMinimum(const glm::vec3& minimum, float nextSize, int in
|
||||||
(index & Z_MAXIMUM_FLAG) ? nextSize : 0.0f);
|
(index & Z_MAXIMUM_FLAG) ? nextSize : 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setNode(const AttributePointer& attribute, MetavoxelNode*& node, MetavoxelNode* other) {
|
static void setNode(const AttributeValue& value, MetavoxelNode*& node, MetavoxelNode* other, bool blend) {
|
||||||
if (node) {
|
if (!blend) {
|
||||||
node->decrementReferenceCount(attribute);
|
// if we're not blending, we can just make a shallow copy
|
||||||
|
if (node) {
|
||||||
|
node->decrementReferenceCount(value.getAttribute());
|
||||||
|
}
|
||||||
|
(node = other)->incrementReferenceCount();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
(node = other)->incrementReferenceCount();
|
if (node) {
|
||||||
|
MetavoxelNode* oldNode = node;
|
||||||
|
node = new MetavoxelNode(value.getAttribute(), oldNode);
|
||||||
|
oldNode->decrementReferenceCount(value.getAttribute());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
node = new MetavoxelNode(value);
|
||||||
|
}
|
||||||
|
OwnedAttributeValue oldValue = node->getAttributeValue(value.getAttribute());
|
||||||
|
node->blendAttributeValues(other->getAttributeValue(value.getAttribute()), oldValue);
|
||||||
|
if (other->isLeaf()) {
|
||||||
|
node->clearChildren(value.getAttribute());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) {
|
||||||
|
MetavoxelNode* child = node->getChild(i);
|
||||||
|
setNode(oldValue, child, other->getChild(i), true);
|
||||||
|
node->setChild(i, child);
|
||||||
|
}
|
||||||
|
node->mergeChildren(value.getAttribute());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setNode(const AttributeValue& value, MetavoxelNode*& node, const glm::vec3& minimum, float size,
|
static void setNode(const AttributeValue& value, MetavoxelNode*& node, const glm::vec3& minimum, float size,
|
||||||
MetavoxelNode* other, const glm::vec3& otherMinimum, float otherSize) {
|
MetavoxelNode* other, const glm::vec3& otherMinimum, float otherSize, bool blend) {
|
||||||
if (otherSize >= size) {
|
if (otherSize >= size) {
|
||||||
setNode(value.getAttribute(), node, other);
|
setNode(value, node, other, blend);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!node) {
|
if (!node) {
|
||||||
|
@ -372,21 +396,27 @@ static void setNode(const AttributeValue& value, MetavoxelNode*& node, const glm
|
||||||
}
|
}
|
||||||
MetavoxelNode* nextNode = node->getChild(index);
|
MetavoxelNode* nextNode = node->getChild(index);
|
||||||
setNode(node->getAttributeValue(value.getAttribute()), nextNode, getNextMinimum(minimum, nextSize, index),
|
setNode(node->getAttributeValue(value.getAttribute()), nextNode, getNextMinimum(minimum, nextSize, index),
|
||||||
nextSize, other, otherMinimum, otherSize);
|
nextSize, other, otherMinimum, otherSize, blend);
|
||||||
node->setChild(index, nextNode);
|
node->setChild(index, nextNode);
|
||||||
|
node->mergeChildren(value.getAttribute());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelData::set(const glm::vec3& minimum, const MetavoxelData& data) {
|
void MetavoxelData::set(const glm::vec3& minimum, const MetavoxelData& data, bool blend) {
|
||||||
// expand to fit the entire data
|
// expand to fit the entire data
|
||||||
Box bounds = minimum + glm::vec3(data.getSize(), data.getSize(), data.getSize());
|
Box bounds = minimum + glm::vec3(data.getSize(), data.getSize(), data.getSize());
|
||||||
while (!getBounds().contains(bounds)) {
|
while (!getBounds().contains(bounds)) {
|
||||||
expand();
|
expand();
|
||||||
}
|
}
|
||||||
|
|
||||||
// set each attribute separately
|
// set/mix each attribute separately
|
||||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = data._roots.constBegin();
|
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = data._roots.constBegin();
|
||||||
it != data._roots.constEnd(); it++) {
|
it != data._roots.constEnd(); it++) {
|
||||||
setNode(it.key(), _roots[it.key()], getMinimum(), getSize(), it.value(), minimum, data.getSize());
|
MetavoxelNode*& root = _roots[it.key()];
|
||||||
|
setNode(it.key(), root, getMinimum(), getSize(), it.value(), minimum, data.getSize(), blend);
|
||||||
|
if (root->isLeaf() && root->getAttributeValue(it.key()).isDefault()) {
|
||||||
|
_roots.remove(it.key());
|
||||||
|
root->decrementReferenceCount(it.key());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,7 +689,11 @@ MetavoxelNode::MetavoxelNode(const AttributePointer& attribute, const MetavoxelN
|
||||||
void MetavoxelNode::setAttributeValue(const AttributeValue& attributeValue) {
|
void MetavoxelNode::setAttributeValue(const AttributeValue& attributeValue) {
|
||||||
attributeValue.getAttribute()->destroy(_attributeValue);
|
attributeValue.getAttribute()->destroy(_attributeValue);
|
||||||
_attributeValue = attributeValue.copy();
|
_attributeValue = attributeValue.copy();
|
||||||
clearChildren(attributeValue.getAttribute());
|
}
|
||||||
|
|
||||||
|
void MetavoxelNode::blendAttributeValues(const AttributeValue& source, const AttributeValue& dest) {
|
||||||
|
source.getAttribute()->destroy(_attributeValue);
|
||||||
|
_attributeValue = source.getAttribute()->blend(source.getValue(), dest.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeValue MetavoxelNode::getAttributeValue(const AttributePointer& attribute) const {
|
AttributeValue MetavoxelNode::getAttributeValue(const AttributePointer& attribute) const {
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
const AttributePointer& attribute, float& distance, const MetavoxelLOD& lod = MetavoxelLOD());
|
const AttributePointer& attribute, float& distance, const MetavoxelLOD& lod = MetavoxelLOD());
|
||||||
|
|
||||||
/// Sets part of the data.
|
/// Sets part of the data.
|
||||||
void set(const glm::vec3& minimum, const MetavoxelData& data);
|
void set(const glm::vec3& minimum, const MetavoxelData& data, bool blend = false);
|
||||||
|
|
||||||
/// Expands the tree, increasing its capacity in all dimensions.
|
/// Expands the tree, increasing its capacity in all dimensions.
|
||||||
void expand();
|
void expand();
|
||||||
|
@ -158,6 +158,8 @@ public:
|
||||||
|
|
||||||
void setAttributeValue(const AttributeValue& attributeValue);
|
void setAttributeValue(const AttributeValue& attributeValue);
|
||||||
|
|
||||||
|
void blendAttributeValues(const AttributeValue& source, const AttributeValue& dest);
|
||||||
|
|
||||||
AttributeValue getAttributeValue(const AttributePointer& attribute) const;
|
AttributeValue getAttributeValue(const AttributePointer& attribute) const;
|
||||||
void* getAttributeValue() const { return _attributeValue; }
|
void* getAttributeValue() const { return _attributeValue; }
|
||||||
|
|
||||||
|
@ -190,13 +192,13 @@ public:
|
||||||
|
|
||||||
void destroy(const AttributePointer& attribute);
|
void destroy(const AttributePointer& attribute);
|
||||||
|
|
||||||
|
void clearChildren(const AttributePointer& attribute);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(MetavoxelNode)
|
Q_DISABLE_COPY(MetavoxelNode)
|
||||||
|
|
||||||
friend class MetavoxelVisitation;
|
friend class MetavoxelVisitation;
|
||||||
|
|
||||||
void clearChildren(const AttributePointer& attribute);
|
|
||||||
|
|
||||||
int _referenceCount;
|
int _referenceCount;
|
||||||
void* _attributeValue;
|
void* _attributeValue;
|
||||||
MetavoxelNode* _children[CHILD_COUNT];
|
MetavoxelNode* _children[CHILD_COUNT];
|
||||||
|
|
|
@ -306,11 +306,12 @@ void SetSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& obje
|
||||||
setIntersectingMasked(spanner->getBounds(), data);
|
setIntersectingMasked(spanner->getBounds(), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDataEdit::SetDataEdit(const glm::vec3& minimum, const MetavoxelData& data) :
|
SetDataEdit::SetDataEdit(const glm::vec3& minimum, const MetavoxelData& data, bool blend) :
|
||||||
minimum(minimum),
|
minimum(minimum),
|
||||||
data(data) {
|
data(data),
|
||||||
|
blend(blend) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDataEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
void SetDataEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
||||||
data.set(minimum, this->data);
|
data.set(minimum, this->data, blend);
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,10 +183,10 @@ class SetDataEdit : public MetavoxelEdit {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
STREAM glm::vec3 minimum;
|
STREAM glm::vec3 minimum;
|
||||||
|
|
||||||
STREAM MetavoxelData data;
|
STREAM MetavoxelData data;
|
||||||
|
STREAM bool blend;
|
||||||
|
|
||||||
SetDataEdit(const glm::vec3& minimum = glm::vec3(), const MetavoxelData& data = MetavoxelData());
|
SetDataEdit(const glm::vec3& minimum = glm::vec3(), const MetavoxelData& data = MetavoxelData(), bool blend = false);
|
||||||
|
|
||||||
virtual void apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const;
|
virtual void apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue