Spanner subdivision streaming bits.

This commit is contained in:
Andrzej Kapolka 2014-12-04 16:41:19 -08:00
parent a990b4ae1f
commit 9819658e20
7 changed files with 81 additions and 29 deletions

View file

@ -1274,25 +1274,37 @@ void SpannerSetAttribute::writeMetavoxelRoot(const MetavoxelNode& root, Metavoxe
void SpannerSetAttribute::readMetavoxelDelta(MetavoxelData& data, void SpannerSetAttribute::readMetavoxelDelta(MetavoxelData& data,
const MetavoxelNode& reference, MetavoxelStreamState& state) { const MetavoxelNode& reference, MetavoxelStreamState& state) {
forever { readMetavoxelSubdivision(data, state);
SharedObjectPointer object;
state.base.stream >> object;
if (!object) {
break;
} }
data.toggle(state.base.attribute, object);
static void writeDeltaSubdivision(SharedObjectSet& oldSet, SharedObjectSet& newSet, Bitstream& stream) {
for (SharedObjectSet::iterator newIt = newSet.begin(); newIt != newSet.end(); ) {
SharedObjectSet::iterator oldIt = oldSet.find(*newIt);
if (oldIt == oldSet.end()) {
stream << *newIt; // added
newIt = newSet.erase(newIt);
} else {
oldSet.erase(oldIt);
newIt++;
} }
// even if the root is empty, it should still exist
if (!data.getRoot(state.base.attribute)) {
data.createRoot(state.base.attribute);
} }
foreach (const SharedObjectPointer& object, oldSet) {
stream << object; // removed
}
stream << SharedObjectPointer();
foreach (const SharedObjectPointer& object, newSet) {
object->maybeWriteSubdivision(stream);
}
stream << SharedObjectPointer();
} }
void SpannerSetAttribute::writeMetavoxelDelta(const MetavoxelNode& root, void SpannerSetAttribute::writeMetavoxelDelta(const MetavoxelNode& root,
const MetavoxelNode& reference, MetavoxelStreamState& state) { const MetavoxelNode& reference, MetavoxelStreamState& state) {
state.base.visit = Spanner::getAndIncrementNextVisit(); SharedObjectSet oldSet, newSet;
root.writeSpannerDelta(reference, state); reference.getSpanners(this, state.minimum, state.size, state.base.referenceLOD, oldSet);
state.base.stream << SharedObjectPointer(); root.getSpanners(this, state.minimum, state.size, state.base.lod, newSet);
writeDeltaSubdivision(oldSet, newSet, state.base.stream);
} }
void SpannerSetAttribute::readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state) { void SpannerSetAttribute::readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
@ -1302,14 +1314,31 @@ void SpannerSetAttribute::readMetavoxelSubdivision(MetavoxelData& data, Metavoxe
if (!object) { if (!object) {
break; break;
} }
data.insert(state.base.attribute, object); data.toggle(state.base.attribute, object);
}
forever {
SharedObjectPointer object;
state.base.stream >> object;
if (!object) {
break;
}
SharedObjectPointer newObject = object->readSubdivision(state.base.stream);
if (newObject != object) {
data.replace(state.base.attribute, object, newObject);
state.base.stream.addSubdividedObject(newObject);
}
}
// even if the root is empty, it should still exist
if (!data.getRoot(state.base.attribute)) {
data.createRoot(state.base.attribute);
} }
} }
void SpannerSetAttribute::writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) { void SpannerSetAttribute::writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
state.base.visit = Spanner::getAndIncrementNextVisit(); SharedObjectSet oldSet, newSet;
root.writeSpannerSubdivision(state); root.getSpanners(this, state.minimum, state.size, state.base.referenceLOD, oldSet);
state.base.stream << SharedObjectPointer(); root.getSpanners(this, state.minimum, state.size, state.base.lod, newSet);
writeDeltaSubdivision(oldSet, newSet, state.base.stream);
} }
bool SpannerSetAttribute::metavoxelRootsEqual(const MetavoxelNode& firstRoot, const MetavoxelNode& secondRoot, bool SpannerSetAttribute::metavoxelRootsEqual(const MetavoxelNode& firstRoot, const MetavoxelNode& secondRoot,

View file

@ -267,7 +267,9 @@ Bitstream::ReadMappings Bitstream::getAndResetReadMappings() {
_typeStreamerStreamer.getAndResetTransientValues(), _typeStreamerStreamer.getAndResetTransientValues(),
_attributeStreamer.getAndResetTransientValues(), _attributeStreamer.getAndResetTransientValues(),
_scriptStringStreamer.getAndResetTransientValues(), _scriptStringStreamer.getAndResetTransientValues(),
_sharedObjectStreamer.getAndResetTransientValues() }; _sharedObjectStreamer.getAndResetTransientValues(),
_subdividedObjects };
_subdividedObjects.clear();
return mappings; return mappings;
} }
@ -291,6 +293,16 @@ void Bitstream::persistReadMappings(const ReadMappings& mappings) {
reference = it.value(); reference = it.value();
_weakSharedObjectHash.remove(it.value()->getRemoteID()); _weakSharedObjectHash.remove(it.value()->getRemoteID());
} }
foreach (const SharedObjectPointer& object, mappings.subdividedObjects) {
QPointer<SharedObject>& reference = _sharedObjectReferences[object->getRemoteOriginID()];
if (reference && reference != object) {
int id = _sharedObjectStreamer.removePersistentValue(reference.data());
if (id != 0) {
_sharedObjectStreamer.insertPersistentValue(id, object);
}
}
reference = object;
}
} }
void Bitstream::persistAndResetReadMappings() { void Bitstream::persistAndResetReadMappings() {

View file

@ -99,10 +99,12 @@ public:
int takePersistentID(P value) { return _persistentIDs.take(value); } int takePersistentID(P value) { return _persistentIDs.take(value); }
void removePersistentValue(V value) { int id = _valueIDs.take(value); _persistentValues.remove(id); } int removePersistentValue(V value) { int id = _valueIDs.take(value); _persistentValues.remove(id); return id; }
V takePersistentValue(int id) { V value = _persistentValues.take(id); _valueIDs.remove(value); return value; } V takePersistentValue(int id) { V value = _persistentValues.take(id); _valueIDs.remove(value); return value; }
void insertPersistentValue(int id, V value) { _valueIDs.insert(value, id); _persistentValues.insert(id, value); }
void copyPersistentMappings(const RepeatedValueStreamer& other); void copyPersistentMappings(const RepeatedValueStreamer& other);
void clearPersistentMappings(); void clearPersistentMappings();
@ -289,6 +291,7 @@ public:
QHash<int, AttributePointer> attributeValues; QHash<int, AttributePointer> attributeValues;
QHash<int, QScriptString> scriptStringValues; QHash<int, QScriptString> scriptStringValues;
QHash<int, SharedObjectPointer> sharedObjectValues; QHash<int, SharedObjectPointer> sharedObjectValues;
QVector<SharedObjectPointer> subdividedObjects;
}; };
/// Performs all of the various lazily initializations (of object streamers, etc.) If multiple threads need to use /// Performs all of the various lazily initializations (of object streamers, etc.) If multiple threads need to use
@ -374,6 +377,9 @@ public:
/// Resets to the initial state. /// Resets to the initial state.
void reset(); void reset();
/// Adds a subdivided object, which will be added to the read mappings and used as a reference if persisted.
void addSubdividedObject(const SharedObjectPointer& object) { _subdividedObjects.append(object); }
/// Returns the set of transient mappings gathered during writing and resets them. /// Returns the set of transient mappings gathered during writing and resets them.
WriteMappings getAndResetWriteMappings(); WriteMappings getAndResetWriteMappings();
@ -576,6 +582,8 @@ private:
RepeatedValueStreamer<QScriptString> _scriptStringStreamer; RepeatedValueStreamer<QScriptString> _scriptStringStreamer;
RepeatedValueStreamer<SharedObjectPointer, SharedObject*> _sharedObjectStreamer; RepeatedValueStreamer<SharedObjectPointer, SharedObject*> _sharedObjectStreamer;
QVector<SharedObjectPointer> _subdividedObjects;
WeakSharedObjectHash _sharedObjectReferences; WeakSharedObjectHash _sharedObjectReferences;
WeakSharedObjectHash _weakSharedObjectHash; WeakSharedObjectHash _weakSharedObjectHash;

