mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-08 22:07:35 +02:00
Finally at the point of actually getting spanners to turn into voxels.
This commit is contained in:
parent
78896d6af9
commit
176d8f746e
6 changed files with 153 additions and 55 deletions
|
@ -188,7 +188,7 @@ 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 (info.inputValues.at(4).getAttribute()) {
|
if (!info.isLODLeaf) {
|
||||||
if (alpha > 0) {
|
if (alpha > 0) {
|
||||||
Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size),
|
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(color)), quint8(qGreen(color)), quint8(qBlue(color)), alpha },
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
REGISTER_META_OBJECT(QRgbAttribute)
|
REGISTER_META_OBJECT(QRgbAttribute)
|
||||||
REGISTER_META_OBJECT(PackedNormalAttribute)
|
REGISTER_META_OBJECT(PackedNormalAttribute)
|
||||||
|
REGISTER_META_OBJECT(SpannerQRgbAttribute)
|
||||||
|
REGISTER_META_OBJECT(SpannerPackedNormalAttribute)
|
||||||
REGISTER_META_OBJECT(SharedObjectAttribute)
|
REGISTER_META_OBJECT(SharedObjectAttribute)
|
||||||
REGISTER_META_OBJECT(SharedObjectSetAttribute)
|
REGISTER_META_OBJECT(SharedObjectSetAttribute)
|
||||||
REGISTER_META_OBJECT(SpannerSetAttribute)
|
REGISTER_META_OBJECT(SpannerSetAttribute)
|
||||||
|
@ -35,7 +37,7 @@ AttributeRegistry::AttributeRegistry() :
|
||||||
_spannerNormalAttribute(registerAttribute(new SpannerPackedNormalAttribute("spannerNormal"))) {
|
_spannerNormalAttribute(registerAttribute(new SpannerPackedNormalAttribute("spannerNormal"))) {
|
||||||
|
|
||||||
// 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 = 8.0f;
|
||||||
_spannersAttribute->setLODThresholdMultiplier(SPANNER_LOD_THRESHOLD_MULTIPLIER);
|
_spannersAttribute->setLODThresholdMultiplier(SPANNER_LOD_THRESHOLD_MULTIPLIER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +170,10 @@ Attribute::Attribute(const QString& name) :
|
||||||
Attribute::~Attribute() {
|
Attribute::~Attribute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetavoxelNode* Attribute::createMetavoxelNode(const AttributeValue& value, const MetavoxelNode* original) const {
|
||||||
|
return new MetavoxelNode(value);
|
||||||
|
}
|
||||||
|
|
||||||
void Attribute::readMetavoxelRoot(MetavoxelData& data, MetavoxelStreamState& state) {
|
void Attribute::readMetavoxelRoot(MetavoxelData& data, MetavoxelStreamState& state) {
|
||||||
data.createRoot(state.attribute)->read(state);
|
data.createRoot(state.attribute)->read(state);
|
||||||
}
|
}
|
||||||
|
@ -257,7 +263,7 @@ 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]);
|
||||||
glm::vec3 total = unpackNormal(firstValue);
|
glm::vec3 total = unpackNormal(firstValue) * (float)qAlpha(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]);
|
||||||
|
@ -290,46 +296,62 @@ SpannerQRgbAttribute::SpannerQRgbAttribute(const QString& name, QRgb defaultValu
|
||||||
QRgbAttribute(name, defaultValue) {
|
QRgbAttribute(name, defaultValue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpannerQRgbAttribute::read(Bitstream& in, void*& value, bool isLeaf) const {
|
||||||
|
value = getDefaultValue();
|
||||||
|
in.read(&value, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpannerQRgbAttribute::write(Bitstream& out, void* value, bool isLeaf) const {
|
||||||
|
out.write(&value, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetavoxelNode* SpannerQRgbAttribute::createMetavoxelNode(
|
||||||
|
const AttributeValue& value, const MetavoxelNode* original) const {
|
||||||
|
return new MetavoxelNode(value, original);
|
||||||
|
}
|
||||||
|
|
||||||
bool SpannerQRgbAttribute::merge(void*& parent, void* children[]) const {
|
bool SpannerQRgbAttribute::merge(void*& parent, void* children[]) const {
|
||||||
QRgb firstValue = decodeInline<QRgb>(children[0]);
|
for (int i = 0; i < MERGE_COUNT; i++) {
|
||||||
int totalAlpha = qAlpha(firstValue);
|
if (qAlpha(decodeInline<QRgb>(children[i])) != 0) {
|
||||||
int totalRed = qRed(firstValue) * totalAlpha;
|
return false;
|
||||||
int totalGreen = qGreen(firstValue) * totalAlpha;
|
}
|
||||||
int totalBlue = qBlue(firstValue) * totalAlpha;
|
|
||||||
bool allChildrenEqual = true;
|
|
||||||
for (int i = 1; i < Attribute::MERGE_COUNT; i++) {
|
|
||||||
QRgb value = decodeInline<QRgb>(children[i]);
|
|
||||||
int alpha = qAlpha(value);
|
|
||||||
totalRed += qRed(value) * alpha;
|
|
||||||
totalGreen += qGreen(value) * alpha;
|
|
||||||
totalBlue += qBlue(value) * alpha;
|
|
||||||
totalAlpha += alpha;
|
|
||||||
allChildrenEqual &= (firstValue == value);
|
|
||||||
}
|
}
|
||||||
if (totalAlpha == 0) {
|
return true;
|
||||||
parent = encodeInline(QRgb());
|
|
||||||
} else {
|
|
||||||
parent = encodeInline(qRgba(totalRed / totalAlpha, totalGreen / totalAlpha,
|
|
||||||
totalBlue / totalAlpha, totalAlpha / MERGE_COUNT));
|
|
||||||
}
|
|
||||||
return allChildrenEqual;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttributeValue SpannerQRgbAttribute::inherit(const AttributeValue& parentValue) const {
|
||||||
|
return AttributeValue(parentValue.getAttribute());
|
||||||
|
}
|
||||||
|
|
||||||
SpannerPackedNormalAttribute::SpannerPackedNormalAttribute(const QString& name, QRgb defaultValue) :
|
SpannerPackedNormalAttribute::SpannerPackedNormalAttribute(const QString& name, QRgb defaultValue) :
|
||||||
PackedNormalAttribute(name, defaultValue) {
|
PackedNormalAttribute(name, defaultValue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpannerPackedNormalAttribute::read(Bitstream& in, void*& value, bool isLeaf) const {
|
||||||
|
value = getDefaultValue();
|
||||||
|
in.read(&value, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpannerPackedNormalAttribute::write(Bitstream& out, void* value, bool isLeaf) const {
|
||||||
|
out.write(&value, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetavoxelNode* SpannerPackedNormalAttribute::createMetavoxelNode(
|
||||||
|
const AttributeValue& value, const MetavoxelNode* original) const {
|
||||||
|
return new MetavoxelNode(value, original);
|
||||||
|
}
|
||||||
|
|
||||||
bool SpannerPackedNormalAttribute::merge(void*& parent, void* children[]) const {
|
bool SpannerPackedNormalAttribute::merge(void*& parent, void* children[]) const {
|
||||||
QRgb firstValue = decodeInline<QRgb>(children[0]);
|
for (int i = 0; i < MERGE_COUNT; i++) {
|
||||||
glm::vec3 total = unpackNormal(firstValue);
|
if (qAlpha(decodeInline<QRgb>(children[i])) != 0) {
|
||||||
bool allChildrenEqual = true;
|
return false;
|
||||||
for (int i = 1; i < Attribute::MERGE_COUNT; i++) {
|
}
|
||||||
QRgb value = decodeInline<QRgb>(children[i]);
|
|
||||||
total += unpackNormal(value) * (float)qAlpha(value);
|
|
||||||
allChildrenEqual &= (firstValue == value);
|
|
||||||
}
|
}
|
||||||
parent = encodeInline(packNormal(glm::normalize(total)));
|
return true;
|
||||||
return allChildrenEqual;
|
}
|
||||||
|
|
||||||
|
AttributeValue SpannerPackedNormalAttribute::inherit(const AttributeValue& parentValue) const {
|
||||||
|
return AttributeValue(parentValue.getAttribute());
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject,
|
SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject,
|
||||||
|
@ -386,6 +408,11 @@ void SharedObjectSetAttribute::write(Bitstream& out, void* value, bool isLeaf) c
|
||||||
out << decodeInline<SharedObjectSet>(value);
|
out << decodeInline<SharedObjectSet>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetavoxelNode* SharedObjectSetAttribute::createMetavoxelNode(
|
||||||
|
const AttributeValue& value, const MetavoxelNode* original) const {
|
||||||
|
return new MetavoxelNode(value, original);
|
||||||
|
}
|
||||||
|
|
||||||
bool SharedObjectSetAttribute::merge(void*& parent, void* children[]) const {
|
bool SharedObjectSetAttribute::merge(void*& parent, void* children[]) const {
|
||||||
for (int i = 0; i < MERGE_COUNT; i++) {
|
for (int i = 0; i < MERGE_COUNT; i++) {
|
||||||
if (!decodeInline<SharedObjectSet>(children[i]).isEmpty()) {
|
if (!decodeInline<SharedObjectSet>(children[i]).isEmpty()) {
|
||||||
|
@ -395,6 +422,10 @@ bool SharedObjectSetAttribute::merge(void*& parent, void* children[]) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttributeValue SharedObjectSetAttribute::inherit(const AttributeValue& parentValue) const {
|
||||||
|
return AttributeValue(parentValue.getAttribute());
|
||||||
|
}
|
||||||
|
|
||||||
QWidget* SharedObjectSetAttribute::createEditor(QWidget* parent) const {
|
QWidget* SharedObjectSetAttribute::createEditor(QWidget* parent) const {
|
||||||
return new SharedObjectEditor(_metaObject, parent);
|
return new SharedObjectEditor(_metaObject, parent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,8 @@ public:
|
||||||
virtual void readDelta(Bitstream& in, void*& value, void* reference, bool isLeaf) const { read(in, value, isLeaf); }
|
virtual void readDelta(Bitstream& in, void*& value, void* reference, bool isLeaf) const { read(in, value, isLeaf); }
|
||||||
virtual void writeDelta(Bitstream& out, void* value, void* reference, bool isLeaf) const { write(out, value, isLeaf); }
|
virtual void writeDelta(Bitstream& out, void* value, void* reference, bool isLeaf) const { write(out, value, isLeaf); }
|
||||||
|
|
||||||
|
virtual MetavoxelNode* createMetavoxelNode(const AttributeValue& value, const MetavoxelNode* original) const;
|
||||||
|
|
||||||
virtual void readMetavoxelRoot(MetavoxelData& data, MetavoxelStreamState& state);
|
virtual void readMetavoxelRoot(MetavoxelData& data, MetavoxelStreamState& state);
|
||||||
virtual void writeMetavoxelRoot(const MetavoxelNode& root, MetavoxelStreamState& state);
|
virtual void writeMetavoxelRoot(const MetavoxelNode& root, MetavoxelStreamState& state);
|
||||||
|
|
||||||
|
@ -206,6 +208,9 @@ 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;
|
||||||
|
|
||||||
|
/// Given the parent value, returns the value that children should inherit (either the parent value or the default).
|
||||||
|
virtual AttributeValue inherit(const AttributeValue& parentValue) const { return parentValue; }
|
||||||
|
|
||||||
/// 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;
|
||||||
|
|
||||||
|
@ -307,7 +312,14 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE SpannerQRgbAttribute(const QString& name = QString(), QRgb defaultValue = QRgb());
|
Q_INVOKABLE SpannerQRgbAttribute(const QString& name = QString(), QRgb defaultValue = QRgb());
|
||||||
|
|
||||||
|
virtual void read(Bitstream& in, void*& value, bool isLeaf) const;
|
||||||
|
virtual void write(Bitstream& out, void* value, bool isLeaf) const;
|
||||||
|
|
||||||
|
virtual MetavoxelNode* createMetavoxelNode(const AttributeValue& value, const MetavoxelNode* original) const;
|
||||||
|
|
||||||
virtual bool merge(void*& parent, void* children[]) const;
|
virtual bool merge(void*& parent, void* children[]) const;
|
||||||
|
|
||||||
|
virtual AttributeValue inherit(const AttributeValue& parentValue) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Packed normals for voxelized spanners.
|
/// Packed normals for voxelized spanners.
|
||||||
|
@ -318,7 +330,14 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE SpannerPackedNormalAttribute(const QString& name = QString(), QRgb defaultValue = QRgb());
|
Q_INVOKABLE SpannerPackedNormalAttribute(const QString& name = QString(), QRgb defaultValue = QRgb());
|
||||||
|
|
||||||
|
virtual void read(Bitstream& in, void*& value, bool isLeaf) const;
|
||||||
|
virtual void write(Bitstream& out, void* value, bool isLeaf) const;
|
||||||
|
|
||||||
|
virtual MetavoxelNode* createMetavoxelNode(const AttributeValue& value, const MetavoxelNode* original) const;
|
||||||
|
|
||||||
virtual bool merge(void*& parent, void* children[]) const;
|
virtual bool merge(void*& parent, void* children[]) const;
|
||||||
|
|
||||||
|
virtual AttributeValue inherit(const AttributeValue& parentValue) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An attribute that takes the form of QObjects of a given meta-type (a subclass of SharedObject).
|
/// An attribute that takes the form of QObjects of a given meta-type (a subclass of SharedObject).
|
||||||
|
@ -361,8 +380,12 @@ public:
|
||||||
virtual void read(Bitstream& in, void*& value, bool isLeaf) const;
|
virtual void read(Bitstream& in, void*& value, bool isLeaf) const;
|
||||||
virtual void write(Bitstream& out, void* value, bool isLeaf) const;
|
virtual void write(Bitstream& out, void* value, bool isLeaf) const;
|
||||||
|
|
||||||
|
virtual MetavoxelNode* createMetavoxelNode(const AttributeValue& value, const MetavoxelNode* original) const;
|
||||||
|
|
||||||
virtual bool merge(void*& parent, void* children[]) const;
|
virtual bool merge(void*& parent, void* children[]) const;
|
||||||
|
|
||||||
|
virtual AttributeValue inherit(const AttributeValue& parentValue) const;
|
||||||
|
|
||||||
virtual QWidget* createEditor(QWidget* parent = NULL) const;
|
virtual QWidget* createEditor(QWidget* parent = NULL) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -485,14 +485,26 @@ void MetavoxelStreamState::setMinimum(const glm::vec3& lastMinimum, int index) {
|
||||||
minimum = getNextMinimum(lastMinimum, size, index);
|
minimum = getNextMinimum(lastMinimum, size, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelNode::MetavoxelNode(const AttributeValue& attributeValue) : _referenceCount(1) {
|
MetavoxelNode::MetavoxelNode(const AttributeValue& attributeValue, const MetavoxelNode* copyChildren) :
|
||||||
|
_referenceCount(1) {
|
||||||
|
|
||||||
_attributeValue = attributeValue.copy();
|
_attributeValue = attributeValue.copy();
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
if (copyChildren) {
|
||||||
_children[i] = NULL;
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
if ((_children[i] = copyChildren->_children[i])) {
|
||||||
|
_children[i]->incrementReferenceCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
_children[i] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelNode::MetavoxelNode(const AttributePointer& attribute, const MetavoxelNode* copy) : _referenceCount(1) {
|
MetavoxelNode::MetavoxelNode(const AttributePointer& attribute, const MetavoxelNode* copy) :
|
||||||
|
_referenceCount(1) {
|
||||||
|
|
||||||
_attributeValue = attribute->create(copy->_attributeValue);
|
_attributeValue = attribute->create(copy->_attributeValue);
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
if ((_children[i] = copy->_children[i])) {
|
if ((_children[i] = copy->_children[i])) {
|
||||||
|
@ -969,7 +981,7 @@ bool DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
// "set" to same value; disregard
|
// "set" to same value; disregard
|
||||||
value = AttributeValue();
|
value = AttributeValue();
|
||||||
} else {
|
} else {
|
||||||
node = new MetavoxelNode(value);
|
node = value.getAttribute()->createMetavoxelNode(value, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (encodedOrder == MetavoxelVisitor::STOP_RECURSION) {
|
if (encodedOrder == MetavoxelVisitor::STOP_RECURSION) {
|
||||||
|
@ -991,7 +1003,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.getAttribute()->inherit(parentValue);
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
@ -1019,7 +1031,7 @@ bool DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
node = new MetavoxelNode(value.getAttribute(), node);
|
node = new MetavoxelNode(value.getAttribute(), node);
|
||||||
} else {
|
} else {
|
||||||
// create leaf with inherited value
|
// create leaf with inherited value
|
||||||
node = new MetavoxelNode(visitation.getInheritedOutputValue(j));
|
node = new MetavoxelNode(value.getAttribute()->inherit(visitation.getInheritedOutputValue(j)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MetavoxelNode* node = visitation.outputNodes.at(j);
|
MetavoxelNode* node = visitation.outputNodes.at(j);
|
||||||
|
@ -1028,7 +1040,7 @@ bool DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
child->decrementReferenceCount(value.getAttribute());
|
child->decrementReferenceCount(value.getAttribute());
|
||||||
} else {
|
} else {
|
||||||
// it's a leaf; we need to split it up
|
// it's a leaf; we need to split it up
|
||||||
AttributeValue nodeValue = node->getAttributeValue(value.getAttribute());
|
AttributeValue nodeValue = value.getAttribute()->inherit(node->getAttributeValue(value.getAttribute()));
|
||||||
for (int k = 1; k < MetavoxelNode::CHILD_COUNT; k++) {
|
for (int k = 1; k < MetavoxelNode::CHILD_COUNT; k++) {
|
||||||
node->setChild((index + k) % MetavoxelNode::CHILD_COUNT, new MetavoxelNode(nodeValue));
|
node->setChild((index + k) % MetavoxelNode::CHILD_COUNT, new MetavoxelNode(nodeValue));
|
||||||
}
|
}
|
||||||
|
@ -1234,7 +1246,7 @@ bool Spanner::getAttributeValues(MetavoxelInfo& info) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Spanner::blendAttributeValues(MetavoxelInfo& info) const {
|
bool Spanner::blendAttributeValues(MetavoxelInfo& info, bool force) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1369,10 +1381,10 @@ bool Sphere::getAttributeValues(MetavoxelInfo& info) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sphere::blendAttributeValues(MetavoxelInfo& info) const {
|
bool Sphere::blendAttributeValues(MetavoxelInfo& info, bool force) const {
|
||||||
// bounds check
|
// bounds check
|
||||||
Box bounds = info.getBounds();
|
Box bounds = info.getBounds();
|
||||||
if (!getBounds().intersects(bounds)) {
|
if (!(force || getBounds().intersects(bounds))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// count the points inside the sphere
|
// count the points inside the sphere
|
||||||
|
@ -1388,7 +1400,7 @@ bool Sphere::blendAttributeValues(MetavoxelInfo& info) const {
|
||||||
info.outputValues[1] = getNormal(info);
|
info.outputValues[1] = getNormal(info);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (info.size <= getVoxelizationGranularity()) {
|
if (force || info.size <= getVoxelizationGranularity()) {
|
||||||
// best guess
|
// best guess
|
||||||
if (pointsWithin > 0) {
|
if (pointsWithin > 0) {
|
||||||
int oldAlpha = qAlpha(info.inputValues.at(0).getInlineValue<QRgb>());
|
int oldAlpha = qAlpha(info.inputValues.at(0).getInlineValue<QRgb>());
|
||||||
|
|
|
@ -132,7 +132,7 @@ public:
|
||||||
|
|
||||||
static const int CHILD_COUNT = 8;
|
static const int CHILD_COUNT = 8;
|
||||||
|
|
||||||
MetavoxelNode(const AttributeValue& attributeValue);
|
MetavoxelNode(const AttributeValue& attributeValue, const MetavoxelNode* copyChildren = NULL);
|
||||||
MetavoxelNode(const AttributePointer& attribute, const MetavoxelNode* copy);
|
MetavoxelNode(const AttributePointer& attribute, const MetavoxelNode* copy);
|
||||||
|
|
||||||
void setAttributeValue(const AttributeValue& attributeValue);
|
void setAttributeValue(const AttributeValue& attributeValue);
|
||||||
|
@ -439,8 +439,9 @@ public:
|
||||||
virtual bool getAttributeValues(MetavoxelInfo& info) const;
|
virtual bool getAttributeValues(MetavoxelInfo& info) const;
|
||||||
|
|
||||||
/// Blends the attribute values associated with this spanner into the supplied info.
|
/// Blends the attribute values associated with this spanner into the supplied info.
|
||||||
|
/// \param force if true, blend even if we would normally subdivide
|
||||||
/// \return true to recurse, false to stop
|
/// \return true to recurse, false to stop
|
||||||
virtual bool blendAttributeValues(MetavoxelInfo& info) const;
|
virtual bool blendAttributeValues(MetavoxelInfo& info, bool force = false) 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.
|
||||||
|
@ -536,7 +537,7 @@ public:
|
||||||
virtual const QVector<AttributePointer>& getAttributes() const;
|
virtual const QVector<AttributePointer>& getAttributes() const;
|
||||||
virtual const QVector<AttributePointer>& getVoxelizedAttributes() 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 blendAttributeValues(MetavoxelInfo& info, bool force = false) 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:
|
||||||
|
|
|
@ -104,32 +104,42 @@ InsertSpannerEdit::InsertSpannerEdit(const AttributePointer& attribute, const Sh
|
||||||
spanner(spanner) {
|
spanner(spanner) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class SetSpannerEditVisitor : public MetavoxelVisitor {
|
class InsertSpannerEditVisitor : public MetavoxelVisitor {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SetSpannerEditVisitor(const QVector<AttributePointer>& attributes, Spanner* spanner);
|
InsertSpannerEditVisitor(const QVector<AttributePointer>& attributes, Spanner* spanner);
|
||||||
|
|
||||||
virtual int visit(MetavoxelInfo& info);
|
virtual int visit(MetavoxelInfo& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Spanner* _spanner;
|
Spanner* _spanner;
|
||||||
|
float _longestSide;
|
||||||
};
|
};
|
||||||
|
|
||||||
SetSpannerEditVisitor::SetSpannerEditVisitor(const QVector<AttributePointer>& attributes, Spanner* spanner) :
|
InsertSpannerEditVisitor::InsertSpannerEditVisitor(const QVector<AttributePointer>& attributes, Spanner* spanner) :
|
||||||
MetavoxelVisitor(attributes, attributes),
|
MetavoxelVisitor(attributes, attributes),
|
||||||
_spanner(spanner) {
|
_spanner(spanner),
|
||||||
|
_longestSide(qMax(spanner->getBounds().getLongestSide(), spanner->getPlacementGranularity()) * 2.0f /
|
||||||
|
AttributeRegistry::getInstance()->getSpannersAttribute()->getLODThresholdMultiplier()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int SetSpannerEditVisitor::visit(MetavoxelInfo& info) {
|
int InsertSpannerEditVisitor::visit(MetavoxelInfo& info) {
|
||||||
return _spanner->blendAttributeValues(info) ? DEFAULT_ORDER : STOP_RECURSION;
|
if (!info.getBounds().intersects(_spanner->getBounds())) {
|
||||||
|
return STOP_RECURSION;
|
||||||
|
}
|
||||||
|
if (info.size > _longestSide) {
|
||||||
|
return DEFAULT_ORDER;
|
||||||
|
}
|
||||||
|
_spanner->blendAttributeValues(info, true);
|
||||||
|
return STOP_RECURSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
void InsertSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
||||||
data.insert(attribute, this->spanner);
|
data.insert(attribute, this->spanner);
|
||||||
|
|
||||||
Spanner* spanner = static_cast<Spanner*>(this->spanner.data());
|
Spanner* spanner = static_cast<Spanner*>(this->spanner.data());
|
||||||
SetSpannerEditVisitor visitor(spanner->getVoxelizedAttributes(), spanner);
|
InsertSpannerEditVisitor visitor(spanner->getVoxelizedAttributes(), spanner);
|
||||||
data.guide(visitor);
|
data.guide(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +169,27 @@ SetSpannerEdit::SetSpannerEdit(const SharedObjectPointer& spanner) :
|
||||||
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 SetSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
void SetSpannerEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
||||||
Spanner* spanner = static_cast<Spanner*>(this->spanner.data());
|
Spanner* spanner = static_cast<Spanner*>(this->spanner.data());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue