diff options
| author | Dave Parks <davep@lindenlab.com> | 2011-12-16 17:43:30 -0600 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2011-12-16 17:43:30 -0600 | 
| commit | c0b4ec6fe72d703191b28749cfd30262d131b245 (patch) | |
| tree | 295f2b197f16af8a8c57275c2e6320cf12e83f5e /indra/llmath | |
| parent | 9fa68f0da363cd3c20dbb079f5d2901a45dfea5f (diff) | |
SH-2694 Fix for FPS drop when mousing over flexi objects (don't use an octree for flexi raycast)
Diffstat (limited to 'indra/llmath')
| -rw-r--r-- | indra/llmath/lloctree.h | 36 | ||||
| -rw-r--r-- | indra/llmath/llvolume.cpp | 85 | 
2 files changed, 95 insertions, 26 deletions
| diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 3c1ae45d68..1b11e83b4a 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -80,8 +80,8 @@ public:  	typedef LLOctreeTraveler<T>									oct_traveler;  	typedef LLTreeTraveler<T>									tree_traveler;  	typedef typename std::set<LLPointer<T> >					element_list; -	typedef typename std::set<LLPointer<T> >::iterator			element_iter; -	typedef typename std::set<LLPointer<T> >::const_iterator	const_element_iter; +	typedef typename element_list::iterator						element_iter; +	typedef typename element_list::const_iterator	const_element_iter;  	typedef typename std::vector<LLTreeListener<T>*>::iterator	tree_listener_iter;  	typedef typename std::vector<LLOctreeNode<T>* >				child_list;  	typedef LLTreeNode<T>		BaseType; @@ -114,6 +114,8 @@ public:  			mOctant = ((oct_node*) mParent)->getOctant(mCenter);  		} +		mElementCount = 0; +  		clearChildren();  	} @@ -219,11 +221,11 @@ public:  	void accept(oct_traveler* visitor)				{ visitor->visit(this); }  	virtual bool isLeaf() const						{ return mChild.empty(); } -	U32 getElementCount() const						{ return mData.size(); } +	U32 getElementCount() const						{ return mElementCount; }  	element_list& getData()							{ return mData; }  	const element_list& getData() const				{ return mData; } -	U32 getChildCount()	const						{ return mChild.size(); } +	U32 getChildCount()	const						{ return mChildCount; }  	oct_node* getChild(U32 index)					{ return mChild[index]; }  	const oct_node* getChild(U32 index) const		{ return mChild[index]; }  	child_list& getChildren()						{ return mChild; } @@ -300,17 +302,13 @@ public:  			if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||  				(data->getBinRadius() > getSize()[0] &&	parent && parent->getElementCount() >= gOctreeMaxCapacity)))   			{ //it belongs here -#if LL_OCTREE_PARANOIA_CHECK  				//if this is a redundant insertion, error out (should never happen) -				if (mData.find(data) != mData.end()) -				{ -					llwarns << "Redundant octree insertion detected. " << data << llendl; -					return false; -				} -#endif +				llassert(mData.find(data) == mData.end());  				mData.insert(data);  				BaseType::insert(data); + +				mElementCount = mData.size();  				return true;  			}  			else @@ -346,6 +344,8 @@ public:  				{  					mData.insert(data);  					BaseType::insert(data); + +					mElementCount = mData.size();  					return true;  				} @@ -399,6 +399,7 @@ public:  		if (mData.find(data) != mData.end())  		{	//we have data  			mData.erase(data); +			mElementCount = mData.size();  			notifyRemoval(data);  			checkAlive();  			return true; @@ -436,6 +437,7 @@ public:          if (mData.find(data) != mData.end())  		{  			mData.erase(data); +			mElementCount = mData.size();  			notifyRemoval(data);  			llwarns << "FOUND!" << llendl;  			checkAlive(); @@ -452,7 +454,7 @@ public:  	void clearChildren()  	{  		mChild.clear(); - +		mChildCount = 0;  		U32* foo = (U32*) mChildMap;  		foo[0] = foo[1] = 0xFFFFFFFF;  	} @@ -512,9 +514,10 @@ public:  		}  #endif -		mChildMap[child->getOctant()] = (U8) mChild.size(); +		mChildMap[child->getOctant()] = mChildCount;  		mChild.push_back(child); +		++mChildCount;  		child->setParent(this);  		if (!silent) @@ -534,21 +537,20 @@ public:  			oct_listener* listener = getOctListener(i);  			listener->handleChildRemoval(this, getChild(index));  		} - -  		if (destroy)  		{  			mChild[index]->destroy();  			delete mChild[index];  		}  		mChild.erase(mChild.begin() + index); +		--mChildCount;  		//rebuild child map  		U32* foo = (U32*) mChildMap;  		foo[0] = foo[1] = 0xFFFFFFFF; -		for (U32 i = 0; i < mChild.size(); ++i) +		for (U32 i = 0; i < mChildCount; ++i)  		{  			mChildMap[mChild[i]->getOctant()] = i;  		} @@ -601,8 +603,10 @@ protected:  	child_list mChild;  	U8 mChildMap[8]; +	U32 mChildCount;  	element_list mData; +	U32 mElementCount;  };  diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index da0fa32963..0c6cf1dfae 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4617,18 +4617,83 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en  				genBinormals(i);  			} -			if (!face.mOctree) -			{ -				face.createOctree(); -			} -			 -			//LLVector4a* p = (LLVector4a*) face.mPositions; +			if (isUnique()) +			{ //don't bother with an octree for flexi volumes +				U32 tri_count = face.mNumIndices/3; + +				for (U32 j = 0; j < tri_count; ++j) +				{ +					U16 idx0 = face.mIndices[j*3+0]; +					U16 idx1 = face.mIndices[j*3+1]; +					U16 idx2 = face.mIndices[j*3+2]; -			LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); -			intersect.traverse(face.mOctree); -			if (intersect.mHitFace) +					const LLVector4a& v0 = face.mPositions[idx0]; +					const LLVector4a& v1 = face.mPositions[idx1]; +					const LLVector4a& v2 = face.mPositions[idx2]; +				 +					F32 a,b,t; + +					if (LLTriangleRayIntersect(v0, v1, v2, +							start, dir, a, b, t)) +					{ +						if ((t >= 0.f) &&      // if hit is after start +							(t <= 1.f) &&      // and before end +							(t < closest_t))   // and this hit is closer +						{ +							closest_t = t; +							hit_face = i; + +							if (intersection != NULL) +							{ +								LLVector4a intersect = dir; +								intersect.mul(closest_t); +								intersect.add(start); +								intersection->set(intersect.getF32ptr()); +							} + + +							if (tex_coord != NULL) +							{ +								LLVector2* tc = (LLVector2*) face.mTexCoords; +								*tex_coord = ((1.f - a - b)  * tc[idx0] + +									a              * tc[idx1] + +									b              * tc[idx2]); + +							} + +							if (normal!= NULL) +							{ +								LLVector4* norm = (LLVector4*) face.mNormals; + +								*normal		= ((1.f - a - b)  * LLVector3(norm[idx0]) +  +									a              * LLVector3(norm[idx1]) + +									b              * LLVector3(norm[idx2])); +							} + +							if (bi_normal != NULL) +							{ +								LLVector4* binormal = (LLVector4*) face.mBinormals; +								*bi_normal = ((1.f - a - b)  * LLVector3(binormal[idx0]) +  +										a              * LLVector3(binormal[idx1]) + +										b              * LLVector3(binormal[idx2])); +							} +						} +					} +				} +			} +			else  			{ -				hit_face = i; +				if (!face.mOctree) +				{ +					face.createOctree(); +				} +			 +				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); +				intersect.traverse(face.mOctree); +				if (intersect.mHitFace) +				{ +					hit_face = i; +				}  			}  		}		  	} | 
