mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 04:34:38 +02:00
cleanup EncodeBitstreamParams to use nodeData when possible
This commit is contained in:
parent
9b26e8ee95
commit
53e6a77fcc
23 changed files with 129 additions and 220 deletions
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<EntityNodeData*>(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<EntityNodeData*>(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<EntityNodeData*>(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<EntityNodeData*>(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<EntityNodeData*>(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<EntityTreeElementExtraEncodeData>((*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<EntityNodeData*>(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<EntityNodeData*>(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<EntityNodeData*>(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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -43,14 +43,15 @@
|
|||
#include <PathUtils.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#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<QString> PERSIST_EXTENSIONS = {"svo", "json", "json.gz"};
|
||||
QVector<QString> 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<OctreeQueryNode*>(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<OctreeQueryNode*>(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<char*>(&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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in a new issue