diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 9ffe74d470..6441415cb8 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -142,32 +143,36 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { PerformanceTimer perfTimer("otherAvatars"); - auto avatarMap = getHashCopy(); - QList avatarList = avatarMap.values(); + class SortableAvatar: public PrioritySortUtil::Sortable { + public: + SortableAvatar() = delete; + SortableAvatar(const AvatarSharedPointer& avatar) : _avatar(avatar) {} + glm::vec3 getPosition() const override { return _avatar->getPosition(); } + float getRadius() const override { return std::static_pointer_cast(_avatar)->getBoundingRadius(); } + uint64_t getTimestamp() const override { return std::static_pointer_cast(_avatar)->getLastRenderUpdateTime(); } + const AvatarSharedPointer& getAvatar() const { return _avatar; } + private: + AvatarSharedPointer _avatar; + }; + ViewFrustum cameraView; qApp->copyDisplayViewFrustum(cameraView); + PrioritySortUtil::PriorityQueue sortedAvatars(cameraView); - std::priority_queue sortedAvatars; - AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars, - - [](AvatarSharedPointer avatar)->uint64_t{ - return std::static_pointer_cast(avatar)->getLastRenderUpdateTime(); - }, - - [](AvatarSharedPointer avatar)->float{ - return std::static_pointer_cast(avatar)->getBoundingRadius(); - }, - - [this](AvatarSharedPointer avatar)->bool{ - const auto& castedAvatar = std::static_pointer_cast(avatar); - if (castedAvatar == _myAvatar || !castedAvatar->isInitialized()) { - // DO NOT update _myAvatar! Its update has already been done earlier in the main loop. - // DO NOT update or fade out uninitialized Avatars - return true; // ignore it - } - return false; - }); + // sort + auto avatarMap = getHashCopy(); + AvatarHash::iterator itr = avatarMap.begin(); + while (itr != avatarMap.end()) { + const auto& avatar = std::static_pointer_cast(*itr); + // DO NOT update _myAvatar! Its update has already been done earlier in the main loop. + // DO NOT update or fade out uninitialized Avatars + if (avatar != _myAvatar && avatar->isInitialized()) { + sortedAvatars.push(SortableAvatar(avatar)); + } + ++itr; + } + // process in sorted order uint64_t startTime = usecTimestampNow(); const uint64_t UPDATE_BUDGET = 2000; // usec uint64_t updateExpiry = startTime + UPDATE_BUDGET; @@ -176,8 +181,8 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { render::Transaction transaction; while (!sortedAvatars.empty()) { - const AvatarPriority& sortData = sortedAvatars.top(); - const auto& avatar = std::static_pointer_cast(sortData.avatar); + const SortableAvatar& sortData = sortedAvatars.top(); + const auto& avatar = std::static_pointer_cast(sortData.getAvatar()); bool ignoring = DependencyManager::get()->isPersonalMutingNode(avatar->getID()); if (ignoring) { @@ -207,7 +212,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { uint64_t now = usecTimestampNow(); if (now < updateExpiry) { // we're within budget - bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD; + bool inView = sortData.getPriority() > OUT_OF_VIEW_THRESHOLD; if (inView && avatar->hasNewJointData()) { numAvatarsUpdated++; } @@ -221,7 +226,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { // --> some avatar velocity measurements may be a little off // no time simulate, but we take the time to count how many were tragically missed - bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD; + bool inView = sortData.getPriority() > OUT_OF_VIEW_THRESHOLD; if (!inView) { break; } @@ -230,9 +235,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { } sortedAvatars.pop(); while (inView && !sortedAvatars.empty()) { - const AvatarPriority& newSortData = sortedAvatars.top(); - const auto& newAvatar = std::static_pointer_cast(newSortData.avatar); - inView = newSortData.priority > OUT_OF_VIEW_THRESHOLD; + const SortableAvatar& newSortData = sortedAvatars.top(); + const auto& newAvatar = std::static_pointer_cast(newSortData.getAvatar()); + inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD; if (inView && newAvatar->hasNewJointData()) { numAVatarsNotUpdated++; } diff --git a/libraries/shared/src/PrioritySortUtil.h b/libraries/shared/src/PrioritySortUtil.h index 1d11a04265..6026d2b21f 100644 --- a/libraries/shared/src/PrioritySortUtil.h +++ b/libraries/shared/src/PrioritySortUtil.h @@ -32,11 +32,10 @@ (2) Make a PrioritySortUtil::PriorityQueue and add them to the queue: - PrioritySortUtil::Prioritizer prioritizer(viewFrustum); + PrioritySortUtil::PriorityQueue sortedThings(viewFrustum); std::priority_queue< PrioritySortUtil::Sortable > sortedThings; for (thing in things) { - float priority = prioritizer.computePriority(PrioritySortUtil::PrioritizableThing(thing)); - sortedThings.push(PrioritySortUtil::Sortable entry(thing, priority)); + sortedThings.push(SortableWrapper(thing)); } (3) Loop over your priority queue and do timeboxed work: @@ -65,6 +64,7 @@ namespace PrioritySortUtil { virtual uint64_t getTimestamp() const = 0; void setPriority(float priority) { _priority = priority; } + float getPriority() const { return _priority; } bool operator<(const Sortable& other) const { return _priority < other._priority; } private: float _priority { 0.0f };