View file

@ -147,11 +147,11 @@ void SharedObject::readExtraDelta(Bitstream& in, const SharedObject* reference)
// nothing by default // nothing by default
} }
void SharedObject::writeExtraSubdivision(Bitstream& out) { void SharedObject::maybeWriteSubdivision(Bitstream& out) {
// nothing by default // nothing by default
} }
SharedObject* SharedObject::readExtraSubdivision(Bitstream& in) { SharedObject* SharedObject::readSubdivision(Bitstream& in) {
return this; return this;
} }

View file

@ -92,12 +92,13 @@ public:
/// Reads the delta-encoded non-property contents of this object from the specified stream. /// Reads the delta-encoded non-property contents of this object from the specified stream.
virtual void readExtraDelta(Bitstream& in, const SharedObject* reference); virtual void readExtraDelta(Bitstream& in, const SharedObject* reference);
/// Writes the subdivision of the non-property contents of this object to the specified stream. /// Writes the subdivision of the contents of this object (preceeded by a
virtual void writeExtraSubdivision(Bitstream& out); /// reference to the object itself) to the specified stream if necessary.
virtual void maybeWriteSubdivision(Bitstream& out);
/// Reads the subdivision of the non-property contents of this object from the specified stream. /// Reads the subdivision of this object from the specified stream.
/// \return the modified object, or this if no modification was performed /// \return the modified object, or this if no modification was performed
virtual SharedObject* readExtraSubdivision(Bitstream& in); virtual SharedObject* readSubdivision(Bitstream& in);
private: private:

