mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 17:03:58 +02:00
full scene traversal and json filters
This commit is contained in:
parent
0ad5f47bfd
commit
7938e301e7
6 changed files with 82 additions and 25 deletions
|
@ -98,7 +98,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
|||
nodeData->copyCurrentViewFrustum(viewFrustum);
|
||||
EntityTreeElementPointer root = std::dynamic_pointer_cast<EntityTreeElement>(_myServer->getOctree()->getRoot());
|
||||
int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
|
||||
startNewTraversal(viewFrustum, root, lodLevelOffset);
|
||||
startNewTraversal(viewFrustum, root, lodLevelOffset, true);
|
||||
|
||||
// When the viewFrustum changed the sort order may be incorrect, so we re-sort
|
||||
// and also use the opportunity to cull anything no longer in view
|
||||
|
@ -138,6 +138,11 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (_traversal.finished()) {
|
||||
ViewFrustum viewFrustum;
|
||||
EntityTreeElementPointer root = std::dynamic_pointer_cast<EntityTreeElement>(_myServer->getOctree()->getRoot());
|
||||
int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + NO_BOUNDARY_ADJUST;
|
||||
startNewTraversal(viewFrustum, root, lodLevelOffset, false);
|
||||
}
|
||||
|
||||
if (!_traversal.finished()) {
|
||||
|
@ -165,7 +170,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
|||
EntityItemPointer entity = entry.getEntity();
|
||||
if (entity) {
|
||||
std::cout << "adebug send '" << entity->getName().toStdString() << "'" << " : " << entry.getPriority() << std::endl; // adebug
|
||||
_knownState[entity] = sendTime;
|
||||
_knownState[entity.get()] = sendTime;
|
||||
}
|
||||
_sendQueue.pop();
|
||||
_entitiesInQueue.erase(entry.getRawEntityPointer());
|
||||
|
@ -225,13 +230,14 @@ bool EntityTreeSendThread::addDescendantsToExtraFlaggedEntities(const QUuid& fil
|
|||
return hasNewChild || hasNewDescendants;
|
||||
}
|
||||
|
||||
void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTreeElementPointer root, int32_t lodLevelOffset) {
|
||||
DiffTraversal::Type type = _traversal.prepareNewTraversal(view, root, lodLevelOffset);
|
||||
// there are three types of traversal:
|
||||
void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTreeElementPointer root, int32_t lodLevelOffset, bool usesFrustum) {
|
||||
DiffTraversal::Type type = _traversal.prepareNewTraversal(view, root, lodLevelOffset, usesFrustum);
|
||||
// there are four types of traversal:
|
||||
//
|
||||
// (1) FirstTime = at login --> find everything in view
|
||||
// (2) Repeat = view hasn't changed --> find what has changed since last complete traversal
|
||||
// (3) Differential = view has changed --> find what has changed or in new view but not old
|
||||
// (4) FullScene = no view frustum -> send everything
|
||||
//
|
||||
// The "scanCallback" we provide to the traversal depends on the type:
|
||||
//
|
||||
|
@ -371,10 +377,26 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
|||
}
|
||||
});
|
||||
break;
|
||||
case DiffTraversal::FullScene:
|
||||
_traversal.setScanCallback([&](DiffTraversal::VisibleElement& next) {
|
||||
next.element->forEachEntity([&](EntityItemPointer entity) {
|
||||
// Bail early if we've already checked this entity this frame
|
||||
if (_entitiesInQueue.find(entity.get()) != _entitiesInQueue.end()) {
|
||||
return;
|
||||
}
|
||||
if (_knownState.find(entity.get()) == _knownState.end() ||
|
||||
(_knownState.find(entity.get()) != _knownState.end() && entity->getLastEdited() > _knownState[entity.get()])) {
|
||||
// We don't have a view frustum from which to compute priority
|
||||
_sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY));
|
||||
_entitiesInQueue.insert(entity.get());
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params) {
|
||||
bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params, const QJsonObject& jsonFilters) {
|
||||
#ifdef SEND_SORTED_ENTITIES
|
||||
//auto entityTree = std::static_pointer_cast<EntityTree>(_myServer->getOctree());
|
||||
if (_sendQueue.empty()) {
|
||||
|
@ -418,17 +440,20 @@ bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstream
|
|||
PrioritizedEntity queuedItem = _sendQueue.top();
|
||||
EntityItemPointer entity = queuedItem.getEntity();
|
||||
if (entity) {
|
||||
OctreeElement::AppendState appendEntityState = entity->appendEntityData(&_packetData, params, _extraEncodeData);
|
||||
_knownState[entity.get()] = sendTime;
|
||||
// Only send entities that match the jsonFilters, but keep track of everything we've tried to send so we don't try to send it again
|
||||
if (entity->matchesJSONFilters(jsonFilters)) {
|
||||
OctreeElement::AppendState appendEntityState = entity->appendEntityData(&_packetData, params, _extraEncodeData);
|
||||
|
||||
if (appendEntityState != OctreeElement::COMPLETED) {
|
||||
if (appendEntityState == OctreeElement::PARTIAL) {
|
||||
++_numEntities;
|
||||
if (appendEntityState != OctreeElement::COMPLETED) {
|
||||
if (appendEntityState == OctreeElement::PARTIAL) {
|
||||
++_numEntities;
|
||||
}
|
||||
params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
|
||||
break;
|
||||
}
|
||||
params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
|
||||
break;
|
||||
++_numEntities;
|
||||
}
|
||||
++_numEntities;
|
||||
_knownState[entity.get()] = sendTime;
|
||||
}
|
||||
_sendQueue.pop();
|
||||
_entitiesInQueue.erase(entity.get());
|
||||
|
|
|
@ -39,8 +39,8 @@ private:
|
|||
bool addAncestorsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
||||
bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
||||
|
||||
void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset);
|
||||
bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params) override;
|
||||
void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, bool usesFrustum);
|
||||
bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params, const QJsonObject& jsonFilters) override;
|
||||
|
||||
DiffTraversal _traversal;
|
||||
EntityPriorityQueue _sendQueue;
|
||||
|
|
|
@ -458,7 +458,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode*
|
|||
return _truePacketsSent;
|
||||
}
|
||||
|
||||
bool OctreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params) {
|
||||
bool OctreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params, const QJsonObject& jsonFilters) {
|
||||
bool somethingToSend = false;
|
||||
OctreeQueryNode* nodeData = static_cast<OctreeQueryNode*>(params.nodeData);
|
||||
if (!nodeData->elementBag.isEmpty()) {
|
||||
|
@ -523,7 +523,7 @@ void OctreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, Octre
|
|||
bool lastNodeDidntFit = false; // assume each node fits
|
||||
params.stopReason = EncodeBitstreamParams::UNKNOWN; // reset params.stopReason before traversal
|
||||
|
||||
somethingToSend = traverseTreeAndBuildNextPacketPayload(params);
|
||||
somethingToSend = traverseTreeAndBuildNextPacketPayload(params, nodeData->getJSONParameters());
|
||||
|
||||
if (params.stopReason == EncodeBitstreamParams::DIDNT_FIT) {
|
||||
lastNodeDidntFit = true;
|
||||
|
|
|
@ -55,7 +55,7 @@ protected:
|
|||
virtual void preDistributionProcessing() {};
|
||||
virtual void traverseTreeAndSendContents(SharedNodePointer node, OctreeQueryNode* nodeData,
|
||||
bool viewFrustumChanged, bool isFullScene);
|
||||
virtual bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params);
|
||||
virtual bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params, const QJsonObject& jsonFilters);
|
||||
|
||||
OctreePacketData _packetData;
|
||||
QWeakPointer<Node> _node;
|
||||
|
|
|
@ -142,19 +142,45 @@ void DiffTraversal::Waypoint::getNextVisibleElementDifferential(DiffTraversal::V
|
|||
next.intersection = ViewFrustum::OUTSIDE;
|
||||
}
|
||||
|
||||
void DiffTraversal::Waypoint::getNextVisibleElementFullScene(DiffTraversal::VisibleElement& next, uint64_t lastTime) {
|
||||
// NOTE: no need to set next.intersection or check LOD truncation in the "FullScene" context
|
||||
if (_nextIndex == -1) {
|
||||
++_nextIndex;
|
||||
EntityTreeElementPointer element = _weakElement.lock();
|
||||
if (element->getLastChangedContent() > lastTime) {
|
||||
next.element = element;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_nextIndex < NUMBER_OF_CHILDREN) {
|
||||
EntityTreeElementPointer element = _weakElement.lock();
|
||||
if (element) {
|
||||
while (_nextIndex < NUMBER_OF_CHILDREN) {
|
||||
EntityTreeElementPointer nextElement = element->getChildAtIndex(_nextIndex);
|
||||
++_nextIndex;
|
||||
if (nextElement && nextElement->getLastChanged() > lastTime) {
|
||||
next.element = nextElement;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
next.element.reset();
|
||||
}
|
||||
|
||||
DiffTraversal::DiffTraversal() {
|
||||
const int32_t MIN_PATH_DEPTH = 16;
|
||||
_path.reserve(MIN_PATH_DEPTH);
|
||||
}
|
||||
|
||||
DiffTraversal::Type DiffTraversal::prepareNewTraversal(
|
||||
const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset) {
|
||||
DiffTraversal::Type DiffTraversal::prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, bool usesFrustum) {
|
||||
assert(root);
|
||||
// there are three types of traversal:
|
||||
// there are four types of traversal:
|
||||
//
|
||||
// (1) First = fresh view --> find all elements in view
|
||||
// (2) Repeat = view hasn't changed --> find elements changed since last complete traversal
|
||||
// (3) Differential = view has changed --> find elements changed or in new view but not old
|
||||
// (4) FullScene = no view frustum -> send everything
|
||||
//
|
||||
// for each traversal type we assign the appropriate _getNextVisibleElementCallback
|
||||
//
|
||||
|
@ -166,7 +192,12 @@ DiffTraversal::Type DiffTraversal::prepareNewTraversal(
|
|||
//
|
||||
|
||||
Type type;
|
||||
if (_completedView.startTime == 0) {
|
||||
if (!usesFrustum) {
|
||||
type = Type::FullScene;
|
||||
_getNextVisibleElementCallback = [&](DiffTraversal::VisibleElement& next) {
|
||||
_path.back().getNextVisibleElementFullScene(next, _completedView.startTime);
|
||||
};
|
||||
} else if (_completedView.startTime == 0) {
|
||||
type = Type::First;
|
||||
_currentView.viewFrustum = viewFrustum;
|
||||
_currentView.lodLevelOffset = root->getLevel() + lodLevelOffset - 1; // -1 because true root has level=1
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
void getNextVisibleElementFirstTime(VisibleElement& next, const View& view);
|
||||
void getNextVisibleElementRepeat(VisibleElement& next, const View& view, uint64_t lastTime);
|
||||
void getNextVisibleElementDifferential(VisibleElement& next, const View& view, const View& lastView);
|
||||
void getNextVisibleElementFullScene(VisibleElement& next, uint64_t lastTime);
|
||||
|
||||
int8_t getNextIndex() const { return _nextIndex; }
|
||||
void initRootNextIndex() { _nextIndex = -1; }
|
||||
|
@ -55,11 +56,11 @@ public:
|
|||
int8_t _nextIndex;
|
||||
};
|
||||
|
||||
typedef enum { First, Repeat, Differential } Type;
|
||||
typedef enum { First, Repeat, Differential, FullScene } Type;
|
||||
|
||||
DiffTraversal();
|
||||
|
||||
Type prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset);
|
||||
Type prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, bool isFullScene);
|
||||
|
||||
const ViewFrustum& getCurrentView() const { return _currentView.viewFrustum; }
|
||||
const ViewFrustum& getCompletedView() const { return _completedView.viewFrustum; }
|
||||
|
|
Loading…
Reference in a new issue