From 53e6a77fcc613cfde2042686b646338f1db587f4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 20 Jan 2017 15:00:56 -0800 Subject: [PATCH] cleanup EncodeBitstreamParams to use nodeData when possible --- .../src/octree/OctreeSendThread.cpp | 9 +- libraries/entities/src/EntityItem.h | 2 +- libraries/entities/src/EntityTreeElement.cpp | 54 ++-- libraries/entities/src/LightEntityItem.cpp | 2 +- libraries/entities/src/LineEntityItem.cpp | 2 +- libraries/entities/src/LineEntityItem.h | 2 +- libraries/entities/src/ModelEntityItem.cpp | 2 +- libraries/entities/src/ModelEntityItem.h | 2 +- .../entities/src/ParticleEffectEntityItem.cpp | 2 +- libraries/entities/src/PolyLineEntityItem.cpp | 2 +- libraries/entities/src/PolyLineEntityItem.h | 2 +- libraries/entities/src/PolyVoxEntityItem.cpp | 2 +- libraries/entities/src/PolyVoxEntityItem.h | 2 +- libraries/entities/src/ShapeEntityItem.cpp | 2 +- libraries/entities/src/TextEntityItem.cpp | 2 +- libraries/entities/src/TextEntityItem.h | 2 +- libraries/entities/src/WebEntityItem.cpp | 2 +- libraries/entities/src/WebEntityItem.h | 2 +- libraries/entities/src/ZoneEntityItem.cpp | 2 +- libraries/entities/src/ZoneEntityItem.h | 2 +- libraries/octree/src/Octree.cpp | 230 ++++++------------ libraries/octree/src/Octree.h | 18 +- libraries/octree/src/OctreePersistThread.h | 2 +- 23 files changed, 129 insertions(+), 220 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 7922da8af4..7db06f12c0 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -443,13 +443,8 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST); EncodeBitstreamParams params(INT_MAX, WANT_EXISTS_BITS, DONT_CHOP, - viewFrustumChanged, - boundaryLevelAdjust, octreeSizeScale, - nodeData->getLastTimeBagEmpty(), - isFullScene, &nodeData->stats, _myServer->getJurisdiction(), - &nodeData->extraEncodeData, - nodeData->getUsesFrustum(), - nodeData); + viewFrustumChanged, boundaryLevelAdjust, octreeSizeScale, + isFullScene, _myServer->getJurisdiction(), nodeData); nodeData->copyCurrentViewFrustum(params.viewFrustum); if (viewFrustumChanged) { nodeData->copyLastKnownViewFrustum(params.lastViewFrustum); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 163b4d9e45..878058ad13 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -125,7 +125,7 @@ public: void markAsChangedOnServer() { _changedOnServer = usecTimestampNow(); } quint64 getLastChangedOnServer() const { return _changedOnServer; } - // TODO: eventually only include properties changed since the params.lastQuerySent time + // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; virtual OctreeElement::AppendState appendEntityData(OctreePacketData* packetData, EncodeBitstreamParams& params, diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 755c19e625..98287541e3 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -51,7 +51,10 @@ void EntityTreeElement::debugExtraEncodeData(EncodeBitstreamParams& params) cons qCDebug(entities) << "EntityTreeElement::debugExtraEncodeData()... "; qCDebug(entities) << " element:" << _cube; - OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; + auto entityNodeData = static_cast(params.nodeData); + assert(entityNodeData); + + OctreeElementExtraEncodeData* extraEncodeData = &entityNodeData->extraEncodeData; assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes if (extraEncodeData->contains(this)) { @@ -65,7 +68,11 @@ void EntityTreeElement::debugExtraEncodeData(EncodeBitstreamParams& params) cons void EntityTreeElement::initializeExtraEncodeData(EncodeBitstreamParams& params) { - OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; + auto entityNodeData = static_cast(params.nodeData); + assert(entityNodeData); + + OctreeElementExtraEncodeData* extraEncodeData = &entityNodeData->extraEncodeData; + assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes // Check to see if this element yet has encode data... if it doesn't create it if (!extraEncodeData->contains(this)) { @@ -93,7 +100,11 @@ void EntityTreeElement::initializeExtraEncodeData(EncodeBitstreamParams& params) } bool EntityTreeElement::shouldIncludeChildData(int childIndex, EncodeBitstreamParams& params) const { - OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; + + auto entityNodeData = static_cast(params.nodeData); + assert(entityNodeData); + + OctreeElementExtraEncodeData* extraEncodeData = &entityNodeData->extraEncodeData; assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes if (extraEncodeData->contains(this)) { @@ -122,7 +133,10 @@ bool EntityTreeElement::shouldRecurseChildTree(int childIndex, EncodeBitstreamPa } bool EntityTreeElement::alreadyFullyEncoded(EncodeBitstreamParams& params) const { - OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; + auto entityNodeData = static_cast(params.nodeData); + assert(entityNodeData); + + OctreeElementExtraEncodeData* extraEncodeData = &entityNodeData->extraEncodeData; assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes if (extraEncodeData->contains(this)) { @@ -137,8 +151,12 @@ bool EntityTreeElement::alreadyFullyEncoded(EncodeBitstreamParams& params) const } void EntityTreeElement::updateEncodedData(int childIndex, AppendState childAppendState, EncodeBitstreamParams& params) const { - OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; + auto entityNodeData = static_cast(params.nodeData); + assert(entityNodeData); + + OctreeElementExtraEncodeData* extraEncodeData = &entityNodeData->extraEncodeData; assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes + if (extraEncodeData->contains(this)) { EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData = std::static_pointer_cast((*extraEncodeData)[this]); @@ -161,7 +179,10 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params) con qCDebug(entities) << "EntityTreeElement::elementEncodeComplete() element:" << _cube; } - OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; + auto entityNodeData = static_cast(params.nodeData); + assert(entityNodeData); + + OctreeElementExtraEncodeData* extraEncodeData = &entityNodeData->extraEncodeData; assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes assert(extraEncodeData->contains(this)); @@ -236,8 +257,12 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData OctreeElement::AppendState appendElementState = OctreeElement::COMPLETED; // assume the best... + auto entityNodeData = static_cast(params.nodeData); + Q_ASSERT_X(entityNodeData, "EntityTreeElement::appendElementData", "expected params.nodeData not to be null"); + // first, check the params.extraEncodeData to see if there's any partial re-encode data for this element - OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; + OctreeElementExtraEncodeData* extraEncodeData = &entityNodeData->extraEncodeData; + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData = NULL; bool hadElementExtraData = false; if (extraEncodeData && extraEncodeData->contains(this)) { @@ -285,20 +310,17 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData // need to handle the case where our sibling elements need encoding but we don't. if (!entityTreeElementExtraEncodeData->elementCompleted) { - QJsonObject jsonFilters; - auto entityNodeData = static_cast(params.nodeData); - if (entityNodeData) { - // we have an EntityNodeData instance - // so we should assume that means we might have JSON filters to check - jsonFilters = entityNodeData->getJSONParameters(); - } + // we have an EntityNodeData instance + // so we should assume that means we might have JSON filters to check + auto jsonFilters = entityNodeData->getJSONParameters(); + for (uint16_t i = 0; i < _entityItems.size(); i++) { EntityItemPointer entity = _entityItems[i]; bool includeThisEntity = true; - if (!params.forceSendScene && entity->getLastChangedOnServer() < params.lastQuerySent) { + if (!params.forceSendScene && entity->getLastChangedOnServer() < entityNodeData->getLastTimeBagEmpty()) { includeThisEntity = false; } @@ -330,7 +352,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData // we only check the bounds against our frustum and LOD if the query has asked us to check against the frustum // which can sometimes not be the case when JSON filters are sent - if (params.usesFrustum && (includeThisEntity || params.recurseEverything)) { + if (entityNodeData->getUsesFrustum() && (includeThisEntity || params.recurseEverything)) { // we want to use the maximum possible box for this, so that we don't have to worry about the nuance of // simulation changing what's visible. consider the case where the entity contains an angular velocity diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index e09822f028..bc8e55e118 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -174,7 +174,7 @@ int LightEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags LightEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_IS_SPOTLIGHT; diff --git a/libraries/entities/src/LineEntityItem.cpp b/libraries/entities/src/LineEntityItem.cpp index 8ace665616..80e3f65fb3 100644 --- a/libraries/entities/src/LineEntityItem.cpp +++ b/libraries/entities/src/LineEntityItem.cpp @@ -126,7 +126,7 @@ int LineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags LineEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_COLOR; diff --git a/libraries/entities/src/LineEntityItem.h b/libraries/entities/src/LineEntityItem.h index 8629c94eb4..ff64c7c17e 100644 --- a/libraries/entities/src/LineEntityItem.h +++ b/libraries/entities/src/LineEntityItem.h @@ -26,7 +26,7 @@ class LineEntityItem : public EntityItem { virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; - // TODO: eventually only include properties changed since the params.lastQuerySent time + // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 911ff224b2..51d9c2ad25 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -160,7 +160,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, return bytesRead; } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index e1cb5cd92c..5076a43892 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -29,7 +29,7 @@ public: virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; - // TODO: eventually only include properties changed since the params.lastQuerySent time + // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 140522b00e..fc2d128bd1 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -469,7 +469,7 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index 7abafad627..473d9c1131 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -170,7 +170,7 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_COLOR; diff --git a/libraries/entities/src/PolyLineEntityItem.h b/libraries/entities/src/PolyLineEntityItem.h index 5f9f9124cf..3b3cf6e6ba 100644 --- a/libraries/entities/src/PolyLineEntityItem.h +++ b/libraries/entities/src/PolyLineEntityItem.h @@ -26,7 +26,7 @@ class PolyLineEntityItem : public EntityItem { virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; - // TODO: eventually only include properties changed since the params.lastQuerySent time + // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp index 90344d6c4b..dc794f1dcc 100644 --- a/libraries/entities/src/PolyVoxEntityItem.cpp +++ b/libraries/entities/src/PolyVoxEntityItem.cpp @@ -179,7 +179,7 @@ int PolyVoxEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* dat } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags PolyVoxEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_VOXEL_VOLUME_SIZE; diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index 311a002a4a..db30e54b61 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -26,7 +26,7 @@ class PolyVoxEntityItem : public EntityItem { virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; - // TODO: eventually only include properties changed since the params.lastQuerySent time + // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 345d9e54ab..018d8c568a 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -137,7 +137,7 @@ int ShapeEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags ShapeEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_SHAPE; diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp index fbb0bdc9cf..366fdc7aa2 100644 --- a/libraries/entities/src/TextEntityItem.cpp +++ b/libraries/entities/src/TextEntityItem.cpp @@ -99,7 +99,7 @@ int TextEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags TextEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_TEXT; diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h index 633aa96bfa..c706423cbd 100644 --- a/libraries/entities/src/TextEntityItem.h +++ b/libraries/entities/src/TextEntityItem.h @@ -30,7 +30,7 @@ public: virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; - // TODO: eventually only include properties changed since the params.lastQuerySent time + // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, diff --git a/libraries/entities/src/WebEntityItem.cpp b/libraries/entities/src/WebEntityItem.cpp index 182d58ba36..40da2a0af2 100644 --- a/libraries/entities/src/WebEntityItem.cpp +++ b/libraries/entities/src/WebEntityItem.cpp @@ -84,7 +84,7 @@ int WebEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, i } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags WebEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_SOURCE_URL; diff --git a/libraries/entities/src/WebEntityItem.h b/libraries/entities/src/WebEntityItem.h index 19a7b577fe..483c2bbc8a 100644 --- a/libraries/entities/src/WebEntityItem.h +++ b/libraries/entities/src/WebEntityItem.h @@ -29,7 +29,7 @@ public: virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; - // TODO: eventually only include properties changed since the params.lastQuerySent time + // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 37b3be99a3..6d1facc979 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -137,7 +137,7 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, } -// TODO: eventually only include properties changed since the params.lastQuerySent time +// TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index 2bef95e452..6a6326d067 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -30,7 +30,7 @@ public: virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual bool setProperties(const EntityItemProperties& properties) override; - // TODO: eventually only include properties changed since the params.lastQuerySent time + // TODO: eventually only include properties changed since the params.nodeData->getLastTimeBagEmpty() time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 58910c66bd..dfc6195f95 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -43,14 +43,15 @@ #include #include +#include "Octree.h" #include "OctreeConstants.h" #include "OctreeElementBag.h" -#include "Octree.h" -#include "OctreeUtils.h" #include "OctreeLogging.h" +#include "OctreeQueryNode.h" +#include "OctreeUtils.h" -QVector PERSIST_EXTENSIONS = {"svo", "json", "json.gz"}; +QVector PERSIST_EXTENSIONS = {"json", "json.gz"}; Octree::Octree(bool shouldReaverage) : _rootElement(NULL), @@ -898,8 +899,16 @@ int Octree::encodeTreeBitstream(OctreeElementPointer element, return bytesWritten; } + // you can't call this without a valid nodeData + auto octreeQueryNode = static_cast(params.nodeData); + if (!octreeQueryNode) { + qCDebug(octree, "WARNING! encodeTreeBitstream() called with nodeData=NULL"); + params.stopReason = EncodeBitstreamParams::NULL_NODE_DATA; + return bytesWritten; + } + // If we're at a element that is out of view, then we can return, because no nodes below us will be in view! - if (params.usesFrustum && !params.recurseEverything && !element->isInView(params.viewFrustum)) { + if (octreeQueryNode->getUsesFrustum() && !params.recurseEverything && !element->isInView(params.viewFrustum)) { params.stopReason = EncodeBitstreamParams::OUT_OF_VIEW; return bytesWritten; } @@ -935,9 +944,7 @@ int Octree::encodeTreeBitstream(OctreeElementPointer element, // record some stats, this is the one element that we won't record below in the recursion function, so we need to // track it here - if (params.stats) { - params.stats->traversed(element); - } + octreeQueryNode->stats.traversed(element); ViewFrustum::intersection parentLocationThisView = ViewFrustum::INTERSECT; // assume parent is in view, but not fully @@ -993,6 +1000,15 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, return bytesAtThisLevel; } + // you can't call this without a valid nodeData + auto octreeQueryNode = static_cast(params.nodeData); + if (!octreeQueryNode) { + qCDebug(octree, "WARNING! encodeTreeBitstream() called with nodeData=NULL"); + params.stopReason = EncodeBitstreamParams::NULL_NODE_DATA; + return bytesAtThisLevel; + } + + // Keep track of how deep we've encoded. currentEncodeLevel++; @@ -1015,15 +1031,13 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, } ViewFrustum::intersection nodeLocationThisView = ViewFrustum::INSIDE; // assume we're inside - if (params.usesFrustum && !params.recurseEverything) { + if (octreeQueryNode->getUsesFrustum() && !params.recurseEverything) { float boundaryDistance = boundaryDistanceForRenderLevel(element->getLevel() + params.boundaryLevelAdjust, params.octreeElementSizeScale); // If we're too far away for our render level, then just return if (element->distanceToCamera(params.viewFrustum) >= boundaryDistance) { - if (params.stats) { - params.stats->skippedDistance(element); - } + octreeQueryNode->stats.skippedDistance(element); params.stopReason = EncodeBitstreamParams::LOD_SKIP; return bytesAtThisLevel; } @@ -1039,9 +1053,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, // although technically, we really shouldn't ever be here, because our callers shouldn't be calling us if // we're out of view if (nodeLocationThisView == ViewFrustum::OUTSIDE) { - if (params.stats) { - params.stats->skippedOutOfView(element); - } + octreeQueryNode->stats.skippedOutOfView(element); params.stopReason = EncodeBitstreamParams::OUT_OF_VIEW; return bytesAtThisLevel; } @@ -1066,7 +1078,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, // as "was in view"... if (wasInView) { float boundaryDistance = boundaryDistanceForRenderLevel(element->getLevel() + params.boundaryLevelAdjust, - params.octreeElementSizeScale); + params.octreeElementSizeScale); if (element->distanceToCamera(params.lastViewFrustum) >= boundaryDistance) { // This would have been invisible... but now should be visible (we wouldn't be here otherwise)... wasInView = false; @@ -1077,22 +1089,20 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, // If we were previously in the view, then we normally will return out of here and stop recursing. But // if we're in deltaView mode, and this element has changed since it was last sent, then we do // need to send it. - if (wasInView && !(params.deltaView && element->hasChangedSince(params.lastQuerySent - CHANGE_FUDGE))) { - if (params.stats) { - params.stats->skippedWasInView(element); - } + if (wasInView && !(params.deltaView && element->hasChangedSince(octreeQueryNode->getLastTimeBagEmpty() - CHANGE_FUDGE))) { + octreeQueryNode->stats.skippedWasInView(element); params.stopReason = EncodeBitstreamParams::WAS_IN_VIEW; return bytesAtThisLevel; } } - // If we're not in delta sending mode, and we weren't asked to do a force send, and the octree element hasn't changed, + // If we're not in delta sending mode, and we weren't asked to do a force send, and the voxel hasn't changed, // then we can also bail early and save bits if (!params.forceSendScene && !params.deltaView && - !element->hasChangedSince(params.lastQuerySent - CHANGE_FUDGE)) { - if (params.stats) { - params.stats->skippedNoChange(element); - } + !element->hasChangedSince(octreeQueryNode->getLastTimeBagEmpty() - CHANGE_FUDGE)) { + + octreeQueryNode->stats.skippedNoChange(element); + params.stopReason = EncodeBitstreamParams::NO_CHANGE; return bytesAtThisLevel; } @@ -1164,8 +1174,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, // track stats // must check childElement here, because it could be we got here with no childElement - if (params.stats && childElement) { - params.stats->traversed(childElement); + if (childElement) { + octreeQueryNode->stats.traversed(childElement); } } @@ -1176,7 +1186,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, int originalIndex = indexOfChildren[i]; bool childIsInView = (childElement && - (params.recurseEverything || !params.usesFrustum || + (params.recurseEverything || !octreeQueryNode->getUsesFrustum() || (nodeLocationThisView == ViewFrustum::INSIDE) || // parent was fully in view, we can assume ALL children are (nodeLocationThisView == ViewFrustum::INTERSECT && childElement->isInView(params.viewFrustum)) // the parent intersects and the child is in view @@ -1184,20 +1194,18 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, if (!childIsInView) { // must check childElement here, because it could be we got here because there was no childElement - if (params.stats && childElement) { - params.stats->skippedOutOfView(childElement); + if (childElement) { + octreeQueryNode->stats.skippedOutOfView(childElement); } } else { // Before we consider this further, let's see if it's in our LOD scope... - float boundaryDistance = params.recurseEverything || !params.usesFrustum ? 1 : + float boundaryDistance = params.recurseEverything || !octreeQueryNode->getUsesFrustum() ? 1 : boundaryDistanceForRenderLevel(childElement->getLevel() + params.boundaryLevelAdjust, params.octreeElementSizeScale); if (!(distancesToChildren[i] < boundaryDistance)) { // don't need to check childElement here, because we can't get here with no childElement - if (params.stats) { - params.stats->skippedDistance(childElement); - } + octreeQueryNode->stats.skippedDistance(childElement); } else { inViewCount++; @@ -1211,20 +1219,18 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, bool childIsOccluded = false; // assume it's not occluded - bool shouldRender = params.recurseEverything || !params.usesFrustum || + bool shouldRender = params.recurseEverything || !octreeQueryNode->getUsesFrustum() || childElement->calculateShouldRender(params.viewFrustum, params.octreeElementSizeScale, params.boundaryLevelAdjust); // track some stats - if (params.stats) { - // don't need to check childElement here, because we can't get here with no childElement - if (!shouldRender && childElement->isLeaf()) { - params.stats->skippedDistance(childElement); - } - // don't need to check childElement here, because we can't get here with no childElement - if (childIsOccluded) { - params.stats->skippedOccluded(childElement); - } + // don't need to check childElement here, because we can't get here with no childElement + if (!shouldRender && childElement->isLeaf()) { + octreeQueryNode->stats.skippedDistance(childElement); + } + // don't need to check childElement here, because we can't get here with no childElement + if (childIsOccluded) { + octreeQueryNode->stats.skippedOccluded(childElement); } // track children with actual color, only if the child wasn't previously in view! @@ -1247,19 +1253,17 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, // need to send it. if (!childWasInView || (params.deltaView && - childElement->hasChangedSince(params.lastQuerySent - CHANGE_FUDGE))){ + childElement->hasChangedSince(octreeQueryNode->getLastTimeBagEmpty() - CHANGE_FUDGE))){ childrenDataBits += (1 << (7 - originalIndex)); inViewWithColorCount++; } else { // otherwise just track stats of the items we discarded // don't need to check childElement here, because we can't get here with no childElement - if (params.stats) { - if (childWasInView) { - params.stats->skippedWasInView(childElement); - } else { - params.stats->skippedNoChange(childElement); - } + if (childWasInView) { + octreeQueryNode->stats.skippedWasInView(childElement); + } else { + octreeQueryNode->stats.skippedNoChange(childElement); } } } @@ -1277,9 +1281,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, assert(continueThisLevel); // since we used reserved bits, this really shouldn't fail bytesAtThisLevel += sizeof(childrenDataBits); // keep track of byte count - if (params.stats) { - params.stats->colorBitsWritten(); // really data bits not just color bits - } + + octreeQueryNode->stats.colorBitsWritten(); // really data bits not just color bits // NOW might be a good time to give our tree subclass and this element a chance to set up and check any extra encode data element->initializeExtraEncodeData(params); @@ -1349,8 +1352,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, bytesAtThisLevel += (bytesAfterChild - bytesBeforeChild); // keep track of byte count for this child // don't need to check childElement here, because we can't get here with no childElement - if (params.stats && (childAppendState != OctreeElement::NONE)) { - params.stats->colorSent(childElement); + if (childAppendState != OctreeElement::NONE) { + octreeQueryNode->stats.colorSent(childElement); } } } @@ -1377,9 +1380,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, continueThisLevel = packetData->appendBitMask(childrenExistInTreeBits); if (continueThisLevel) { bytesAtThisLevel += sizeof(childrenExistInTreeBits); // keep track of byte count - if (params.stats) { - params.stats->existsBitsWritten(); - } + + octreeQueryNode->stats.existsBitsWritten(); } else { qCDebug(octree) << "WARNING UNEXPECTED CASE: Failed to append childrenExistInTreeBits"; qCDebug(octree) << "This is not expected!!!! -- continueThisLevel=FALSE...."; @@ -1392,9 +1394,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, continueThisLevel = packetData->appendBitMask(childrenExistInPacketBits); if (continueThisLevel) { bytesAtThisLevel += sizeof(childrenExistInPacketBits); // keep track of byte count - if (params.stats) { - params.stats->existsInPacketBitsWritten(); - } + + octreeQueryNode->stats.existsInPacketBitsWritten(); } else { qCDebug(octree) << "WARNING UNEXPECTED CASE: Failed to append childrenExistInPacketBits"; qCDebug(octree) << "This is not expected!!!! -- continueThisLevel=FALSE...."; @@ -1451,7 +1452,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, // called databits), then we wouldn't send the children. So those types of Octree's should tell us to keep // recursing, by returning TRUE in recurseChildrenWithData(). - if (params.recurseEverything || !params.usesFrustum + if (params.recurseEverything || !octreeQueryNode->getUsesFrustum() || recurseChildrenWithData() || !oneAtBit(childrenDataBits, originalIndex)) { // Allow the datatype a chance to determine if it really wants to recurse this tree. Usually this @@ -1502,8 +1503,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, } // If this is the last of the child exists bits, then we're actually be rolling out the entire tree - if (params.stats && childrenExistInPacketBits == 0) { - params.stats->childBitsRemoved(params.includeExistsBits); + if (childrenExistInPacketBits == 0) { + octreeQueryNode->stats.childBitsRemoved(params.includeExistsBits); } if (!continueThisLevel) { @@ -1558,9 +1559,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, if (continueThisLevel) { bytesAtThisLevel += (bytesAfterChild - bytesBeforeChild); // keep track of byte count for this child - if (params.stats) { - params.stats->colorSent(element); - } + octreeQueryNode->stats.colorSent(element); } if (!continueThisLevel) { @@ -1595,9 +1594,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, bag.insert(element); // don't need to check element here, because we can't get here with no element - if (params.stats) { - params.stats->didntFit(element); - } + octreeQueryNode->stats.didntFit(element); params.stopReason = EncodeBitstreamParams::DIDNT_FIT; bytesAtThisLevel = 0; // didn't fit @@ -1876,9 +1873,7 @@ bool Octree::writeToFile(const char* fileName, OctreeElementPointer element, QSt const char* cFileName = byteArray.constData(); bool success = false; - if (persistAsFileType == "svo") { - success = writeToSVOFile(fileName, element); - } else if (persistAsFileType == "json") { + if (persistAsFileType == "json") { success = writeToJSONFile(cFileName, element); } else if (persistAsFileType == "json.gz") { success = writeToJSONFile(cFileName, element, true); @@ -1936,95 +1931,6 @@ bool Octree::writeToJSONFile(const char* fileName, OctreeElementPointer element, return success; } -bool Octree::writeToSVOFile(const char* fileName, OctreeElementPointer element) { - qWarning() << "SVO file format deprecated. Support for reading SVO files is no longer support and will be removed soon."; - bool success = false; - - std::ofstream file(fileName, std::ios::out|std::ios::binary); - - if(file.is_open()) { - qCDebug(octree, "Saving binary SVO to file %s...", fileName); - - PacketType expectedPacketType = expectedDataPacketType(); - int expectedIntType = (int) expectedPacketType; - PacketVersion expectedVersion = versionForPacketType(expectedPacketType); - bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion); - - // before reading the file, check to see if this version of the Octree supports file versions - if (getWantSVOfileVersions()) { - // if so, read the first byte of the file and see if it matches the expected version code - file.write(reinterpret_cast(&expectedIntType), sizeof(expectedIntType)); - file.write(&expectedVersion, sizeof(expectedVersion)); - qCDebug(octree) << "SVO file type: " << expectedPacketType << " version: " << (int)expectedVersion; - - hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion); - } - if (hasBufferBreaks) { - qCDebug(octree) << " this version includes buffer breaks"; - } else { - qCDebug(octree) << " this version does not include buffer breaks"; - } - - - OctreeElementBag elementBag; - OctreeElementExtraEncodeData extraEncodeData; - // If we were given a specific element, start from there, otherwise start from root - if (element) { - elementBag.insert(element); - } else { - elementBag.insert(_rootElement); - } - - OctreePacketData packetData; - int bytesWritten = 0; - bool lastPacketWritten = false; - - while (OctreeElementPointer subTree = elementBag.extract()) { - EncodeBitstreamParams params(INT_MAX, NO_EXISTS_BITS); - params.recurseEverything = true; - withReadLock([&] { - params.extraEncodeData = &extraEncodeData; - bytesWritten = encodeTreeBitstream(subTree, &packetData, elementBag, params); - }); - - // if the subTree couldn't fit, and so we should reset the packet and reinsert the element in our bag and try again - if (bytesWritten == 0 && (params.stopReason == EncodeBitstreamParams::DIDNT_FIT)) { - if (packetData.hasContent()) { - // if this type of SVO file should have buffer breaks, then we will write a buffer size before each - // buffer to allow the reader to read this file in chunks. - if (hasBufferBreaks) { - quint16 bufferSize = packetData.getFinalizedSize(); - file.write((const char*)&bufferSize, sizeof(bufferSize)); - } - file.write((const char*)packetData.getFinalizedData(), packetData.getFinalizedSize()); - lastPacketWritten = true; - } - packetData.reset(); // is there a better way to do this? could we fit more? - elementBag.insert(subTree); - } else { - lastPacketWritten = false; - } - } - - if (!lastPacketWritten) { - // if this type of SVO file should have buffer breaks, then we will write a buffer size before each - // buffer to allow the reader to read this file in chunks. - if (hasBufferBreaks) { - quint16 bufferSize = packetData.getFinalizedSize(); - file.write((const char*)&bufferSize, sizeof(bufferSize)); - } - file.write((const char*)packetData.getFinalizedData(), packetData.getFinalizedSize()); - } - - releaseSceneEncodeData(&extraEncodeData); - - success = true; - } - file.close(); - - return success; -} - unsigned long Octree::getOctreeElementsCount() { unsigned long nodeCount = 0; recurseTreeWithOperation(countOctreeElementsOperation, &nodeCount); diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index 7b2f303c0d..caae31eaa5 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -59,9 +59,7 @@ const bool DONT_COLLAPSE = false; const int DONT_CHOP = 0; const int NO_BOUNDARY_ADJUST = 0; const int LOW_RES_MOVING_ADJUST = 1; -const quint64 IGNORE_LAST_SENT = 0; -#define IGNORE_SCENE_STATS NULL #define IGNORE_COVERAGE_MAP NULL #define IGNORE_JURISDICTION_MAP NULL @@ -69,7 +67,6 @@ class EncodeBitstreamParams { public: ViewFrustum viewFrustum; ViewFrustum lastViewFrustum; - quint64 lastQuerySent; int maxEncodeLevel; int maxLevelReached; bool includeExistsBits; @@ -79,10 +76,7 @@ public: int boundaryLevelAdjust; float octreeElementSizeScale; bool forceSendScene; - OctreeSceneStats* stats; JurisdictionMap* jurisdictionMap; - OctreeElementExtraEncodeData* extraEncodeData; - bool usesFrustum; NodeData* nodeData; // output hints from the encode process @@ -90,6 +84,7 @@ public: UNKNOWN, DIDNT_FIT, NULL_NODE, + NULL_NODE_DATA, TOO_DEEP, OUT_OF_JURISDICTION, LOD_SKIP, @@ -107,14 +102,9 @@ public: bool useDeltaView = false, int boundaryLevelAdjust = NO_BOUNDARY_ADJUST, float octreeElementSizeScale = DEFAULT_OCTREE_SIZE_SCALE, - quint64 lastQuerySent = IGNORE_LAST_SENT, bool forceSendScene = true, - OctreeSceneStats* stats = IGNORE_SCENE_STATS, JurisdictionMap* jurisdictionMap = IGNORE_JURISDICTION_MAP, - OctreeElementExtraEncodeData* extraEncodeData = nullptr, - bool usesFrustum = true, NodeData* nodeData = nullptr) : - lastQuerySent(lastQuerySent), maxEncodeLevel(maxEncodeLevel), maxLevelReached(0), includeExistsBits(includeExistsBits), @@ -123,10 +113,7 @@ public: boundaryLevelAdjust(boundaryLevelAdjust), octreeElementSizeScale(octreeElementSizeScale), forceSendScene(forceSendScene), - stats(stats), jurisdictionMap(jurisdictionMap), - extraEncodeData(extraEncodeData), - usesFrustum(usesFrustum), nodeData(nodeData), stopReason(UNKNOWN) { @@ -306,9 +293,8 @@ public: void loadOctreeFile(const char* fileName); // Octree exporters - bool writeToFile(const char* filename, OctreeElementPointer element = NULL, QString persistAsFileType = "svo"); + bool writeToFile(const char* filename, OctreeElementPointer element = NULL, QString persistAsFileType = "json.gz"); bool writeToJSONFile(const char* filename, OctreeElementPointer element = NULL, bool doGzip = false); - bool writeToSVOFile(const char* filename, OctreeElementPointer element = NULL); virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues, bool skipThoseWithBadParents) = 0; diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index f8215fb34a..927304e862 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -35,7 +35,7 @@ public: OctreePersistThread(OctreePointer tree, const QString& filename, const QString& backupDirectory, int persistInterval = DEFAULT_PERSIST_INTERVAL, bool wantBackup = false, - const QJsonObject& settings = QJsonObject(), bool debugTimestampNow = false, QString persistAsFileType="svo"); + const QJsonObject& settings = QJsonObject(), bool debugTimestampNow = false, QString persistAsFileType="json.gz"); bool isInitialLoadComplete() const { return _initialLoadComplete; } quint64 getLoadElapsedTime() const { return _loadTimeUSecs; }