View file

@ -3016,7 +3016,7 @@ void Heightfield::readExtraDelta(Bitstream& in, const SharedObject* reference) {
} }
} }
void Heightfield::writeExtraSubdivision(Bitstream& out) { void Heightfield::maybeWriteSubdivision(Bitstream& out) {
MetavoxelLOD lod, referenceLOD; MetavoxelLOD lod, referenceLOD;
if (out.getContext()) { if (out.getContext()) {
MetavoxelStreamBase* base = static_cast<MetavoxelStreamBase*>(out.getContext()); MetavoxelStreamBase* base = static_cast<MetavoxelStreamBase*>(out.getContext());
@ -3026,13 +3026,13 @@ void Heightfield::writeExtraSubdivision(Bitstream& out) {
HeightfieldStreamBase base = { out, lod, referenceLOD }; HeightfieldStreamBase base = { out, lod, referenceLOD };
HeightfieldStreamState state = { base, glm::vec2(), 1.0f }; HeightfieldStreamState state = { base, glm::vec2(), 1.0f };
if (state.becameSubdivided()) { if (state.becameSubdividedOrCollapsed()) {
out << SharedObjectPointer(this); out << SharedObjectPointer(this);
_root->writeSubdivision(state); _root->writeSubdivision(state);
} }
} }
SharedObject* Heightfield::readExtraSubdivision(Bitstream& in) { SharedObject* Heightfield::readSubdivision(Bitstream& in) {
MetavoxelLOD lod, referenceLOD; MetavoxelLOD lod, referenceLOD;
if (in.getContext()) { if (in.getContext()) {
MetavoxelStreamBase* base = static_cast<MetavoxelStreamBase*>(in.getContext()); MetavoxelStreamBase* base = static_cast<MetavoxelStreamBase*>(in.getContext());
@ -3046,6 +3046,8 @@ SharedObject* Heightfield::readExtraSubdivision(Bitstream& in) {
HeightfieldNodePointer root(_root->readSubdivision(state)); HeightfieldNodePointer root(_root->readSubdivision(state));
if (_root != root) { if (_root != root) {
Heightfield* newHeightfield = static_cast<Heightfield*>(clone(true)); Heightfield* newHeightfield = static_cast<Heightfield*>(clone(true));
newHeightfield->setRemoteID(getRemoteID());
newHeightfield->setRemoteOriginID(getRemoteOriginID());
newHeightfield->setRoot(root); newHeightfield->setRoot(root);
return newHeightfield; return newHeightfield;
} }

View file

@ -642,8 +642,8 @@ public:
virtual void readExtra(Bitstream& in); virtual void readExtra(Bitstream& in);
virtual void writeExtraDelta(Bitstream& out, const SharedObject* reference) const; virtual void writeExtraDelta(Bitstream& out, const SharedObject* reference) const;
virtual void readExtraDelta(Bitstream& in, const SharedObject* reference); virtual void readExtraDelta(Bitstream& in, const SharedObject* reference);
virtual void writeExtraSubdivision(Bitstream& out); virtual void maybeWriteSubdivision(Bitstream& out);
virtual SharedObject* readExtraSubdivision(Bitstream& in); virtual SharedObject* readSubdivision(Bitstream& in);
signals: signals: