diff options
| author | Dave Parks <davep@lindenlab.com> | 2010-09-19 23:08:12 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2010-09-19 23:08:12 -0500 | 
| commit | 2c4c1c47bce3db7420f0eb27bdaa7598fbbbb65a (patch) | |
| tree | a3ffe2463739f9677fa6ceca29b5676bcd4a50f1 /indra/llmath | |
| parent | e18e26e87c46806f75d219b21be8b6ff2228fc99 (diff) | |
Take advantage of automagical tcmalloc alignment.
Diffstat (limited to 'indra/llmath')
| -rw-r--r-- | indra/llmath/lloctree.h | 127 | 
1 files changed, 86 insertions, 41 deletions
| diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 73910ef98d..63adfa85b2 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -95,22 +95,30 @@ public:  	typedef LLOctreeNode<T>		oct_node;  	typedef LLOctreeListener<T>	oct_listener; +	/*void* operator new(size_t size) +	{ +		return ll_aligned_malloc_16(size); +	} + +	void operator delete(void* ptr) +	{ +		ll_aligned_free_16(ptr); +	}*/ +  	LLOctreeNode(	const LLVector4a& center,   					const LLVector4a& size,   					BaseType* parent,  -					S32 octant = -1) +					U8 octant = 255)  	:	mParent((oct_node*)parent),   		mOctant(octant)   	{  -		mD = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*4); - -		mD[CENTER] = center; -		mD[SIZE] = size; +		mCenter = center; +		mSize = size;  		updateMinMax(); -		if ((mOctant == -1) && mParent) +		if ((mOctant == 255) && mParent)  		{ -			mOctant = ((oct_node*) mParent)->getOctant(mD[CENTER]); +			mOctant = ((oct_node*) mParent)->getOctant(mCenter);  		}  		clearChildren(); @@ -124,30 +132,27 @@ public:  		{  			delete getChild(i);  		}  - -		ll_aligned_free_16(mD);  	}  	inline const BaseType* getParent()	const			{ return mParent; }  	inline void setParent(BaseType* parent)				{ mParent = (oct_node*) parent; } -	inline const LLVector4a& getCenter() const			{ return mD[CENTER]; } -	inline const LLVector4a& getSize() const			{ return mD[SIZE]; } -	inline void setCenter(const LLVector4a& center)		{ mD[CENTER] = center; } -	inline void setSize(const LLVector4a& size)			{ mD[SIZE] = size; } +	inline const LLVector4a& getCenter() const			{ return mCenter; } +	inline const LLVector4a& getSize() const			{ return mSize; } +	inline void setCenter(const LLVector4a& center)		{ mCenter = center; } +	inline void setSize(const LLVector4a& size)			{ mSize = size; }      inline oct_node* getNodeAt(T* data)					{ return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } -	inline S32 getOctant() const						{ return mOctant; } -	inline void setOctant(S32 octant)					{ mOctant = octant; } +	inline U8 getOctant() const							{ return mOctant; }  	inline const oct_node*	getOctParent() const		{ return (const oct_node*) getParent(); }  	inline oct_node* getOctParent() 					{ return (oct_node*) getParent(); } -	S32 getOctant(const LLVector4a& pos) const			//get the octant pos is in +	U8 getOctant(const LLVector4a& pos) const			//get the octant pos is in  	{ -		return pos.greaterThan(mD[CENTER]).getGatheredBits() & 0x7; +		return (U8) (pos.greaterThan(mCenter).getGatheredBits() & 0x7);  	}  	inline bool isInside(const LLVector4a& pos, const F32& rad) const  	{ -		return rad <= mD[SIZE][0]*2.f && isInside(pos);  +		return rad <= mSize[0]*2.f && isInside(pos);   	}  	inline bool isInside(T* data) const			 @@ -157,13 +162,13 @@ public:  	bool isInside(const LLVector4a& pos) const  	{ -		S32 gt = pos.greaterThan(mD[MAX]).getGatheredBits() & 0x7; +		S32 gt = pos.greaterThan(mMax).getGatheredBits() & 0x7;  		if (gt)  		{  			return false;  		} -		S32 lt = pos.lessEqual(mD[MIN]).getGatheredBits() & 0x7; +		S32 lt = pos.lessEqual(mMin).getGatheredBits() & 0x7;  		if (lt)  		{  			return false; @@ -174,8 +179,8 @@ public:  	void updateMinMax()  	{ -		mD[MAX].setAdd(mD[CENTER], mD[SIZE]); -		mD[MIN].setSub(mD[CENTER], mD[SIZE]); +		mMax.setAdd(mCenter, mSize); +		mMin.setSub(mCenter, mSize);  	}  	inline oct_listener* getOctListener(U32 index)  @@ -195,7 +200,7 @@ public:  			return false;  		} -		F32 size = mD[SIZE][0]; +		F32 size = mSize[0];  		F32 p_size = size * 2.f;  		return (radius <= 0.001f && size <= 0.001f) || @@ -234,6 +239,29 @@ public:  	void accept(tree_traveler* visitor) const		{ visitor->visit(this); }  	void accept(oct_traveler* visitor) const		{ visitor->visit(this); } +	void validateChildMap() +	{ +		for (U32 i = 0; i < 8; i++) +		{ +			U8 idx = mChildMap[i]; +			if (idx != 255) +			{ +				LLOctreeNode<T>* child = mChild[idx]; + +				if (child->getOctant() != i) +				{ +					llerrs << "Invalid child map, bad octant data." << llendl; +				} + +				if (getOctant(child->getCenter()) != child->getOctant()) +				{ +					llerrs << "Invalid child octant compared to position data." << llendl; +				} +			} +		} +	} + +  	oct_node* getNodeAt(const LLVector4a& pos, const F32& rad)  	{   		LLOctreeNode<T>* node = this; @@ -241,25 +269,19 @@ public:  		if (node->isInside(pos, rad))  		{		  			//do a quick search by octant -			S32 octant = node->getOctant(pos); -			BOOL keep_going = TRUE; - +			U8 octant = node->getOctant(pos); +			  			//traverse the tree until we find a node that has no node  			//at the appropriate octant or is smaller than the object.    			//by definition, that node is the smallest node that contains   			// the data -			while (keep_going && node->getSize()[0] >= rad) +			U8 next_node = node->mChildMap[octant]; +			 +			while (next_node != 255 && node->getSize()[0] >= rad)  			{	 -				keep_going = FALSE; -				for (U32 i = 0; i < node->getChildCount() && !keep_going; i++) -				{ -					if (node->getChild(i)->getOctant() == octant) -					{ -						node = node->getChild(i); -						octant = node->getOctant(pos); -						keep_going = TRUE; -					} -				} +				node = node->getChild(next_node); +				octant = node->getOctant(pos); +				next_node = node->mChildMap[octant];  			}  		}  		else if (!node->contains(rad) && node->getParent()) @@ -439,6 +461,9 @@ public:  	void clearChildren()  	{  		mChild.clear(); + +		U32* foo = (U32*) mChildMap; +		foo[0] = foo[1] = 0xFFFFFFFF;  	}  	void validate() @@ -496,6 +521,8 @@ public:  		}  #endif +		mChildMap[child->getOctant()] = (U8) mChild.size(); +  		mChild.push_back(child);  		child->setParent(this); @@ -517,6 +544,8 @@ public:  			listener->handleChildRemoval(this, getChild(index));  		} +		 +  		if (destroy)  		{  			mChild[index]->destroy(); @@ -524,6 +553,15 @@ public:  		}  		mChild.erase(mChild.begin() + index); +		//rebuild child map +		U32* foo = (U32*) mChildMap; +		foo[0] = foo[1] = 0xFFFFFFFF; + +		for (U32 i = 0; i < mChild.size(); ++i) +		{ +			mChildMap[mChild[i]->getOctant()] = i; +		} +  		checkAlive();  	} @@ -562,15 +600,20 @@ protected:  		MIN = 3  	} eDName; -	LLVector4a* mD; +	LLVector4a mCenter; +	LLVector4a mSize; +	LLVector4a mMax; +	LLVector4a mMin;  	oct_node* mParent; -	S32 mOctant; +	U8 mOctant;  	child_list mChild; +	U8 mChildMap[8]; +  	element_list mData; -}; +};   //just like a regular node, except it might expand on insert and compress on balance  template <class T> @@ -613,6 +656,8 @@ public:  			//destroy child  			child->clearChildren();  			delete child; + +			return false;  		}  		return true; @@ -639,7 +684,7 @@ public:  		const LLVector4a& v = data->getPositionGroup();  		LLVector4a val; -		val.setSub(v, BaseType::mD[BaseType::CENTER]); +		val.setSub(v, BaseType::mCenter);  		val.setAbs(val);  		S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7; | 
