mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 12:09:52 +02:00
Merge pull request #9718 from AndrewMeadows/sort-avatars-correctly
fix sorting algorithm for avatar render updates
This commit is contained in:
commit
97fc88491f
2 changed files with 46 additions and 10 deletions
|
@ -154,8 +154,7 @@ public:
|
||||||
AvatarPriority(AvatarSharedPointer a, float p) : avatar(a), priority(p) {}
|
AvatarPriority(AvatarSharedPointer a, float p) : avatar(a), priority(p) {}
|
||||||
AvatarSharedPointer avatar;
|
AvatarSharedPointer avatar;
|
||||||
float priority;
|
float priority;
|
||||||
// NOTE: we invert the less-than operator to sort high priorities to front
|
bool operator<(const AvatarPriority& other) const { return priority < other.priority; }
|
||||||
bool operator<(const AvatarPriority& other) const { return priority > other.priority; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void AvatarManager::updateOtherAvatars(float deltaTime) {
|
void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
|
@ -205,15 +204,17 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
float distance = glm::length(offset) + 0.001f; // add 1mm to avoid divide by zero
|
float distance = glm::length(offset) + 0.001f; // add 1mm to avoid divide by zero
|
||||||
float radius = avatar->getBoundingRadius();
|
float radius = avatar->getBoundingRadius();
|
||||||
const glm::vec3& forward = cameraView.getDirection();
|
const glm::vec3& forward = cameraView.getDirection();
|
||||||
float apparentSize = radius / distance;
|
float apparentSize = 2.0f * radius / distance;
|
||||||
float cosineAngle = glm::length(offset - glm::dot(offset, forward) * forward) / distance;
|
float cosineAngle = glm::length(glm::dot(offset, forward) * forward) / distance;
|
||||||
const float TIME_PENALTY = 0.080f; // seconds
|
float age = (float)(startTime - avatar->getLastRenderUpdateTime()) / (float)(USECS_PER_SECOND);
|
||||||
float age = (float)(startTime - avatar->getLastRenderUpdateTime()) / (float)(USECS_PER_SECOND) - TIME_PENALTY;
|
|
||||||
// NOTE: we are adding values of different units to get a single measure of "priority".
|
// NOTE: we are adding values of different units to get a single measure of "priority".
|
||||||
// Thus we multiply each component by a conversion "weight" that scales its units
|
// Thus we multiply each component by a conversion "weight" that scales its units relative to the others.
|
||||||
// relative to the others. These weights are pure magic tuning and are hard coded in the
|
// These weights are pure magic tuning and should be hard coded in the relation below,
|
||||||
// relation below: (hint: unitary weights are not explicityly shown)
|
// but are currently exposed for anyone who would like to explore fine tuning:
|
||||||
float priority = apparentSize + 0.25f * cosineAngle + age;
|
float priority = _avatarSortCoefficientSize * apparentSize
|
||||||
|
+ _avatarSortCoefficientCenter * cosineAngle
|
||||||
|
+ _avatarSortCoefficientAge * age;
|
||||||
|
|
||||||
// decrement priority of avatars outside keyhole
|
// decrement priority of avatars outside keyhole
|
||||||
if (distance > cameraView.getCenterRadius()) {
|
if (distance > cameraView.getCenterRadius()) {
|
||||||
|
@ -593,3 +594,29 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersection(const PickRay&
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK
|
||||||
|
float AvatarManager::getAvatarSortCoefficient(const QString& name) {
|
||||||
|
if (name == "size") {
|
||||||
|
return _avatarSortCoefficientSize;
|
||||||
|
} else if (name == "center") {
|
||||||
|
return _avatarSortCoefficientCenter;
|
||||||
|
} else if (name == "age") {
|
||||||
|
return _avatarSortCoefficientAge;
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK
|
||||||
|
void AvatarManager::setAvatarSortCoefficient(const QString& name, const QScriptValue& value) {
|
||||||
|
if (value.isNumber()) {
|
||||||
|
float numericalValue = (float)value.toNumber();
|
||||||
|
if (name == "size") {
|
||||||
|
_avatarSortCoefficientSize = numericalValue;
|
||||||
|
} else if (name == "center") {
|
||||||
|
_avatarSortCoefficientCenter = numericalValue;
|
||||||
|
} else if (name == "age") {
|
||||||
|
_avatarSortCoefficientAge = numericalValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -81,6 +81,10 @@ public:
|
||||||
const QScriptValue& avatarIdsToInclude = QScriptValue(),
|
const QScriptValue& avatarIdsToInclude = QScriptValue(),
|
||||||
const QScriptValue& avatarIdsToDiscard = QScriptValue());
|
const QScriptValue& avatarIdsToDiscard = QScriptValue());
|
||||||
|
|
||||||
|
// TODO: remove this HACK once we settle on optimal default sort coefficients
|
||||||
|
Q_INVOKABLE float getAvatarSortCoefficient(const QString& name);
|
||||||
|
Q_INVOKABLE void setAvatarSortCoefficient(const QString& name, const QScriptValue& value);
|
||||||
|
|
||||||
float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); }
|
float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -120,6 +124,11 @@ private:
|
||||||
int _partiallySimulatedAvatars { 0 };
|
int _partiallySimulatedAvatars { 0 };
|
||||||
float _avatarSimulationTime { 0.0f };
|
float _avatarSimulationTime { 0.0f };
|
||||||
|
|
||||||
|
// TODO: remove this HACK once we settle on optimal sort coefficients
|
||||||
|
// These coefficients exposed for fine tuning the sort priority for transfering new _jointData to the render pipeline.
|
||||||
|
float _avatarSortCoefficientSize { 0.5f };
|
||||||
|
float _avatarSortCoefficientCenter { 0.25 };
|
||||||
|
float _avatarSortCoefficientAge { 1.0f };
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(AvatarManager::LocalLight)
|
Q_DECLARE_METATYPE(AvatarManager::LocalLight)
|
||||||
|
|
Loading…
Reference in a new issue