From 4caf151c5ad1e07f819bc8e5ab8eda584f41420b Mon Sep 17 00:00:00 2001
From: prep linden <prep@lindenlab.com>
Date: Wed, 22 Jun 2011 13:36:21 -0400
Subject: [PATCH] WIP for SH-1791

---
 indra/newview/llsurface.cpp      | 11 +++++
 indra/newview/llsurface.h        |  3 ++
 indra/newview/llviewerobject.cpp | 84 ++++++++++++++++++++++++++++++--
 indra/newview/llviewerobject.h   | 11 ++++-
 indra/newview/llviewerregion.cpp | 13 +++++
 indra/newview/llviewerregion.h   |  4 ++
 6 files changed, 121 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index bccabe21a85..66df7dae3ed 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -334,6 +334,17 @@ void LLSurface::setOriginGlobal(const LLVector3d &origin_global)
 	}
 }
 
+void LLSurface::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
+{
+	S32 i;
+	for (i = 0; i < 8; i++)
+	{
+		if ( mNeighbors[i] != NULL )
+		{
+			uniqueRegions.push_back( mNeighbors[i]->getRegion() );
+		}
+	}	
+}
 
 void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 {
diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h
index 673ee83fe30..a4ef4fe2de6 100644
--- a/indra/newview/llsurface.h
+++ b/indra/newview/llsurface.h
@@ -140,6 +140,9 @@ class LLSurface
 
 	friend class LLSurfacePatch;
 	friend std::ostream& operator<<(std::ostream &s, const LLSurface &S);
+	
+	void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
+	
 public:
 	// Number of grid points on one side of a region, including +1 buffer for
 	// north and east edge.
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index be9ff872c06..31856250949 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -104,6 +104,7 @@
 #include "llaccountingquota.h"
 
 //#define DEBUG_UPDATE_TYPE
+//#define EXTENDED_ENCROACHMENT_CHECK //temp:
 
 BOOL		LLViewerObject::sVelocityInterpolate = TRUE;
 BOOL		LLViewerObject::sPingInterpolate = TRUE; 
@@ -519,7 +520,6 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)
 	}
 }
 
-
 // This method returns true if the object is over land owned by the
 // agent.
 bool LLViewerObject::isReturnable()
@@ -534,11 +534,87 @@ bool LLViewerObject::isReturnable()
 		 iter != mChildList.end(); iter++)
 	{
 		LLViewerObject* child = *iter;
-		boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+		boxes.push_back( LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+	}
+
+	bool result = (mRegionp && mRegionp->objectIsReturnable(getPositionRegion(), boxes)) ? 1 : 0;
+#ifdef EXTENDED_ENCROACHMENT_CHECK	
+	//Get list of neighboring regions
+	std::vector<LLViewerRegion*> uniqueRegions;
+	//Store this vo's region
+	uniqueRegions.push_back( mRegionp );
+	//Build list of neighboring regions realtive to this vo's region
+	mRegionp->getNeighboringRegions( uniqueRegions );
+	
+	//Build aabb's - for root and all children
+	std::vector<PotentialReturnableObject> returnables;
+	if ( !result )
+	{
+		//Current region 
+		PotentialReturnableObject returnableObj;
+		returnableObj.box = LLBBox( getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned() ;
+		returnableObj.pRegion = getRegion();
+		
+		for (child_list_t::iterator iter = mChildList.begin();  iter != mChildList.end(); iter++)
+		{
+			LLViewerObject* pChild = *iter;		
+			buildReturnablesForChildrenVO( returnables, pChild );
+		}
+	}
+	
+	//TBD# Should probably create a region -> box map 
+	typedef std::vector<PotentialReturnableObject>::iterator ReturnablesIt;
+	ReturnablesIt retCurrentIt = returnables.begin();
+	ReturnablesIt retEndIt = returnables.end();
+	
+	for ( ; retCurrentIt !=retEndIt; ++retCurrentIt )
+	{
+		boxes.clear();
+		LLViewerRegion* pRegion = (*retCurrentIt).pRegion;
+		boxes.push_back( (*retCurrentIt).box );	
+		//LLVector3 boxPos = (*retCurrentIt).box.getPositionAgent();
+		//TBD# Should we just use pRegion->objectIsReturnable, instead? 
+		//As it does various other checks, childrenObjectReturnable does not.
+		bool retResult = (mRegionp && pRegion->childrenObjectReturnable( boxes )) ? 1 : 0;
+		if ( retResult )
+		{ 
+			result = true;
+			break;
+		}
+	}
+#endif
+	return result;
+}
+
+void LLViewerObject::buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild )
+{
+	if ( !pChild )
+	{
+		llerrs<<"child viewerobject is NULL "<<llendl;
 	}
+	
+	constructAndAddReturnable( returnables, pChild );
+	
+	//We want to handle any children VO's.
+	for (child_list_t::iterator iter = pChild->mChildList.begin();  iter != pChild->mChildList.end(); iter++)
+	{
+		LLViewerObject* pChildofChild = *iter;
+		buildReturnablesForChildrenVO( returnables, pChildofChild );
+	}
+}
 
-	return mRegionp
-		&& mRegionp->objectIsReturnable(getPositionRegion(), boxes);
+void LLViewerObject::constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild )
+{
+	PotentialReturnableObject returnableObj;
+	LLViewerRegion* pRegion = pChild->getRegion();	
+		
+	LLVector3d posGlobal		= pRegion->getPosGlobalFromRegion( pChild->getPositionRegion() );
+	LLVector3 targetRegionPos	= pRegion->getPosRegionFromGlobal( posGlobal );
+	
+	returnableObj.box = LLBBox( targetRegionPos, pChild->getRotationRegion(), pChild->getScale() * -0.5f, 
+							    pChild->getScale() * 0.5f).getAxisAligned();
+	returnableObj.pRegion		= pRegion;
+	returnables.push_back( returnableObj );
 }
 
 BOOL LLViewerObject::setParent(LLViewerObject* parent)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index a0ad52df6b9..a7d0933dc37 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -44,11 +44,11 @@
 #include "v3math.h"
 #include "llvertexbuffer.h"
 #include "llaccountingquota.h"
+#include "llbbox.h"
 
 class LLAgent;			// TODO: Get rid of this.
 class LLAudioSource;
 class LLAudioSourceVO;
-class LLBBox;
 class LLDataPacker;
 class LLColor4;
 class LLFrameTimer;
@@ -112,6 +112,12 @@ struct LLMaterialExportInfo
 	LLColor4	mColor;
 };
 
+struct PotentialReturnableObject
+{
+	LLBBox			box;
+	LLViewerRegion* pRegion;
+};
+
 //============================================================================
 
 class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
@@ -234,6 +240,9 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	// anti-encroachment is enabled
 	bool isReturnable();
 
+	void buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild );
+	void constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild );
+
 	/*
 	// This method will scan through this object, and then query the
 	// selection manager to see if the local agent probably has the
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 002e0567e4e..0df97d60501 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1699,6 +1699,19 @@ bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<
 				&& mParcelOverlay->encroachesOwned(boxes)) );
 }
 
+bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const
+{
+	bool result = false;
+	//TBD# Do we need similar checks to objectIsReturnable? if so just use objectisreturnable
+	result = ( mParcelOverlay && mParcelOverlay->encroachesOwned( boxes ) ) ? 1 : 0;
+	return result;
+}
+
+void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
+{
+	mImpl->mLandp->getNeighboringRegions( uniqueRegions );
+}
+
 void LLViewerRegion::showReleaseNotes()
 {
 	std::string url = this->getCapability("ServerReleaseNotes");
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 3811b989e7c..68662c99bd3 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -318,6 +318,10 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	LLSpatialPartition* getSpatialPartition(U32 type);
 
 	bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
+	bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const;
+
+	void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
+	
 public:
 	struct CompareDistance
 	{
-- 
GitLab