From caaa711c6a4e56795b1fd08f0585cedba3e4212c Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 30 Sep 2014 20:02:33 +0300
Subject: [PATCH] MAINT-4448 FIXED Avatar often stops animating when being
 animated by an intan solo dance ball on Interesting based viewers only.

---
 indra/newview/llviewerregion.cpp | 16 +++++++++++-----
 indra/newview/llviewerregion.h   |  2 +-
 indra/newview/llvoavatar.cpp     |  9 +++++++++
 indra/newview/llvoavatar.h       |  1 +
 indra/newview/llvoavatarself.cpp |  8 ++++++++
 indra/newview/llvoavatarself.h   |  1 +
 6 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 7a6637c0a19..7d82ecf565c 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -66,6 +66,7 @@
 #include "llviewerstatsrecorder.h"
 #include "llvlmanager.h"
 #include "llvlcomposition.h"
+#include "llvoavatarself.h"
 #include "llvocache.h"
 #include "llworld.h"
 #include "llspatialpartition.h"
@@ -1485,22 +1486,27 @@ void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>&
 
 	if(drawablep && !drawablep->getParent())
 	{
-		if (drawablep->getVObj()->isSelected())
+		LLViewerObject* v_obj = drawablep->getVObj();
+		if (v_obj->isSelected()
+			|| (v_obj->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(v_obj->getID())))
 		{
-			// do not remove selected objects
+			// do not remove objects user is interacting with
 			((LLViewerOctreeEntryData*)drawablep)->setVisible();
 			return;
 		}
-		LLViewerObject::const_child_list_t& child_list = drawablep->getVObj()->getChildren();
+		LLViewerObject::const_child_list_t& child_list = v_obj->getChildren();
 		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
 			iter != child_list.end(); iter++)
 		{
 			LLViewerObject* child = *iter;
 			if(child->mDrawable)
 			{
-				if(!child->mDrawable->getEntry() || !child->mDrawable->getEntry()->hasVOCacheEntry() || child->isSelected())
+				if( !child->mDrawable->getEntry()
+					|| !child->mDrawable->getEntry()->hasVOCacheEntry()
+					|| child->isSelected()
+					|| (child->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(child->getID())))
 				{
-					//do not remove parent if any of its children non-cacheable or selected
+					//do not remove parent if any of its children non-cacheable, animating or selected
 					//especially for the case that an avatar sits on a cache-able object
 					((LLViewerOctreeEntryData*)drawablep)->setVisible();
 					return;
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 1e225553b81..d01e7469368 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -385,7 +385,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 private:
 	void addToVOCacheTree(LLVOCacheEntry* entry);
 	LLViewerObject* addNewObject(LLVOCacheEntry* entry);
-	void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list);	
+	void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list); //adds entry into list if it is safe to move into cache
 	void removeFromVOCacheTree(LLVOCacheEntry* entry);
 	void killCacheEntry(LLVOCacheEntry* entry, bool for_rendering = false); //physically delete the cache entry	
 	void killInvisibleObjects(F32 max_time);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 904d08ac732..dfb9bb54e77 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5016,6 +5016,15 @@ BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
 	return LLCharacter::stopMotion(remap_id, stop_immediate);
 }
 
+//-----------------------------------------------------------------------------
+// hasMotionFromSource()
+//-----------------------------------------------------------------------------
+// virtual
+bool LLVOAvatar::hasMotionFromSource(const LLUUID& source_id)
+{
+	return false;
+}
+
 //-----------------------------------------------------------------------------
 // stopMotionFromSource()
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 66a357ff628..4d5e6169067 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -191,6 +191,7 @@ class LLVOAvatar :
 	/*virtual*/ LLUUID			remapMotionID(const LLUUID& id);
 	/*virtual*/ BOOL			startMotion(const LLUUID& id, F32 time_offset = 0.f);
 	/*virtual*/ BOOL			stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
+	virtual bool			hasMotionFromSource(const LLUUID& source_id);
 	virtual void			stopMotionFromSource(const LLUUID& source_id);
 	virtual void			requestStopMotion(LLMotion* motion);
 	LLMotion*				findMotion(const LLUUID& id) const;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 42a7c2e576c..02494d50918 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -748,6 +748,13 @@ void LLVOAvatarSelf::requestStopMotion(LLMotion* motion)
 	gAgent.requestStopMotion(motion);
 }
 
+// virtual
+bool LLVOAvatarSelf::hasMotionFromSource(const LLUUID& source_id)
+{
+	AnimSourceIterator motion_it = mAnimationSources.find(source_id);
+	return motion_it != mAnimationSources.end();
+}
+
 // virtual
 void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
 {
@@ -757,6 +764,7 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
 		mAnimationSources.erase(motion_it++);
 	}
 
+
 	LLViewerObject* object = gObjectList.findObject(source_id);
 	if (object)
 	{
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index e03de9fa0bf..ad73dd89b79 100755
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -82,6 +82,7 @@ class LLVOAvatarSelf :
 	// LLCharacter interface and related
 	//--------------------------------------------------------------------
 public:
+	/*virtual*/ bool 		hasMotionFromSource(const LLUUID& source_id);
 	/*virtual*/ void 		stopMotionFromSource(const LLUUID& source_id);
 	/*virtual*/ void 		requestStopMotion(LLMotion* motion);
 	/*virtual*/ LLJoint*	getJoint(const std::string &name);
-- 
GitLab