mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 18:42:58 +02:00
moved TreePathTraversal logic into EntityTreeSendThread
This commit is contained in:
parent
bf27412091
commit
91908ca3da
2 changed files with 144 additions and 163 deletions
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
const float DO_NOT_SEND = -1.0e-6f;
|
const float DO_NOT_SEND = -1.0e-6f;
|
||||||
|
|
||||||
void TreeTraversalPath::ConicalView::set(const ViewFrustum& viewFrustum) {
|
void ConicalView::set(const ViewFrustum& viewFrustum) {
|
||||||
// The ConicalView has two parts: a central sphere (same as ViewFrustm) and a circular cone that bounds the frustum part.
|
// The ConicalView has two parts: a central sphere (same as ViewFrustm) and a circular cone that bounds the frustum part.
|
||||||
// Why? Because approximate intersection tests are much faster to compute for a cone than for a frustum.
|
// Why? Because approximate intersection tests are much faster to compute for a cone than for a frustum.
|
||||||
_position = viewFrustum.getPosition();
|
_position = viewFrustum.getPosition();
|
||||||
|
@ -35,7 +35,7 @@ void TreeTraversalPath::ConicalView::set(const ViewFrustum& viewFrustum) {
|
||||||
_radius = viewFrustum.getCenterRadius();
|
_radius = viewFrustum.getCenterRadius();
|
||||||
}
|
}
|
||||||
|
|
||||||
float TreeTraversalPath::ConicalView::computePriority(const AACube& cube) const {
|
float ConicalView::computePriority(const AACube& cube) const {
|
||||||
glm::vec3 p = cube.calcCenter() - _position; // position of bounding sphere in view-frame
|
glm::vec3 p = cube.calcCenter() - _position; // position of bounding sphere in view-frame
|
||||||
float d = glm::length(p); // distance to center of bounding sphere
|
float d = glm::length(p); // distance to center of bounding sphere
|
||||||
float r = 0.5f * cube.getScale(); // radius of bounding sphere
|
float r = 0.5f * cube.getScale(); // radius of bounding sphere
|
||||||
|
@ -51,7 +51,7 @@ float TreeTraversalPath::ConicalView::computePriority(const AACube& cube) const
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
float TreeTraversalPath::ConicalView::computePriority(const EntityItemPointer& entity) const {
|
float ConicalView::computePriority(const EntityItemPointer& entity) const {
|
||||||
assert(entity);
|
assert(entity);
|
||||||
bool success;
|
bool success;
|
||||||
AACube cube = entity->getQueryAACube(success);
|
AACube cube = entity->getQueryAACube(success);
|
||||||
|
@ -63,7 +63,7 @@ float TreeTraversalPath::ConicalView::computePriority(const EntityItemPointer& e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float TreeTraversalPath::PrioritizedEntity::updatePriority(const TreeTraversalPath::ConicalView& conicalView) {
|
float PrioritizedEntity::updatePriority(const ConicalView& conicalView) {
|
||||||
EntityItemPointer entity = _weakEntity.lock();
|
EntityItemPointer entity = _weakEntity.lock();
|
||||||
if (entity) {
|
if (entity) {
|
||||||
_priority = conicalView.computePriority(entity);
|
_priority = conicalView.computePriority(entity);
|
||||||
|
@ -73,14 +73,14 @@ float TreeTraversalPath::PrioritizedEntity::updatePriority(const TreeTraversalPa
|
||||||
return _priority;
|
return _priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeTraversalPath::Fork::Fork(EntityTreeElementPointer& element) : _nextIndex(0) {
|
Fork::Fork(EntityTreeElementPointer& element) : _nextIndex(0) {
|
||||||
assert(element);
|
assert(element);
|
||||||
_weakElement = element;
|
_weakElement = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTreeElementPointer TreeTraversalPath::Fork::getNextElementFirstTime(const ViewFrustum& view) {
|
EntityTreeElementPointer Fork::getNextElementFirstTime(const ViewFrustum& view) {
|
||||||
if (_nextIndex == -1) {
|
if (_nextIndex == -1) {
|
||||||
// only get here for the TreeTraversalPath's root Fork at the very beginning of traversal
|
// only get here for the root Fork at the very beginning of traversal
|
||||||
// safe to assume this element is in view
|
// safe to assume this element is in view
|
||||||
++_nextIndex;
|
++_nextIndex;
|
||||||
return _weakElement.lock();
|
return _weakElement.lock();
|
||||||
|
@ -99,9 +99,9 @@ EntityTreeElementPointer TreeTraversalPath::Fork::getNextElementFirstTime(const
|
||||||
return EntityTreeElementPointer();
|
return EntityTreeElementPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTreeElementPointer TreeTraversalPath::Fork::getNextElementAgain(const ViewFrustum& view, uint64_t lastTime) {
|
EntityTreeElementPointer Fork::getNextElementAgain(const ViewFrustum& view, uint64_t lastTime) {
|
||||||
if (_nextIndex == -1) {
|
if (_nextIndex == -1) {
|
||||||
// only get here for the TreeTraversalPath's root Fork at the very beginning of traversal
|
// only get here for the root Fork at the very beginning of traversal
|
||||||
// safe to assume this element is in view
|
// safe to assume this element is in view
|
||||||
++_nextIndex;
|
++_nextIndex;
|
||||||
EntityTreeElementPointer element = _weakElement.lock();
|
EntityTreeElementPointer element = _weakElement.lock();
|
||||||
|
@ -123,9 +123,9 @@ EntityTreeElementPointer TreeTraversalPath::Fork::getNextElementAgain(const View
|
||||||
return EntityTreeElementPointer();
|
return EntityTreeElementPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTreeElementPointer TreeTraversalPath::Fork::getNextElementDifferential(const ViewFrustum& view, const ViewFrustum& lastView, uint64_t lastTime) {
|
EntityTreeElementPointer Fork::getNextElementDifferential(const ViewFrustum& view, const ViewFrustum& lastView, uint64_t lastTime) {
|
||||||
if (_nextIndex == -1) {
|
if (_nextIndex == -1) {
|
||||||
// only get here for the TreeTraversalPath's root Fork at the very beginning of traversal
|
// only get here for the root Fork at the very beginning of traversal
|
||||||
// safe to assume this element is in view
|
// safe to assume this element is in view
|
||||||
++_nextIndex;
|
++_nextIndex;
|
||||||
EntityTreeElementPointer element = _weakElement.lock();
|
EntityTreeElementPointer element = _weakElement.lock();
|
||||||
|
@ -149,77 +149,12 @@ EntityTreeElementPointer TreeTraversalPath::Fork::getNextElementDifferential(con
|
||||||
return EntityTreeElementPointer();
|
return EntityTreeElementPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeTraversalPath::TreeTraversalPath() {
|
EntityTreeSendThread::EntityTreeSendThread(OctreeServer* myServer, const SharedNodePointer& node)
|
||||||
|
: OctreeSendThread(myServer, node) {
|
||||||
const int32_t MIN_PATH_DEPTH = 16;
|
const int32_t MIN_PATH_DEPTH = 16;
|
||||||
_forks.reserve(MIN_PATH_DEPTH);
|
_forks.reserve(MIN_PATH_DEPTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeTraversalPath::startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root) {
|
|
||||||
if (_startOfCompletedTraversal == 0) {
|
|
||||||
_currentView = viewFrustum;
|
|
||||||
_getNextElementCallback = [&]() {
|
|
||||||
return _forks.back().getNextElementFirstTime(_currentView);
|
|
||||||
};
|
|
||||||
|
|
||||||
} else if (_currentView.isVerySimilar(viewFrustum)) {
|
|
||||||
_getNextElementCallback = [&]() {
|
|
||||||
return _forks.back().getNextElementAgain(_currentView, _startOfCompletedTraversal);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_currentView = viewFrustum;
|
|
||||||
_getNextElementCallback = [&]() {
|
|
||||||
return _forks.back().getNextElementDifferential(_currentView, _completedView, _startOfCompletedTraversal);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
_forks.clear();
|
|
||||||
assert(root);
|
|
||||||
_forks.push_back(Fork(root));
|
|
||||||
// set root fork's index such that root element returned at getNextElement()
|
|
||||||
_forks.back().initRootNextIndex();
|
|
||||||
|
|
||||||
_startOfCurrentTraversal = usecTimestampNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityTreeElementPointer TreeTraversalPath::getNextElement() {
|
|
||||||
if (_forks.empty()) {
|
|
||||||
return EntityTreeElementPointer();
|
|
||||||
}
|
|
||||||
EntityTreeElementPointer nextElement = _getNextElementCallback();
|
|
||||||
if (nextElement) {
|
|
||||||
int8_t nextIndex = _forks.back().getNextIndex();
|
|
||||||
if (nextIndex > 0) {
|
|
||||||
// nextElement needs to be added to the path
|
|
||||||
_forks.push_back(Fork(nextElement));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// we're done at this level
|
|
||||||
while (!nextElement) {
|
|
||||||
// pop one level
|
|
||||||
_forks.pop_back();
|
|
||||||
if (_forks.empty()) {
|
|
||||||
// we've traversed the entire tree
|
|
||||||
_completedView = _currentView;
|
|
||||||
_startOfCompletedTraversal = _startOfCurrentTraversal;
|
|
||||||
return nextElement;
|
|
||||||
}
|
|
||||||
// keep looking for nextElement
|
|
||||||
nextElement = _getNextElementCallback();
|
|
||||||
if (nextElement) {
|
|
||||||
// we've descended one level so add it to the path
|
|
||||||
_forks.push_back(Fork(nextElement));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nextElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeTraversalPath::dump() const {
|
|
||||||
for (size_t i = 0; i < _forks.size(); ++i) {
|
|
||||||
std::cout << (int32_t)(_forks[i].getNextIndex()) << "-->";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EntityTreeSendThread::preDistributionProcessing() {
|
void EntityTreeSendThread::preDistributionProcessing() {
|
||||||
auto node = _node.toStrongRef();
|
auto node = _node.toStrongRef();
|
||||||
auto nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
auto nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
||||||
|
@ -291,31 +226,30 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
||||||
ViewFrustum viewFrustum;
|
ViewFrustum viewFrustum;
|
||||||
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());
|
||||||
_path.startNewTraversal(viewFrustum, root);
|
startNewTraversal(viewFrustum, root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_path.empty()) {
|
if (!_forks.empty()) {
|
||||||
uint64_t t0 = usecTimestampNow();
|
uint64_t t0 = usecTimestampNow();
|
||||||
uint64_t now = t0;
|
uint64_t now = t0;
|
||||||
|
|
||||||
const ViewFrustum& currentView = _path.getCurrentView();
|
ConicalView conicalView(_currentView);
|
||||||
TreeTraversalPath::ConicalView conicalView(currentView);
|
EntityTreeElementPointer nextElement = getNextElement();
|
||||||
EntityTreeElementPointer nextElement = _path.getNextElement();
|
|
||||||
while (nextElement) {
|
while (nextElement) {
|
||||||
nextElement->forEachEntity([&](EntityItemPointer entity) {
|
nextElement->forEachEntity([&](EntityItemPointer entity) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
AACube cube = entity->getQueryAACube(success);
|
AACube cube = entity->getQueryAACube(success);
|
||||||
if (success) {
|
if (success) {
|
||||||
if (currentView.cubeIntersectsKeyhole(cube)) {
|
if (_currentView.cubeIntersectsKeyhole(cube)) {
|
||||||
float priority = conicalView.computePriority(cube);
|
float priority = conicalView.computePriority(cube);
|
||||||
_sendQueue.push(TreeTraversalPath::PrioritizedEntity(entity, priority));
|
_sendQueue.push(PrioritizedEntity(entity, priority));
|
||||||
std::cout << "adebug '" << entity->getName().toStdString() << "' send = " << (priority != DO_NOT_SEND) << std::endl; // adebug
|
std::cout << "adebug '" << entity->getName().toStdString() << "' send = " << (priority != DO_NOT_SEND) << std::endl; // adebug
|
||||||
} else {
|
} else {
|
||||||
std::cout << "adebug '" << entity->getName().toStdString() << "' out of view" << std::endl; // adebug
|
std::cout << "adebug '" << entity->getName().toStdString() << "' out of view" << std::endl; // adebug
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
|
const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
|
||||||
_sendQueue.push(TreeTraversalPath::PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY));
|
_sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -324,14 +258,14 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
||||||
if (now - t0 > PARTIAL_TRAVERSAL_TIME_BUDGET) {
|
if (now - t0 > PARTIAL_TRAVERSAL_TIME_BUDGET) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nextElement = _path.getNextElement();
|
nextElement = getNextElement();
|
||||||
}
|
}
|
||||||
uint64_t dt1 = now - t0;
|
uint64_t dt1 = now - t0;
|
||||||
|
|
||||||
//} else if (!_sendQueue.empty()) {
|
//} else if (!_sendQueue.empty()) {
|
||||||
size_t sendQueueSize = _sendQueue.size();
|
size_t sendQueueSize = _sendQueue.size();
|
||||||
while (!_sendQueue.empty()) {
|
while (!_sendQueue.empty()) {
|
||||||
TreeTraversalPath::PrioritizedEntity entry = _sendQueue.top();
|
PrioritizedEntity entry = _sendQueue.top();
|
||||||
EntityItemPointer entity = entry.getEntity();
|
EntityItemPointer entity = entry.getEntity();
|
||||||
if (entity) {
|
if (entity) {
|
||||||
std::cout << "adebug '" << entity->getName().toStdString() << "'"
|
std::cout << "adebug '" << entity->getName().toStdString() << "'"
|
||||||
|
@ -400,4 +334,68 @@ bool EntityTreeSendThread::addDescendantsToExtraFlaggedEntities(const QUuid& fil
|
||||||
return hasNewChild || hasNewDescendants;
|
return hasNewChild || hasNewDescendants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityTreeSendThread::startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root) {
|
||||||
|
if (_startOfCompletedTraversal == 0) {
|
||||||
|
_currentView = viewFrustum;
|
||||||
|
_getNextElementCallback = [&]() {
|
||||||
|
return _forks.back().getNextElementFirstTime(_currentView);
|
||||||
|
};
|
||||||
|
|
||||||
|
} else if (_currentView.isVerySimilar(viewFrustum)) {
|
||||||
|
_getNextElementCallback = [&]() {
|
||||||
|
return _forks.back().getNextElementAgain(_currentView, _startOfCompletedTraversal);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
_currentView = viewFrustum;
|
||||||
|
_getNextElementCallback = [&]() {
|
||||||
|
return _forks.back().getNextElementDifferential(_currentView, _completedView, _startOfCompletedTraversal);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_forks.clear();
|
||||||
|
assert(root);
|
||||||
|
_forks.push_back(Fork(root));
|
||||||
|
// set root fork's index such that root element returned at getNextElement()
|
||||||
|
_forks.back().initRootNextIndex();
|
||||||
|
|
||||||
|
_startOfCurrentTraversal = usecTimestampNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityTreeElementPointer EntityTreeSendThread::getNextElement() {
|
||||||
|
if (_forks.empty()) {
|
||||||
|
return EntityTreeElementPointer();
|
||||||
|
}
|
||||||
|
EntityTreeElementPointer nextElement = _getNextElementCallback();
|
||||||
|
if (nextElement) {
|
||||||
|
int8_t nextIndex = _forks.back().getNextIndex();
|
||||||
|
if (nextIndex > 0) {
|
||||||
|
// nextElement needs to be added to the path
|
||||||
|
_forks.push_back(Fork(nextElement));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we're done at this level
|
||||||
|
while (!nextElement) {
|
||||||
|
// pop one level
|
||||||
|
_forks.pop_back();
|
||||||
|
if (_forks.empty()) {
|
||||||
|
// we've traversed the entire tree
|
||||||
|
_completedView = _currentView;
|
||||||
|
_startOfCompletedTraversal = _startOfCurrentTraversal;
|
||||||
|
return nextElement;
|
||||||
|
}
|
||||||
|
// keep looking for nextElement
|
||||||
|
nextElement = _getNextElementCallback();
|
||||||
|
if (nextElement) {
|
||||||
|
// we've descended one level so add it to the path
|
||||||
|
_forks.push_back(Fork(nextElement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nextElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityTreeSendThread::dump() const {
|
||||||
|
for (size_t i = 0; i < _forks.size(); ++i) {
|
||||||
|
std::cout << (int32_t)(_forks[i].getNextIndex()) << "-->";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,87 +27,61 @@ class EntityNodeData;
|
||||||
class EntityItem;
|
class EntityItem;
|
||||||
|
|
||||||
|
|
||||||
class TreeTraversalPath {
|
class ConicalView {
|
||||||
public:
|
public:
|
||||||
class ConicalView {
|
ConicalView() {}
|
||||||
public:
|
ConicalView(const ViewFrustum& viewFrustum) { set(viewFrustum); }
|
||||||
ConicalView() {}
|
void set(const ViewFrustum& viewFrustum);
|
||||||
ConicalView(const ViewFrustum& viewFrustum) { set(viewFrustum); }
|
float computePriority(const AACube& cube) const;
|
||||||
void set(const ViewFrustum& viewFrustum);
|
float computePriority(const EntityItemPointer& entity) const;
|
||||||
float computePriority(const AACube& cube) const;
|
private:
|
||||||
float computePriority(const EntityItemPointer& entity) const;
|
glm::vec3 _position { 0.0f, 0.0f, 0.0f };
|
||||||
private:
|
glm::vec3 _direction { 0.0f, 0.0f, 1.0f };
|
||||||
glm::vec3 _position { 0.0f, 0.0f, 0.0f };
|
float _sinAngle { SQRT_TWO_OVER_TWO };
|
||||||
glm::vec3 _direction { 0.0f, 0.0f, 1.0f };
|
float _cosAngle { SQRT_TWO_OVER_TWO };
|
||||||
float _sinAngle { SQRT_TWO_OVER_TWO };
|
float _radius { DEFAULT_VIEW_RADIUS };
|
||||||
float _cosAngle { SQRT_TWO_OVER_TWO };
|
|
||||||
float _radius { DEFAULT_VIEW_RADIUS };
|
|
||||||
};
|
|
||||||
|
|
||||||
class PrioritizedEntity {
|
|
||||||
public:
|
|
||||||
PrioritizedEntity(EntityItemPointer entity, float priority) : _weakEntity(entity), _priority(priority) { }
|
|
||||||
float updatePriority(const ConicalView& view);
|
|
||||||
EntityItemPointer getEntity() const { return _weakEntity.lock(); }
|
|
||||||
float getPriority() const { return _priority; }
|
|
||||||
|
|
||||||
class Compare {
|
|
||||||
public:
|
|
||||||
bool operator() (const PrioritizedEntity& A, const PrioritizedEntity& B) { return A._priority < B._priority; }
|
|
||||||
};
|
|
||||||
friend class Compare;
|
|
||||||
|
|
||||||
private:
|
|
||||||
EntityItemWeakPointer _weakEntity;
|
|
||||||
float _priority;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Fork {
|
|
||||||
public:
|
|
||||||
Fork(EntityTreeElementPointer& element);
|
|
||||||
|
|
||||||
EntityTreeElementPointer getNextElementFirstTime(const ViewFrustum& view);
|
|
||||||
EntityTreeElementPointer getNextElementAgain(const ViewFrustum& view, uint64_t lastTime);
|
|
||||||
EntityTreeElementPointer getNextElementDifferential(const ViewFrustum& view, const ViewFrustum& lastView, uint64_t lastTime);
|
|
||||||
|
|
||||||
int8_t getNextIndex() const { return _nextIndex; }
|
|
||||||
void initRootNextIndex() { _nextIndex = -1; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
EntityTreeElementWeakPointer _weakElement;
|
|
||||||
int8_t _nextIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
TreeTraversalPath();
|
|
||||||
|
|
||||||
void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root);
|
|
||||||
|
|
||||||
EntityTreeElementPointer getNextElement();
|
|
||||||
|
|
||||||
const ViewFrustum& getView() const { return _currentView; }
|
|
||||||
|
|
||||||
bool empty() const { return _forks.empty(); }
|
|
||||||
size_t size() const { return _forks.size(); } // adebug
|
|
||||||
void dump() const;
|
|
||||||
|
|
||||||
const ViewFrustum& getCurrentView() const { return _currentView; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ViewFrustum _currentView;
|
|
||||||
ViewFrustum _completedView;
|
|
||||||
std::vector<Fork> _forks;
|
|
||||||
std::function<EntityTreeElementPointer()> _getNextElementCallback { nullptr };
|
|
||||||
uint64_t _startOfCompletedTraversal { 0 };
|
|
||||||
uint64_t _startOfCurrentTraversal { 0 };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using EntityPriorityQueue = std::priority_queue< TreeTraversalPath::PrioritizedEntity, std::vector<TreeTraversalPath::PrioritizedEntity>, TreeTraversalPath::PrioritizedEntity::Compare >;
|
class PrioritizedEntity {
|
||||||
|
public:
|
||||||
|
PrioritizedEntity(EntityItemPointer entity, float priority) : _weakEntity(entity), _priority(priority) { }
|
||||||
|
float updatePriority(const ConicalView& view);
|
||||||
|
EntityItemPointer getEntity() const { return _weakEntity.lock(); }
|
||||||
|
float getPriority() const { return _priority; }
|
||||||
|
|
||||||
|
class Compare {
|
||||||
|
public:
|
||||||
|
bool operator() (const PrioritizedEntity& A, const PrioritizedEntity& B) { return A._priority < B._priority; }
|
||||||
|
};
|
||||||
|
friend class Compare;
|
||||||
|
|
||||||
|
private:
|
||||||
|
EntityItemWeakPointer _weakEntity;
|
||||||
|
float _priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Fork {
|
||||||
|
public:
|
||||||
|
Fork(EntityTreeElementPointer& element);
|
||||||
|
|
||||||
|
EntityTreeElementPointer getNextElementFirstTime(const ViewFrustum& view);
|
||||||
|
EntityTreeElementPointer getNextElementAgain(const ViewFrustum& view, uint64_t lastTime);
|
||||||
|
EntityTreeElementPointer getNextElementDifferential(const ViewFrustum& view, const ViewFrustum& lastView, uint64_t lastTime);
|
||||||
|
|
||||||
|
int8_t getNextIndex() const { return _nextIndex; }
|
||||||
|
void initRootNextIndex() { _nextIndex = -1; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EntityTreeElementWeakPointer _weakElement;
|
||||||
|
int8_t _nextIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
using EntityPriorityQueue = std::priority_queue< PrioritizedEntity, std::vector<PrioritizedEntity>, PrioritizedEntity::Compare >;
|
||||||
|
|
||||||
|
|
||||||
class EntityTreeSendThread : public OctreeSendThread {
|
class EntityTreeSendThread : public OctreeSendThread {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EntityTreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) : OctreeSendThread(myServer, node) {};
|
EntityTreeSendThread(OctreeServer* myServer, const SharedNodePointer& node);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void preDistributionProcessing() override;
|
void preDistributionProcessing() override;
|
||||||
|
@ -119,8 +93,17 @@ private:
|
||||||
bool addAncestorsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
bool addAncestorsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
||||||
bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData);
|
||||||
|
|
||||||
TreeTraversalPath _path;
|
void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root);
|
||||||
|
EntityTreeElementPointer getNextElement();
|
||||||
|
void dump() const;
|
||||||
|
|
||||||
EntityPriorityQueue _sendQueue;
|
EntityPriorityQueue _sendQueue;
|
||||||
|
ViewFrustum _currentView;
|
||||||
|
ViewFrustum _completedView;
|
||||||
|
std::vector<Fork> _forks;
|
||||||
|
std::function<EntityTreeElementPointer()> _getNextElementCallback { nullptr };
|
||||||
|
uint64_t _startOfCompletedTraversal { 0 };
|
||||||
|
uint64_t _startOfCurrentTraversal { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityTreeSendThread_h
|
#endif // hifi_EntityTreeSendThread_h
|
||||||
|
|
Loading…
Reference in a new issue