diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index adb9aedb6b..946dedc3ff 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -94,42 +94,43 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O nodeData->copyCurrentViewFrustum(viewFrustum); EntityTreeElementPointer root = std::dynamic_pointer_cast(_myServer->getOctree()->getRoot()); startNewTraversal(viewFrustum, root, lodLevelOffset); - } - } - // If the previous traversal didn't finish, we'll need to resort the entities still in _sendQueue after calling traverse - EntityPriorityQueue prevSendQueue; - _sendQueue.swap(prevSendQueue); - _prevEntitySet.clear(); - // Re-add elements from previous traveral if they still need to be sent - while (!prevSendQueue.empty()) { - EntityItemPointer entity = prevSendQueue.top().getEntity(); - prevSendQueue.pop(); - if (entity) { - // We can keep track of the entity regardless of if we decide to send it so that we don't have to check it again - // during the traversal - _prevEntitySet.insert(entity); - bool success = false; - AACube cube = entity->getQueryAACube(success); - if (success) { - if (_traversal.getCurrentView().cubeIntersectsKeyhole(cube)) { - const float DO_NOT_SEND = -1.0e-6f; - float priority = _conicalView.computePriority(cube); - if (priority != DO_NOT_SEND) { - float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(), - cube, - _traversal.getCurrentRootSizeScale(), - lodLevelOffset); + // If the previous traversal didn't finish, we'll need to resort the entities still in _sendQueue after calling traverse + if (!_sendQueue.empty()) { + EntityPriorityQueue prevSendQueue; + _sendQueue.swap(prevSendQueue); + // Re-add elements from previous traveral if they still need to be sent + while (!prevSendQueue.empty()) { + EntityItemPointer entity = prevSendQueue.top().getEntity(); + prevSendQueue.pop(); + _entitiesToSend.clear(); + if (entity) { + bool success = false; + AACube cube = entity->getQueryAACube(success); + if (success) { + if (_traversal.getCurrentView().cubeIntersectsKeyhole(cube)) { + const float DO_NOT_SEND = -1.0e-6f; + float priority = _conicalView.computePriority(cube); + if (priority != DO_NOT_SEND) { + float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(), + cube, + _traversal.getCurrentRootSizeScale(), + lodLevelOffset); - // Only send entities if they are large enough to see - if (renderAccuracy > 0.0f) { - _sendQueue.push(PrioritizedEntity(entity, priority)); + // Only send entities if they are large enough to see + if (renderAccuracy > 0.0f) { + _sendQueue.push(PrioritizedEntity(entity, priority)); + _entitiesToSend.insert(entity); + } + } + } + } else { + const float WHEN_IN_DOUBT_PRIORITY = 1.0f; + _sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY)); + _entitiesToSend.insert(entity); } } } - } else { - const float WHEN_IN_DOUBT_PRIORITY = 1.0f; - _sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY)); } } } @@ -153,6 +154,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O std::cout << "adebug send '" << entity->getName().toStdString() << "'" << " : " << entry.getPriority() << std::endl; // adebug } _sendQueue.pop(); + _entitiesToSend.erase(entity); } } // END EXPERIMENTAL DIFFERENTIAL TRAVERSAL @@ -229,7 +231,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree _traversal.setScanCallback([&] (DiffTraversal::VisibleElement& next) { next.element->forEachEntity([&](EntityItemPointer entity) { // Bail early if we've already checked this entity this frame - if (_prevEntitySet.find(entity) != _prevEntitySet.end()) { + if (_entitiesToSend.find(entity) != _entitiesToSend.end()) { return; } bool success = false; @@ -249,11 +251,13 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree if (renderAccuracy > 0.0f) { float priority = _conicalView.computePriority(cube); _sendQueue.push(PrioritizedEntity(entity, priority)); + _entitiesToSend.insert(entity); } } } else { const float WHEN_IN_DOUBT_PRIORITY = 1.0f; _sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY)); + _entitiesToSend.insert(entity); } }); }); @@ -264,7 +268,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree uint64_t timestamp = _traversal.getStartOfCompletedTraversal(); next.element->forEachEntity([&](EntityItemPointer entity) { // Bail early if we've already checked this entity this frame - if (_prevEntitySet.find(entity) != _prevEntitySet.end()) { + if (_entitiesToSend.find(entity) != _entitiesToSend.end()) { return; } if (entity->getLastEdited() > timestamp) { @@ -282,11 +286,13 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree if (renderAccuracy > 0.0f) { float priority = _conicalView.computePriority(cube); _sendQueue.push(PrioritizedEntity(entity, priority)); + _entitiesToSend.insert(entity); } } } else { const float WHEN_IN_DOUBT_PRIORITY = 1.0f; _sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY)); + _entitiesToSend.insert(entity); } } }); @@ -300,7 +306,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree if (next.element->getLastChangedContent() > timestamp || next.intersection != ViewFrustum::INSIDE) { next.element->forEachEntity([&](EntityItemPointer entity) { // Bail early if we've already checked this entity this frame - if (_prevEntitySet.find(entity) != _prevEntitySet.end()) { + if (_entitiesToSend.find(entity) != _entitiesToSend.end()) { return; } bool success = false; @@ -318,6 +324,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree if (entity->getLastEdited() > timestamp || !_traversal.getCompletedView().cubeIntersectsKeyhole(cube)) { float priority = _conicalView.computePriority(cube); _sendQueue.push(PrioritizedEntity(entity, priority)); + _entitiesToSend.insert(entity); } else { // If this entity was skipped last time because it was too small, we still need to send it float lastRenderAccuracy = calculateRenderAccuracy(_traversal.getCompletedView().getPosition(), @@ -328,6 +335,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree if (lastRenderAccuracy <= 0.0f) { float priority = _conicalView.computePriority(cube); _sendQueue.push(PrioritizedEntity(entity, priority)); + _entitiesToSend.insert(entity); } } } @@ -335,6 +343,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree } else { const float WHEN_IN_DOUBT_PRIORITY = 1.0f; _sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY)); + _entitiesToSend.insert(entity); } }); } diff --git a/assignment-client/src/entities/EntityTreeSendThread.h b/assignment-client/src/entities/EntityTreeSendThread.h index f98d007eb3..50e7981938 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.h +++ b/assignment-client/src/entities/EntityTreeSendThread.h @@ -42,7 +42,7 @@ private: DiffTraversal _traversal; EntityPriorityQueue _sendQueue; - std::unordered_set _prevEntitySet; + std::unordered_set _entitiesToSend; ConicalView _conicalView; // cached optimized view for fast priority calculations };