From ca84e0e0c0b4b2844f478a549cb2cb1fbb52c898 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 22 Jun 2023 22:09:42 +0300
Subject: [PATCH] SL-5161 Avatars should stay hidden longer if they are waiting
 for meshes or skin data

---
 indra/llmath/llvolume.cpp          | 25 ++++++++--
 indra/llmath/llvolume.h            |  9 ++--
 indra/newview/llmeshrepository.cpp |  8 ++-
 indra/newview/llvoavatar.cpp       | 80 ++++++++++++++++++++++++++++++
 indra/newview/llvoavatar.h         |  1 +
 5 files changed, 116 insertions(+), 7 deletions(-)

diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 91e463cc325..0e3792fda3f 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2056,7 +2056,8 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
 	mDetail = detail;
 	mSculptLevel = -2;
 	mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims
-	mIsMeshAssetLoaded = FALSE;
+	mIsMeshAssetLoaded = false;
+    mIsMeshAssetUnavaliable = false;
 	mLODScaleBias.setVec(1,1,1);
 	mHullPoints = NULL;
 	mHullIndices = NULL;
@@ -2804,14 +2805,32 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
 }
 
 
-BOOL LLVolume::isMeshAssetLoaded()
+bool LLVolume::isMeshAssetLoaded()
 {
 	return mIsMeshAssetLoaded;
 }
 
-void LLVolume::setMeshAssetLoaded(BOOL loaded)
+void LLVolume::setMeshAssetLoaded(bool loaded)
 {
 	mIsMeshAssetLoaded = loaded;
+    if (loaded)
+    {
+        mIsMeshAssetUnavaliable = false;
+    }
+}
+
+void LLVolume::setMeshAssetUnavaliable(bool unavaliable)
+{
+    // Don't set it if at least one lod loaded
+    if (!mIsMeshAssetLoaded)
+    {
+        mIsMeshAssetUnavaliable = unavaliable;
+    }
+}
+
+bool LLVolume::isMeshAssetUnavaliable()
+{
+    return mIsMeshAssetUnavaliable;
 }
 
 void LLVolume::copyFacesTo(std::vector<LLVolumeFace> &faces) const 
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index ad6a6695316..afed98ff363 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -1111,15 +1111,18 @@ class LLVolume : public LLRefCount
 	bool unpackVolumeFacesInternal(const LLSD& mdl);
 
 public:
-	virtual void setMeshAssetLoaded(BOOL loaded);
-	virtual BOOL isMeshAssetLoaded();
+	virtual void setMeshAssetLoaded(bool loaded);
+	virtual bool isMeshAssetLoaded();
+    virtual void setMeshAssetUnavaliable(bool unavaliable);
+    virtual bool isMeshAssetUnavaliable();
 
  protected:
 	BOOL mUnique;
 	F32 mDetail;
 	S32 mSculptLevel;
 	F32 mSurfaceArea; //unscaled surface area
-	BOOL mIsMeshAssetLoaded;
+	bool mIsMeshAssetLoaded;
+    bool mIsMeshAssetUnavaliable;
 	
 	const LLVolumeParams mParams;
 	LLPath *mPathp;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 9f90e132f8b..57ac111fdf3 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4067,7 +4067,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
 			if (sys_volume)
 			{
 				sys_volume->copyVolumeFaces(volume);
-				sys_volume->setMeshAssetLoaded(TRUE);
+				sys_volume->setMeshAssetLoaded(true);
 				LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
 			}
 			else
@@ -4099,6 +4099,12 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params,
 	{
 		F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod);
 
+        LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail);
+        if (sys_volume)
+        {
+            sys_volume->setMeshAssetUnavaliable(true);
+        }
+
 		for (LLVOVolume* vobj : obj_iter->second)
 		{
 			if (vobj)
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index c7a2cea6273..22cd9f71b34 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -7574,6 +7574,85 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
 	}
 }
 
+bool LLVOAvatar::hasPendingAttachedMeshes()
+{
+    for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+         iter != mAttachmentPoints.end();
+         ++iter)
+    {
+        LLViewerJointAttachment* attachment = iter->second;
+        if (attachment)
+        {
+            for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+                 attachment_iter != attachment->mAttachedObjects.end();
+                 ++attachment_iter)
+            {
+                LLViewerObject* objectp = attachment_iter->get();
+                if (objectp)
+                {
+                    LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+                    for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
+                         iter1 != child_list.end(); ++iter1)
+                    {
+                        LLViewerObject* objectchild = *iter1;
+                        if (objectchild && objectchild->getVolume())
+                        {
+                            const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID();
+                            if (mesh_id.isNull())
+                            {
+                                // No mesh nor skin info needed
+                                continue;
+                            }
+
+                            if (objectchild->getVolume()->isMeshAssetUnavaliable())
+                            {
+                                // Mesh failed to load, do not expect it
+                                continue;
+                            }
+
+                            if (objectchild->mDrawable)
+                            {
+                                LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume();
+                                if (pvobj)
+                                {
+                                    if (!pvobj->isMesh())
+                                    {
+                                        // Not a mesh
+                                        continue;
+                                    }
+
+                                    if (!objectchild->getVolume()->isMeshAssetLoaded())
+                                    {
+                                        // Waiting for mesh
+                                        return true;
+                                    }
+
+                                    const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo();
+                                    if (skin_data)
+                                    {
+                                        // Skin info present, done
+                                        continue;
+                                    }
+
+                                    if (pvobj->isSkinInfoUnavaliable())
+                                    {
+                                        // Load failed or info not present, don't expect it
+                                        continue;
+                                    }
+                                }
+
+                                // objectchild is not ready
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
+
 //-----------------------------------------------------------------------------
 // detachObject()
 //-----------------------------------------------------------------------------
@@ -8150,6 +8229,7 @@ BOOL LLVOAvatar::updateIsFullyLoaded()
                    || (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC)
                    || !mPendingAttachment.empty()
                    || (rez_status < 3 && !isFullyBaked())
+                   || hasPendingAttachedMeshes()
                   );
 	}
 	updateRezzedStatusTimers(rez_status);
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index f1dc503c9e5..48bfd5293af 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -917,6 +917,7 @@ class LLVOAvatar :
 	virtual BOOL 		detachObject(LLViewerObject *viewer_object);
 	static bool		    getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id );
 	void				cleanupAttachedMesh( LLViewerObject* pVO );
+    bool                hasPendingAttachedMeshes();
 	static LLVOAvatar*  findAvatarFromAttachment(LLViewerObject* obj);
 	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type ) const;
 	LLViewerObject *	findAttachmentByID( const LLUUID & target_id ) const;
-- 
GitLab