only resort if view changed

This commit is contained in:
SamGondelman 2017-08-22 18:01:14 -07:00 committed by Andrew Meadows
parent 18f88a5a64
commit 1930c8f215
2 changed files with 44 additions and 35 deletions

View file

@ -94,42 +94,43 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
nodeData->copyCurrentViewFrustum(viewFrustum); nodeData->copyCurrentViewFrustum(viewFrustum);
EntityTreeElementPointer root = std::dynamic_pointer_cast<EntityTreeElement>(_myServer->getOctree()->getRoot()); EntityTreeElementPointer root = std::dynamic_pointer_cast<EntityTreeElement>(_myServer->getOctree()->getRoot());
startNewTraversal(viewFrustum, root, lodLevelOffset); startNewTraversal(viewFrustum, root, lodLevelOffset);
}
}
// If the previous traversal didn't finish, we'll need to resort the entities still in _sendQueue after calling traverse // If the previous traversal didn't finish, we'll need to resort the entities still in _sendQueue after calling traverse
EntityPriorityQueue prevSendQueue; if (!_sendQueue.empty()) {
_sendQueue.swap(prevSendQueue); EntityPriorityQueue prevSendQueue;
_prevEntitySet.clear(); _sendQueue.swap(prevSendQueue);
// Re-add elements from previous traveral if they still need to be sent // Re-add elements from previous traveral if they still need to be sent
while (!prevSendQueue.empty()) { while (!prevSendQueue.empty()) {
EntityItemPointer entity = prevSendQueue.top().getEntity(); EntityItemPointer entity = prevSendQueue.top().getEntity();
prevSendQueue.pop(); prevSendQueue.pop();
if (entity) { _entitiesToSend.clear();
// 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 if (entity) {
// during the traversal bool success = false;
_prevEntitySet.insert(entity); AACube cube = entity->getQueryAACube(success);
bool success = false; if (success) {
AACube cube = entity->getQueryAACube(success); if (_traversal.getCurrentView().cubeIntersectsKeyhole(cube)) {
if (success) { const float DO_NOT_SEND = -1.0e-6f;
if (_traversal.getCurrentView().cubeIntersectsKeyhole(cube)) { float priority = _conicalView.computePriority(cube);
const float DO_NOT_SEND = -1.0e-6f; if (priority != DO_NOT_SEND) {
float priority = _conicalView.computePriority(cube); float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
if (priority != DO_NOT_SEND) { cube,
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(), _traversal.getCurrentRootSizeScale(),
cube, lodLevelOffset);
_traversal.getCurrentRootSizeScale(),
lodLevelOffset);
// Only send entities if they are large enough to see // Only send entities if they are large enough to see
if (renderAccuracy > 0.0f) { if (renderAccuracy > 0.0f) {
_sendQueue.push(PrioritizedEntity(entity, priority)); _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 std::cout << "adebug send '" << entity->getName().toStdString() << "'" << " : " << entry.getPriority() << std::endl; // adebug
} }
_sendQueue.pop(); _sendQueue.pop();
_entitiesToSend.erase(entity);
} }
} }
// END EXPERIMENTAL DIFFERENTIAL TRAVERSAL // END EXPERIMENTAL DIFFERENTIAL TRAVERSAL
@ -229,7 +231,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
_traversal.setScanCallback([&] (DiffTraversal::VisibleElement& next) { _traversal.setScanCallback([&] (DiffTraversal::VisibleElement& next) {
next.element->forEachEntity([&](EntityItemPointer entity) { next.element->forEachEntity([&](EntityItemPointer entity) {
// Bail early if we've already checked this entity this frame // Bail early if we've already checked this entity this frame
if (_prevEntitySet.find(entity) != _prevEntitySet.end()) { if (_entitiesToSend.find(entity) != _entitiesToSend.end()) {
return; return;
} }
bool success = false; bool success = false;
@ -249,11 +251,13 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
if (renderAccuracy > 0.0f) { if (renderAccuracy > 0.0f) {
float priority = _conicalView.computePriority(cube); float priority = _conicalView.computePriority(cube);
_sendQueue.push(PrioritizedEntity(entity, priority)); _sendQueue.push(PrioritizedEntity(entity, priority));
_entitiesToSend.insert(entity);
} }
} }
} else { } else {
const float WHEN_IN_DOUBT_PRIORITY = 1.0f; const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
_sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY)); _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(); uint64_t timestamp = _traversal.getStartOfCompletedTraversal();
next.element->forEachEntity([&](EntityItemPointer entity) { next.element->forEachEntity([&](EntityItemPointer entity) {
// Bail early if we've already checked this entity this frame // Bail early if we've already checked this entity this frame
if (_prevEntitySet.find(entity) != _prevEntitySet.end()) { if (_entitiesToSend.find(entity) != _entitiesToSend.end()) {
return; return;
} }
if (entity->getLastEdited() > timestamp) { if (entity->getLastEdited() > timestamp) {
@ -282,11 +286,13 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
if (renderAccuracy > 0.0f) { if (renderAccuracy > 0.0f) {
float priority = _conicalView.computePriority(cube); float priority = _conicalView.computePriority(cube);
_sendQueue.push(PrioritizedEntity(entity, priority)); _sendQueue.push(PrioritizedEntity(entity, priority));
_entitiesToSend.insert(entity);
} }
} }
} else { } else {
const float WHEN_IN_DOUBT_PRIORITY = 1.0f; const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
_sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY)); _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) { if (next.element->getLastChangedContent() > timestamp || next.intersection != ViewFrustum::INSIDE) {
next.element->forEachEntity([&](EntityItemPointer entity) { next.element->forEachEntity([&](EntityItemPointer entity) {
// Bail early if we've already checked this entity this frame // Bail early if we've already checked this entity this frame
if (_prevEntitySet.find(entity) != _prevEntitySet.end()) { if (_entitiesToSend.find(entity) != _entitiesToSend.end()) {
return; return;
} }
bool success = false; bool success = false;
@ -318,6 +324,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
if (entity->getLastEdited() > timestamp || !_traversal.getCompletedView().cubeIntersectsKeyhole(cube)) { if (entity->getLastEdited() > timestamp || !_traversal.getCompletedView().cubeIntersectsKeyhole(cube)) {
float priority = _conicalView.computePriority(cube); float priority = _conicalView.computePriority(cube);
_sendQueue.push(PrioritizedEntity(entity, priority)); _sendQueue.push(PrioritizedEntity(entity, priority));
_entitiesToSend.insert(entity);
} else { } else {
// If this entity was skipped last time because it was too small, we still need to send it // If this entity was skipped last time because it was too small, we still need to send it
float lastRenderAccuracy = calculateRenderAccuracy(_traversal.getCompletedView().getPosition(), float lastRenderAccuracy = calculateRenderAccuracy(_traversal.getCompletedView().getPosition(),
@ -328,6 +335,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
if (lastRenderAccuracy <= 0.0f) { if (lastRenderAccuracy <= 0.0f) {
float priority = _conicalView.computePriority(cube); float priority = _conicalView.computePriority(cube);
_sendQueue.push(PrioritizedEntity(entity, priority)); _sendQueue.push(PrioritizedEntity(entity, priority));
_entitiesToSend.insert(entity);
} }
} }
} }
@ -335,6 +343,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
} else { } else {
const float WHEN_IN_DOUBT_PRIORITY = 1.0f; const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
_sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY)); _sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY));
_entitiesToSend.insert(entity);
} }
}); });
} }

View file

@ -42,7 +42,7 @@ private:
DiffTraversal _traversal; DiffTraversal _traversal;
EntityPriorityQueue _sendQueue; EntityPriorityQueue _sendQueue;
std::unordered_set<EntityItemPointer> _prevEntitySet; std::unordered_set<EntityItemPointer> _entitiesToSend;
ConicalView _conicalView; // cached optimized view for fast priority calculations ConicalView _conicalView; // cached optimized view for fast priority calculations
}; };