mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
sort and throttle avatar updates in interface
This commit is contained in:
parent
e6c6e5f239
commit
d65101c4e9
2 changed files with 37 additions and 32 deletions
|
@ -28,6 +28,7 @@
|
|||
#include <shared/QtHelpers.h>
|
||||
#include <AvatarData.h>
|
||||
#include <PerfStat.h>
|
||||
#include <PrioritySortUtil.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <Rig.h>
|
||||
#include <SettingHandle.h>
|
||||
|
@ -142,32 +143,36 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
|||
|
||||
PerformanceTimer perfTimer("otherAvatars");
|
||||
|
||||
auto avatarMap = getHashCopy();
|
||||
QList<AvatarSharedPointer> 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>(_avatar)->getBoundingRadius(); }
|
||||
uint64_t getTimestamp() const override { return std::static_pointer_cast<Avatar>(_avatar)->getLastRenderUpdateTime(); }
|
||||
const AvatarSharedPointer& getAvatar() const { return _avatar; }
|
||||
private:
|
||||
AvatarSharedPointer _avatar;
|
||||
};
|
||||
|
||||
ViewFrustum cameraView;
|
||||
qApp->copyDisplayViewFrustum(cameraView);
|
||||
PrioritySortUtil::PriorityQueue<SortableAvatar> sortedAvatars(cameraView);
|
||||
|
||||
std::priority_queue<AvatarPriority> sortedAvatars;
|
||||
AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars,
|
||||
|
||||
[](AvatarSharedPointer avatar)->uint64_t{
|
||||
return std::static_pointer_cast<Avatar>(avatar)->getLastRenderUpdateTime();
|
||||
},
|
||||
|
||||
[](AvatarSharedPointer avatar)->float{
|
||||
return std::static_pointer_cast<Avatar>(avatar)->getBoundingRadius();
|
||||
},
|
||||
|
||||
[this](AvatarSharedPointer avatar)->bool{
|
||||
const auto& castedAvatar = std::static_pointer_cast<Avatar>(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<Avatar>(*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<Avatar>(sortData.avatar);
|
||||
const SortableAvatar& sortData = sortedAvatars.top();
|
||||
const auto& avatar = std::static_pointer_cast<Avatar>(sortData.getAvatar());
|
||||
|
||||
bool ignoring = DependencyManager::get<NodeList>()->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<Avatar>(newSortData.avatar);
|
||||
inView = newSortData.priority > OUT_OF_VIEW_THRESHOLD;
|
||||
const SortableAvatar& newSortData = sortedAvatars.top();
|
||||
const auto& newAvatar = std::static_pointer_cast<Avatar>(newSortData.getAvatar());
|
||||
inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD;
|
||||
if (inView && newAvatar->hasNewJointData()) {
|
||||
numAVatarsNotUpdated++;
|
||||
}
|
||||
|
|
|
@ -32,11 +32,10 @@
|
|||
|
||||
(2) Make a PrioritySortUtil::PriorityQueue<Thing> and add them to the queue:
|
||||
|
||||
PrioritySortUtil::Prioritizer prioritizer(viewFrustum);
|
||||
PrioritySortUtil::PriorityQueue<SortableWrapper> sortedThings(viewFrustum);
|
||||
std::priority_queue< PrioritySortUtil::Sortable<Thing> > sortedThings;
|
||||
for (thing in things) {
|
||||
float priority = prioritizer.computePriority(PrioritySortUtil::PrioritizableThing(thing));
|
||||
sortedThings.push(PrioritySortUtil::Sortable<Thing> 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 };
|
||||
|
|
Loading…
Reference in a new issue