mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +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);
|
||||
}
|
||||
|
||||
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) {
|
||||
if (_attribute) {
|
||||
_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)));
|
||||
}
|
||||
|
||||
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 {
|
||||
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))));
|
||||
}
|
||||
|
||||
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 INVERSE_CHAR_SCALE = 1.0f / CHAR_SCALE;
|
||||
|
||||
|
|
|
@ -158,6 +158,9 @@ public:
|
|||
/// Sets this attribute to a mix of the first and second provided.
|
||||
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.
|
||||
OwnedAttributeValue& operator=(const AttributeValue& other);
|
||||
|
||||
|
@ -218,6 +221,9 @@ public:
|
|||
/// Mixes the first and the second, returning a new value with the result.
|
||||
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* 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* blend(void* source, void* dest) const { return create(source); }
|
||||
|
||||
virtual void* getDefaultValue() const { return encodeInline(_defaultValue); }
|
||||
|
||||
protected:
|
||||
|
@ -315,6 +323,8 @@ public:
|
|||
|
||||
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* createFromVariant(const QVariant& value) const;
|
||||
|
@ -333,6 +343,8 @@ public:
|
|||
virtual bool merge(void*& parent, void* children[], bool postRead = false) 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.
|
||||
|
|
|
@ -336,17 +336,41 @@ static glm::vec3 getNextMinimum(const glm::vec3& minimum, float nextSize, int in
|
|||
(index & Z_MAXIMUM_FLAG) ? nextSize : 0.0f);
|
||||
}
|
||||
|
||||
static void setNode(const AttributePointer& attribute, MetavoxelNode*& node, MetavoxelNode* other) {
|
||||
if (node) {
|
||||
node->decrementReferenceCount(attribute);
|
||||
static void setNode(const AttributeValue& value, MetavoxelNode*& node, MetavoxelNode* other, bool blend) {
|
||||
if (!blend) {
|
||||
// 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,
|
||||
MetavoxelNode* other, const glm::vec3& otherMinimum, float otherSize) {
|
||||
MetavoxelNode* other, const glm::vec3& otherMinimum, float otherSize, bool blend) {
|
||||
if (otherSize >= size) {
|
||||
setNode(value.getAttribute(), node, other);
|
||||
setNode(value, node, other, blend);
|
||||
return;
|
||||
}
|
||||
if (!node) {
|
||||
|
@ -372,21 +396,27 @@ static void setNode(const AttributeValue& value, MetavoxelNode*& node, const glm
|
|||
}
|
||||
MetavoxelNode* nextNode = node->getChild(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->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
|
||||
Box bounds = minimum + glm::vec3(data.getSize(), data.getSize(), data.getSize());
|
||||
while (!getBounds().contains(bounds)) {
|
||||
expand();
|
||||
}
|
||||
|
||||
// set each attribute separately
|
||||
// set/mix each attribute separately
|
||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = data._roots.constBegin();
|
||||
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) {
|
||||
attributeValue.getAttribute()->destroy(_attributeValue);
|
||||
_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 {
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
const AttributePointer& attribute, float& distance, const MetavoxelLOD& lod = MetavoxelLOD());
|
||||
|
||||
/// 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.
|
||||
void expand();
|
||||
|
@ -158,6 +158,8 @@ public:
|
|||
|
||||
void setAttributeValue(const AttributeValue& attributeValue);
|
||||
|
||||
void blendAttributeValues(const AttributeValue& source, const AttributeValue& dest);
|
||||
|
||||
AttributeValue getAttributeValue(const AttributePointer& attribute) const;
|
||||
void* getAttributeValue() const { return _attributeValue; }
|
||||
|
||||
|
@ -190,13 +192,13 @@ public:
|
|||
|
||||
void destroy(const AttributePointer& attribute);
|
||||
|
||||
void clearChildren(const AttributePointer& attribute);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(MetavoxelNode)
|
||||
|
||||
friend class MetavoxelVisitation;
|
||||
|
||||
void clearChildren(const AttributePointer& attribute);
|
||||
|
||||
int _referenceCount;
|
||||
void* _attributeValue;
|
||||
MetavoxelNode* _children[CHILD_COUNT];
|
||||
|
|
|
@ -306,11 +306,12 @@ void SetSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& obje
|
|||
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),
|
||||
data(data) {
|
||||
data(data),
|
||||
blend(blend) {
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
STREAM glm::vec3 minimum;
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue