diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 7fd24ea6b7..c88afe5a34 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -121,7 +121,7 @@ void Avatar::init() { getHead()->init(); _skeletonModel.init(); _initialized = true; - _shouldRenderBillboard = (getLODDistance() >= BILLBOARD_LOD_DISTANCE); + _shouldRenderBillboard = false; } glm::vec3 Avatar::getChestPosition() const { @@ -141,7 +141,8 @@ glm::quat Avatar::getWorldAlignedOrientation () const { } AABox Avatar::getBounds() const { - return AABox(); + // Our skeleton models are rigged, and this method call safely produces the static bounds of the model. + return _skeletonModel.getPartBounds(0, 0, getPosition(), getOrientation()); } float Avatar::getLODDistance() const { @@ -176,16 +177,18 @@ void Avatar::simulate(float deltaTime) { } animateScaleChanges(deltaTime); - // update the billboard render flag - const float BILLBOARD_HYSTERESIS_PROPORTION = 0.1f; + // update the billboard render flag. Currently used only for whether or not we animate: we do so IFF we will render the avatar. + const float MINIMUM_VISIBILITY_FOR_ON = 0.4f; + const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f; + float visibility = qApp->getViewFrustum()->calculateRenderAccuracy(getBounds(), DependencyManager::get()->getOctreeSizeScale()); if (_shouldRenderBillboard) { - if (getLODDistance() < BILLBOARD_LOD_DISTANCE * (1.0f - BILLBOARD_HYSTERESIS_PROPORTION)) { + if (visibility > MINIMUM_VISIBILITY_FOR_ON) { _shouldRenderBillboard = false; - qCDebug(interfaceapp) << "Unbillboarding" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for LOD" << getLODDistance(); + qCDebug(interfaceapp) << "Restoring" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility; } - } else if (getLODDistance() > BILLBOARD_LOD_DISTANCE * (1.0f + BILLBOARD_HYSTERESIS_PROPORTION)) { + } else if (visibility < MAXIMUM_VISIBILITY_FOR_OFF) { _shouldRenderBillboard = true; - qCDebug(interfaceapp) << "Billboarding" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for LOD" << getLODDistance(); + qCDebug(interfaceapp) << "Optimizing" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility; } // simple frustum check diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index e2d0d02af7..91c9ec623d 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1113,7 +1113,7 @@ void Model::deleteGeometry() { _blendedBlendshapeCoefficients.clear(); } -AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) { +AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const { if (!_geometry || !_geometry->isLoaded()) { return AABox(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 157c6dbf70..2c138fa7be 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -89,7 +89,7 @@ public: bool isVisible() const { return _isVisible; } void updateRenderItems(); - AABox getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation); + AABox getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const; bool maybeStartBlender();