mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 19:59:28 +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 <shared/QtHelpers.h>
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
#include <PrioritySortUtil.h>
|
||||||
#include <RegisteredMetaTypes.h>
|
#include <RegisteredMetaTypes.h>
|
||||||
#include <Rig.h>
|
#include <Rig.h>
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
|
@ -142,32 +143,36 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
|
|
||||||
PerformanceTimer perfTimer("otherAvatars");
|
PerformanceTimer perfTimer("otherAvatars");
|
||||||
|
|
||||||
auto avatarMap = getHashCopy();
|
class SortableAvatar: public PrioritySortUtil::Sortable {
|
||||||
QList<AvatarSharedPointer> avatarList = avatarMap.values();
|
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;
|
ViewFrustum cameraView;
|
||||||
qApp->copyDisplayViewFrustum(cameraView);
|
qApp->copyDisplayViewFrustum(cameraView);
|
||||||
|
PrioritySortUtil::PriorityQueue<SortableAvatar> sortedAvatars(cameraView);
|
||||||
|
|
||||||
std::priority_queue<AvatarPriority> sortedAvatars;
|
// sort
|
||||||
AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars,
|
auto avatarMap = getHashCopy();
|
||||||
|
AvatarHash::iterator itr = avatarMap.begin();
|
||||||
[](AvatarSharedPointer avatar)->uint64_t{
|
while (itr != avatarMap.end()) {
|
||||||
return std::static_pointer_cast<Avatar>(avatar)->getLastRenderUpdateTime();
|
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
|
||||||
[](AvatarSharedPointer avatar)->float{
|
if (avatar != _myAvatar && avatar->isInitialized()) {
|
||||||
return std::static_pointer_cast<Avatar>(avatar)->getBoundingRadius();
|
sortedAvatars.push(SortableAvatar(avatar));
|
||||||
},
|
}
|
||||||
|
++itr;
|
||||||
[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;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// process in sorted order
|
||||||
uint64_t startTime = usecTimestampNow();
|
uint64_t startTime = usecTimestampNow();
|
||||||
const uint64_t UPDATE_BUDGET = 2000; // usec
|
const uint64_t UPDATE_BUDGET = 2000; // usec
|
||||||
uint64_t updateExpiry = startTime + UPDATE_BUDGET;
|
uint64_t updateExpiry = startTime + UPDATE_BUDGET;
|
||||||
|
@ -176,8 +181,8 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
|
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
while (!sortedAvatars.empty()) {
|
while (!sortedAvatars.empty()) {
|
||||||
const AvatarPriority& sortData = sortedAvatars.top();
|
const SortableAvatar& sortData = sortedAvatars.top();
|
||||||
const auto& avatar = std::static_pointer_cast<Avatar>(sortData.avatar);
|
const auto& avatar = std::static_pointer_cast<Avatar>(sortData.getAvatar());
|
||||||
|
|
||||||
bool ignoring = DependencyManager::get<NodeList>()->isPersonalMutingNode(avatar->getID());
|
bool ignoring = DependencyManager::get<NodeList>()->isPersonalMutingNode(avatar->getID());
|
||||||
if (ignoring) {
|
if (ignoring) {
|
||||||
|
@ -207,7 +212,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
if (now < updateExpiry) {
|
if (now < updateExpiry) {
|
||||||
// we're within budget
|
// we're within budget
|
||||||
bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD;
|
bool inView = sortData.getPriority() > OUT_OF_VIEW_THRESHOLD;
|
||||||
if (inView && avatar->hasNewJointData()) {
|
if (inView && avatar->hasNewJointData()) {
|
||||||
numAvatarsUpdated++;
|
numAvatarsUpdated++;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +226,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
// --> some avatar velocity measurements may be a little off
|
// --> some avatar velocity measurements may be a little off
|
||||||
|
|
||||||
// no time simulate, but we take the time to count how many were tragically missed
|
// 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) {
|
if (!inView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -230,9 +235,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
}
|
}
|
||||||
sortedAvatars.pop();
|
sortedAvatars.pop();
|
||||||
while (inView && !sortedAvatars.empty()) {
|
while (inView && !sortedAvatars.empty()) {
|
||||||
const AvatarPriority& newSortData = sortedAvatars.top();
|
const SortableAvatar& newSortData = sortedAvatars.top();
|
||||||
const auto& newAvatar = std::static_pointer_cast<Avatar>(newSortData.avatar);
|
const auto& newAvatar = std::static_pointer_cast<Avatar>(newSortData.getAvatar());
|
||||||
inView = newSortData.priority > OUT_OF_VIEW_THRESHOLD;
|
inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD;
|
||||||
if (inView && newAvatar->hasNewJointData()) {
|
if (inView && newAvatar->hasNewJointData()) {
|
||||||
numAVatarsNotUpdated++;
|
numAVatarsNotUpdated++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,11 +32,10 @@
|
||||||
|
|
||||||
(2) Make a PrioritySortUtil::PriorityQueue<Thing> and add them to the queue:
|
(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;
|
std::priority_queue< PrioritySortUtil::Sortable<Thing> > sortedThings;
|
||||||
for (thing in things) {
|
for (thing in things) {
|
||||||
float priority = prioritizer.computePriority(PrioritySortUtil::PrioritizableThing(thing));
|
sortedThings.push(SortableWrapper(thing));
|
||||||
sortedThings.push(PrioritySortUtil::Sortable<Thing> entry(thing, priority));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(3) Loop over your priority queue and do timeboxed work:
|
(3) Loop over your priority queue and do timeboxed work:
|
||||||
|
@ -65,6 +64,7 @@ namespace PrioritySortUtil {
|
||||||
virtual uint64_t getTimestamp() const = 0;
|
virtual uint64_t getTimestamp() const = 0;
|
||||||
|
|
||||||
void setPriority(float priority) { _priority = priority; }
|
void setPriority(float priority) { _priority = priority; }
|
||||||
|
float getPriority() const { return _priority; }
|
||||||
bool operator<(const Sortable& other) const { return _priority < other._priority; }
|
bool operator<(const Sortable& other) const { return _priority < other._priority; }
|
||||||
private:
|
private:
|
||||||
float _priority { 0.0f };
|
float _priority { 0.0f };
|
||||||
|
|
Loading…
Reference in a new issue