mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 13:33:38 +02:00
Working on subdivision.
This commit is contained in:
parent
63b4a2453b
commit
c4f29005a0
4 changed files with 159 additions and 15 deletions
|
@ -165,6 +165,14 @@ void Attribute::writeDelta(const MetavoxelNode& root, const MetavoxelNode& refer
|
|||
root.writeDelta(reference, state);
|
||||
}
|
||||
|
||||
void Attribute::readSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
|
||||
data.getRoot(state.attribute)->readSubdivision(state);
|
||||
}
|
||||
|
||||
void Attribute::writeSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
||||
root.writeSubdivision(state);
|
||||
}
|
||||
|
||||
QRgbAttribute::QRgbAttribute(const QString& name, QRgb defaultValue) :
|
||||
InlineAttribute<QRgb>(name, defaultValue) {
|
||||
}
|
||||
|
@ -313,3 +321,21 @@ void SpannerSetAttribute::writeDelta(const MetavoxelNode& root, const MetavoxelN
|
|||
root.writeSpannerDelta(reference, state);
|
||||
state.stream << SharedObjectPointer();
|
||||
}
|
||||
|
||||
void SpannerSetAttribute::readSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
|
||||
forever {
|
||||
SharedObjectPointer object;
|
||||
state.stream >> object;
|
||||
if (!object) {
|
||||
break;
|
||||
}
|
||||
data.insert(state.attribute, object);
|
||||
}
|
||||
}
|
||||
|
||||
void SpannerSetAttribute::writeSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
||||
Spanner::incrementVisit();
|
||||
root.writeSpannerSubdivision(state);
|
||||
state.stream << SharedObjectPointer();
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,9 @@ public:
|
|||
|
||||
virtual void readDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||
virtual void writeDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||
|
||||
virtual void readSubdivision(MetavoxelData& data, MetavoxelStreamState& state);
|
||||
virtual void writeSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state);
|
||||
|
||||
virtual bool equal(void* first, void* second) const = 0;
|
||||
|
||||
|
@ -332,6 +335,9 @@ public:
|
|||
|
||||
virtual void readDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||
virtual void writeDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||
|
||||
virtual void readSubdivision(MetavoxelData& data, MetavoxelStreamState& state);
|
||||
virtual void writeSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state);
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__AttributeRegistry__) */
|
||||
|
|
|
@ -31,6 +31,10 @@ bool MetavoxelLOD::shouldSubdivide(const glm::vec3& minimum, float size) const {
|
|||
return size >= glm::distance(position, minimum + glm::vec3(size, size, size) * 0.5f) * threshold;
|
||||
}
|
||||
|
||||
bool MetavoxelLOD::becameSubdivided(const glm::vec3& minimum, float size, const MetavoxelLOD& reference) const {
|
||||
return shouldSubdivide(minimum, size) && !reference.shouldSubdivide(minimum, size);
|
||||
}
|
||||
|
||||
MetavoxelData::MetavoxelData() : _size(1.0f) {
|
||||
}
|
||||
|
||||
|
@ -295,10 +299,15 @@ void MetavoxelData::readDelta(const MetavoxelData& reference, const MetavoxelLOD
|
|||
MetavoxelStreamState state = { getMinimum(), _size, attribute, in, lod, referenceLOD };
|
||||
MetavoxelNode* oldRoot = _roots.value(attribute);
|
||||
if (oldRoot) {
|
||||
oldRoot->incrementReferenceCount();
|
||||
attribute->readDelta(*this, *oldRoot, state);
|
||||
oldRoot->decrementReferenceCount(attribute);
|
||||
|
||||
bool changed;
|
||||
in >> changed;
|
||||
if (changed) {
|
||||
oldRoot->incrementReferenceCount();
|
||||
attribute->readDelta(*this, *oldRoot, state);
|
||||
oldRoot->decrementReferenceCount(attribute);
|
||||
} else {
|
||||
attribute->readSubdivision(*this, state);
|
||||
}
|
||||
} else {
|
||||
attribute->read(*this, state);
|
||||
}
|
||||
|
@ -317,7 +326,9 @@ void MetavoxelData::readDelta(const MetavoxelData& reference, const MetavoxelLOD
|
|||
void MetavoxelData::writeDelta(const MetavoxelData& reference, const MetavoxelLOD& referenceLOD,
|
||||
Bitstream& out, const MetavoxelLOD& lod) const {
|
||||
// first things first: there might be no change whatsoever
|
||||
if (_size == reference._size && _roots == reference._roots) {
|
||||
glm::vec3 minimum = getMinimum();
|
||||
bool becameSubdivided = lod.becameSubdivided(minimum, _size, referenceLOD);
|
||||
if (_size == reference._size && _roots == reference._roots && !becameSubdivided) {
|
||||
out << false;
|
||||
return;
|
||||
}
|
||||
|
@ -338,14 +349,20 @@ void MetavoxelData::writeDelta(const MetavoxelData& reference, const MetavoxelLO
|
|||
expandedReference = expanded;
|
||||
}
|
||||
|
||||
// write the added/changed roots
|
||||
// write the added/changed/subdivided roots
|
||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
|
||||
MetavoxelNode* referenceRoot = expandedReference->_roots.value(it.key());
|
||||
if (it.value() != referenceRoot) {
|
||||
out << it.key();
|
||||
MetavoxelStreamState state = { getMinimum(), _size, it.key(), out, lod, referenceLOD };
|
||||
MetavoxelStreamState state = { minimum, _size, it.key(), out, lod, referenceLOD };
|
||||
if (it.value() != referenceRoot || becameSubdivided) {
|
||||
out << it.key();
|
||||
if (referenceRoot) {
|
||||
it.key()->writeDelta(*it.value(), *referenceRoot, state);
|
||||
if (it.value() == referenceRoot) {
|
||||
out << false;
|
||||
it.key()->writeSubdivision(*it.value(), state);
|
||||
} else {
|
||||
out << true;
|
||||
it.key()->writeDelta(*it.value(), *referenceRoot, state);
|
||||
}
|
||||
} else {
|
||||
it.key()->write(*it.value(), state);
|
||||
}
|
||||
|
@ -506,15 +523,18 @@ void MetavoxelNode::readDelta(const MetavoxelNode& reference, MetavoxelStreamSta
|
|||
}
|
||||
} else {
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
bool changed;
|
||||
state.stream >> changed;
|
||||
if (changed) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
if (changed) {
|
||||
_children[i] = new MetavoxelNode(state.attribute);
|
||||
_children[i]->readDelta(*reference._children[i], nextState);
|
||||
} else {
|
||||
_children[i] = reference._children[i];
|
||||
_children[i]->incrementReferenceCount();
|
||||
if (nextState.becameSubdivided()) {
|
||||
_children[i]->readSubdivision(nextState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -539,10 +559,13 @@ void MetavoxelNode::writeDelta(const MetavoxelNode& reference, MetavoxelStreamSt
|
|||
}
|
||||
} else {
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
if (_children[i] == reference._children[i]) {
|
||||
state.stream << false;
|
||||
} else {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
if (nextState.becameSubdivided()) {
|
||||
_children[i]->writeSubdivision(nextState);
|
||||
}
|
||||
} else {
|
||||
state.stream << true;
|
||||
_children[i]->writeDelta(*reference._children[i], nextState);
|
||||
}
|
||||
|
@ -551,6 +574,63 @@ void MetavoxelNode::writeDelta(const MetavoxelNode& reference, MetavoxelStreamSt
|
|||
}
|
||||
}
|
||||
|
||||
void MetavoxelNode::readSubdivision(MetavoxelStreamState& state) {
|
||||
bool leaf;
|
||||
bool subdivideReference = state.shouldSubdivideReference();
|
||||
if (!subdivideReference) {
|
||||
state.stream >> leaf;
|
||||
} else {
|
||||
leaf = isLeaf();
|
||||
}
|
||||
if (leaf) {
|
||||
clearChildren(state.attribute);
|
||||
|
||||
} else {
|
||||
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
||||
state.stream, state.lod, state.referenceLOD };
|
||||
if (!subdivideReference) {
|
||||
clearChildren(state.attribute);
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
_children[i] = new MetavoxelNode(state.attribute);
|
||||
_children[i]->read(nextState);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
if (nextState.becameSubdivided()) {
|
||||
_children[i]->readSubdivision(nextState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MetavoxelNode::writeSubdivision(MetavoxelStreamState& state) const {
|
||||
bool leaf = isLeaf();
|
||||
bool subdivideReference = state.shouldSubdivideReference();
|
||||
if (!subdivideReference) {
|
||||
state.stream << leaf;
|
||||
}
|
||||
if (!leaf) {
|
||||
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
||||
state.stream, state.lod, state.referenceLOD };
|
||||
if (!subdivideReference) {
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
_children[i]->write(nextState);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
if (nextState.becameSubdivided()) {
|
||||
_children[i]->writeSubdivision(nextState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MetavoxelNode::writeSpanners(MetavoxelStreamState& state) const {
|
||||
foreach (const SharedObjectPointer& object, decodeInline<SharedObjectSet>(_attributeValue)) {
|
||||
if (static_cast<Spanner*>(object.data())->testAndSetVisited()) {
|
||||
|
@ -602,9 +682,32 @@ void MetavoxelNode::writeSpannerDelta(const MetavoxelNode& reference, MetavoxelS
|
|||
return;
|
||||
}
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
if (_children[i] != reference._children[i]) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
_children[i]->writeSpannerDelta(*reference._children[i], nextState);
|
||||
|
||||
} else if (nextState.becameSubdivided()) {
|
||||
_children[i]->writeSpannerSubdivision(nextState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MetavoxelNode::writeSpannerSubdivision(MetavoxelStreamState& state) const {
|
||||
if (!isLeaf()) {
|
||||
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
||||
state.stream, state.lod, state.referenceLOD };
|
||||
if (!state.shouldSubdivideReference()) {
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
_children[i]->writeSpanners(nextState);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
nextState.setMinimum(state.minimum, i);
|
||||
if (nextState.becameSubdivided()) {
|
||||
_children[i]->writeSpannerSubdivision(nextState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@ public:
|
|||
bool isValid() const { return threshold > 0.0f; }
|
||||
|
||||
bool shouldSubdivide(const glm::vec3& minimum, float size) const;
|
||||
|
||||
/// Checks whether the node or any of the nodes underneath it have had subdivision enabled as compared to the reference.
|
||||
bool becameSubdivided(const glm::vec3& minimum, float size, const MetavoxelLOD& reference) const;
|
||||
};
|
||||
|
||||
DECLARE_STREAMABLE_METATYPE(MetavoxelLOD)
|
||||
|
@ -88,6 +91,7 @@ public:
|
|||
void writeDelta(const MetavoxelData& reference, const MetavoxelLOD& referenceLOD,
|
||||
Bitstream& out, const MetavoxelLOD& lod) const;
|
||||
|
||||
MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); }
|
||||
MetavoxelNode* createRoot(const AttributePointer& attribute);
|
||||
|
||||
private:
|
||||
|
@ -113,6 +117,7 @@ public:
|
|||
|
||||
bool shouldSubdivide() const { return lod.shouldSubdivide(minimum, size); }
|
||||
bool shouldSubdivideReference() const { return referenceLOD.shouldSubdivide(minimum, size); }
|
||||
bool becameSubdivided() const { return lod.becameSubdivided(minimum, size, referenceLOD); }
|
||||
|
||||
void setMinimum(const glm::vec3& lastMinimum, int index);
|
||||
};
|
||||
|
@ -144,8 +149,12 @@ public:
|
|||
void readDelta(const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||
void writeDelta(const MetavoxelNode& reference, MetavoxelStreamState& state) const;
|
||||
|
||||
void readSubdivision(MetavoxelStreamState& state);
|
||||
void writeSubdivision(MetavoxelStreamState& state) const;
|
||||
|
||||
void writeSpanners(MetavoxelStreamState& state) const;
|
||||
void writeSpannerDelta(const MetavoxelNode& reference, MetavoxelStreamState& state) const;
|
||||
void writeSpannerSubdivision(MetavoxelStreamState& state) const;
|
||||
|
||||
/// Increments the node's reference count.
|
||||
void incrementReferenceCount() { _referenceCount++; }
|
||||
|
|
Loading…
Reference in a new issue