mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-23 12:24:29 +02:00
Add some hysteresis on the LOD switching to prevent rapid switching back
and forth.
This commit is contained in:
parent
ff01470850
commit
078b15c02d
4 changed files with 28 additions and 6 deletions
|
@ -328,16 +328,30 @@ NetworkGeometry::~NetworkGeometry() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<NetworkGeometry> NetworkGeometry::getLODOrFallback(float distance) const {
|
QSharedPointer<NetworkGeometry> NetworkGeometry::getLODOrFallback(float distance, float& hysteresis) const {
|
||||||
if (_lodParent.data() != this) {
|
if (_lodParent.data() != this) {
|
||||||
return _lodParent.data()->getLODOrFallback(distance);
|
return _lodParent.data()->getLODOrFallback(distance, hysteresis);
|
||||||
}
|
}
|
||||||
if (_failedToLoad && _fallback) {
|
if (_failedToLoad && _fallback) {
|
||||||
return _fallback;
|
return _fallback;
|
||||||
}
|
}
|
||||||
|
QSharedPointer<NetworkGeometry> lod = _lodParent;
|
||||||
|
float lodDistance = 0.0f;
|
||||||
QMap<float, QSharedPointer<NetworkGeometry> >::const_iterator it = _lods.upperBound(distance);
|
QMap<float, QSharedPointer<NetworkGeometry> >::const_iterator it = _lods.upperBound(distance);
|
||||||
QSharedPointer<NetworkGeometry> lod = (it == _lods.constBegin()) ? _lodParent.toStrongRef() : *(it - 1);
|
if (it != _lods.constBegin()) {
|
||||||
|
it = it - 1;
|
||||||
|
lod = it.value();
|
||||||
|
lodDistance = it.key();
|
||||||
|
}
|
||||||
|
if (hysteresis != NO_HYSTERESIS && hysteresis != lodDistance) {
|
||||||
|
// if we previously selected a different distance, make sure we've moved far enough to justify switching
|
||||||
|
const float HYSTERESIS_PROPORTION = 0.1f;
|
||||||
|
if (glm::abs(distance - qMax(hysteresis, lodDistance)) / fabsf(hysteresis - lodDistance) < HYSTERESIS_PROPORTION) {
|
||||||
|
return getLODOrFallback(hysteresis, hysteresis);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (lod->isLoaded()) {
|
if (lod->isLoaded()) {
|
||||||
|
hysteresis = lodDistance;
|
||||||
return lod;
|
return lod;
|
||||||
}
|
}
|
||||||
// if the ideal LOD isn't loaded, we need to make sure it's started to load, and possibly return the closest loaded one
|
// if the ideal LOD isn't loaded, we need to make sure it's started to load, and possibly return the closest loaded one
|
||||||
|
@ -356,6 +370,7 @@ QSharedPointer<NetworkGeometry> NetworkGeometry::getLODOrFallback(float distance
|
||||||
closestDistance = distanceToLOD;
|
closestDistance = distanceToLOD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hysteresis = NO_HYSTERESIS;
|
||||||
return lod;
|
return lod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,9 @@ class NetworkGeometry : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// A hysteresis value indicating that we have no state memory.
|
||||||
|
static const float NO_HYSTERESIS = -1.0f;
|
||||||
|
|
||||||
NetworkGeometry(const QUrl& url, const QSharedPointer<NetworkGeometry>& fallback,
|
NetworkGeometry(const QUrl& url, const QSharedPointer<NetworkGeometry>& fallback,
|
||||||
const QVariantHash& mapping = QVariantHash(), const QUrl& textureBase = QUrl());
|
const QVariantHash& mapping = QVariantHash(), const QUrl& textureBase = QUrl());
|
||||||
~NetworkGeometry();
|
~NetworkGeometry();
|
||||||
|
@ -70,7 +73,8 @@ public:
|
||||||
bool isLoaded() const { return !_geometry.joints.isEmpty(); }
|
bool isLoaded() const { return !_geometry.joints.isEmpty(); }
|
||||||
|
|
||||||
/// Returns a pointer to the geometry appropriate for the specified distance.
|
/// Returns a pointer to the geometry appropriate for the specified distance.
|
||||||
QSharedPointer<NetworkGeometry> getLODOrFallback(float distance) const;
|
/// \param hysteresis a hysteresis parameter that prevents rapid model switching
|
||||||
|
QSharedPointer<NetworkGeometry> getLODOrFallback(float distance, float& hysteresis) const;
|
||||||
|
|
||||||
const FBXGeometry& getFBXGeometry() const { return _geometry; }
|
const FBXGeometry& getFBXGeometry() const { return _geometry; }
|
||||||
const QVector<NetworkMesh>& getMeshes() const { return _meshes; }
|
const QVector<NetworkMesh>& getMeshes() const { return _meshes; }
|
||||||
|
|
|
@ -93,7 +93,7 @@ void Model::simulate(float deltaTime) {
|
||||||
// update our LOD
|
// update our LOD
|
||||||
if (_geometry) {
|
if (_geometry) {
|
||||||
QSharedPointer<NetworkGeometry> geometry = _geometry->getLODOrFallback(glm::distance(_translation,
|
QSharedPointer<NetworkGeometry> geometry = _geometry->getLODOrFallback(glm::distance(_translation,
|
||||||
Application::getInstance()->getCamera()->getPosition()));
|
glm::vec3() /* Application::getInstance()->getCamera()->getPosition() */), _lodHysteresis);
|
||||||
if (_geometry != geometry) {
|
if (_geometry != geometry) {
|
||||||
deleteGeometry();
|
deleteGeometry();
|
||||||
_dilatedTextures.clear();
|
_dilatedTextures.clear();
|
||||||
|
@ -419,6 +419,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback) {
|
||||||
// delete our local geometry and custom textures
|
// delete our local geometry and custom textures
|
||||||
deleteGeometry();
|
deleteGeometry();
|
||||||
_dilatedTextures.clear();
|
_dilatedTextures.clear();
|
||||||
|
_lodHysteresis = NetworkGeometry::NO_HYSTERESIS;
|
||||||
|
|
||||||
_baseGeometry = _geometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback);
|
_baseGeometry = _geometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QSharedPointer<NetworkGeometry> _baseGeometry;
|
|
||||||
QSharedPointer<NetworkGeometry> _geometry;
|
QSharedPointer<NetworkGeometry> _geometry;
|
||||||
|
|
||||||
glm::vec3 _translation;
|
glm::vec3 _translation;
|
||||||
|
@ -237,6 +236,9 @@ private:
|
||||||
void deleteGeometry();
|
void deleteGeometry();
|
||||||
void renderMeshes(float alpha, bool translucent);
|
void renderMeshes(float alpha, bool translucent);
|
||||||
|
|
||||||
|
QSharedPointer<NetworkGeometry> _baseGeometry;
|
||||||
|
float _lodHysteresis;
|
||||||
|
|
||||||
float _pupilDilation;
|
float _pupilDilation;
|
||||||
std::vector<float> _blendshapeCoefficients;
|
std::vector<float> _blendshapeCoefficients;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue