diff options
Diffstat (limited to 'indra/llmath')
| -rw-r--r-- | indra/llmath/lloctree.h | 153 | ||||
| -rw-r--r-- | indra/llmath/llvolume.cpp | 95 | ||||
| -rw-r--r-- | indra/llmath/llvolume.h | 11 | ||||
| -rw-r--r-- | indra/llmath/llvolumeoctree.cpp | 18 | ||||
| -rw-r--r-- | indra/llmath/llvolumeoctree.h | 20 | 
5 files changed, 159 insertions, 138 deletions
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index a9a54a8113..318ee65cc0 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -48,52 +48,59 @@ extern float gOctreeMinSize;  #define LL_OCTREE_MAX_CAPACITY 128  #endif*/ -template <class T> class LLOctreeNode; - -template <class T> +// T is the type of the element referenced by the octree node. +// T_PTR determines how pointers to elements are stored internally. +// LLOctreeNode<T, LLPointer<T>> assumes ownership of inserted elements and +// deletes elements removed from the tree. +// LLOctreeNode<T, T*> doesn't take ownership of inserted elements, so the API +// user is responsible for managing the storage lifecycle of elements added to +// the tree. +template <class T, typename T_PTR> class LLOctreeNode; + +template <class T, typename T_PTR>  class LLOctreeListener: public LLTreeListener<T>  {  public:  	typedef LLTreeListener<T> BaseType; -	typedef LLOctreeNode<T> oct_node; +    typedef LLOctreeNode<T, T_PTR> oct_node;  	virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0;  	virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0;  }; -template <class T> +template <class T, typename T_PTR>  class LLOctreeTraveler  {  public: -	virtual void traverse(const LLOctreeNode<T>* node); -	virtual void visit(const LLOctreeNode<T>* branch) = 0; +    virtual void traverse(const LLOctreeNode<T, T_PTR>* node); +    virtual void visit(const LLOctreeNode<T, T_PTR>* branch) = 0;  }; -template <class T> -class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T> +template <class T, typename T_PTR> +class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T, T_PTR>  {  public: -	virtual void traverse(const LLOctreeNode<T>* node) override; +	virtual void traverse(const LLOctreeNode<T, T_PTR>* node) override;  }; -template <class T> +template <class T, typename T_PTR>  class alignas(16) LLOctreeNode : public LLTreeNode<T>  {      LL_ALIGN_NEW  public: -	typedef LLOctreeTraveler<T>									oct_traveler; -	typedef LLTreeTraveler<T>									tree_traveler; -	typedef std::vector< LLPointer<T> >							element_list;		// note:  don't remove the whitespace between "> >" -	typedef LLPointer<T>*										element_iter; -	typedef const LLPointer<T>*									const_element_iter; +    typedef LLOctreeTraveler<T, T_PTR>                          oct_traveler; +    typedef LLTreeTraveler<T>                                   tree_traveler; +    typedef std::vector<T_PTR>                                  element_list; +    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 LLOctreeNode<T>**									child_list; -	typedef LLOctreeNode<T>**									child_iter; +    typedef LLOctreeNode<T, T_PTR>**                            child_list; +    typedef LLOctreeNode<T, T_PTR>**                            child_iter; -	typedef LLTreeNode<T>		BaseType; -	typedef LLOctreeNode<T>		oct_node; -	typedef LLOctreeListener<T>	oct_listener; +    typedef LLTreeNode<T>               BaseType; +    typedef LLOctreeNode<T, T_PTR>      oct_node; +    typedef LLOctreeListener<T, T_PTR>  oct_listener;      enum      { @@ -108,9 +115,6 @@ public:  		mOctant(octant)   	{   		llassert(size[0] >= gOctreeMinSize*0.5f); -		//always keep a NULL terminated list to avoid out of bounds exceptions in debug builds -		mData.push_back(NULL); -		mDataEnd = &mData[0];  		mCenter = center;  		mSize = size; @@ -121,8 +125,6 @@ public:  			mOctant = ((oct_node*) mParent)->getOctant(mCenter);  		} -		mElementCount = 0; -  		clearChildren();  	} @@ -130,15 +132,14 @@ public:  	{   		BaseType::destroyListeners(); -		for (U32 i = 0; i < mElementCount; ++i) +        const U32 element_count = getElementCount(); +        for (U32 i = 0; i < element_count; ++i)  		{  			mData[i]->setBinIndex(-1);  			mData[i] = NULL;  		}  		mData.clear(); -		mData.push_back(NULL); -		mDataEnd = &mData[0];  		for (U32 i = 0; i < getChildCount(); i++)  		{ @@ -238,14 +239,12 @@ public:  	void accept(oct_traveler* visitor)				{ visitor->visit(this); }  	virtual bool isLeaf() const						{ return mChildCount == 0; } -	U32 getElementCount() const						{ return mElementCount; } -	bool isEmpty() const							{ return mElementCount == 0; } -	element_list& getData()							{ return mData; } -	const element_list& getData() const				{ return mData; } -	element_iter getDataBegin()						{ return &mData[0]; } -	element_iter getDataEnd()						{ return mDataEnd; } -	const_element_iter getDataBegin() const			{ return &mData[0]; } -	const_element_iter getDataEnd() const			{ return mDataEnd; } +    U32 getElementCount() const                     { return (U32)mData.size(); } +    bool isEmpty() const                            { return mData.empty(); } +    element_iter getDataBegin()                     { return mData.begin(); } +    element_iter getDataEnd()                       { return mData.end(); } +    const_element_iter getDataBegin() const         { return mData.cbegin(); } +    const_element_iter getDataEnd() const           { return mData.cend(); }  	U32 getChildCount()	const						{ return mChildCount; }  	oct_node* getChild(U32 index)					{ return mChild[index]; } @@ -263,7 +262,7 @@ public:  			U8 idx = mChildMap[i];  			if (idx != NO_CHILD_NODES)  			{ -				LLOctreeNode<T>* child = mChild[idx]; +                oct_node* child = mChild[idx];  				if (child->getOctant() != i)  				{ @@ -281,7 +280,7 @@ public:  	oct_node* getNodeAt(const LLVector4a& pos, const F32& rad)  	{  -		LLOctreeNode<T>* node = this; +        oct_node* node = this;  		if (node->isInside(pos, rad))  		{ @@ -303,7 +302,7 @@ public:  		}  		else if (!node->contains(rad) && node->getParent())  		{ //if we got here, data does not exist in this node -			return ((LLOctreeNode<T>*) node->getParent())->getNodeAt(pos, rad); +            return ((oct_node*) node->getParent())->getNodeAt(pos, rad);  		}  		return node; @@ -318,7 +317,7 @@ public:  			OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL;  			return false;  		} -		LLOctreeNode<T>* parent = getOctParent(); +        oct_node* parent = getOctParent();  		//is it here?  		if (isInside(data->getPositionGroup())) @@ -326,11 +325,8 @@ public:  			if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) ||  				(data->getBinRadius() > getSize()[0] &&	parent && parent->getElementCount() >= gOctreeMaxCapacity)))   			{ //it belongs here -				mData.push_back(NULL); -				mData[mElementCount] = data; -				mElementCount++; -				mDataEnd = &mData[mElementCount]; -				data->setBinIndex(mElementCount-1); +                mData.push_back(data); +                data->setBinIndex(getElementCount() - 1);  				BaseType::insert(data);  				return true;  			} @@ -354,7 +350,7 @@ public:  				size.mul(0.5f);  				//push center in direction of data -				LLOctreeNode<T>::pushCenter(center, size, data); +                oct_node::pushCenter(center, size, data);  				// handle case where floating point number gets too small  				LLVector4a val; @@ -366,11 +362,8 @@ public:  				if( lt == 0x7 )  				{ -					mData.push_back(NULL); -					mData[mElementCount] = data; -					mElementCount++; -					mDataEnd = &mData[mElementCount]; -					data->setBinIndex(mElementCount-1); +                    mData.push_back(data); +                    data->setBinIndex(getElementCount() - 1);  					BaseType::insert(data);  					return true;  				} @@ -396,7 +389,7 @@ public:  				llassert(size[0] >= gOctreeMinSize*0.5f);  				//make the new kid -				child = new LLOctreeNode<T>(center, size, this); +                child = new oct_node(center, size, this);  				addChild(child);  				child->insert(data); @@ -429,28 +422,25 @@ public:  	}  	void _remove(T* data, S32 i) -	{ //precondition -- mElementCount > 0, idx is in range [0, mElementCount) +    { //precondition -- getElementCount() > 0, idx is in range [0, getElementCount()) -		mElementCount--;  		data->setBinIndex(-1);  -		if (mElementCount > 0) +        const U32 new_element_count = getElementCount() - 1; +		if (new_element_count > 0)  		{ -			if (mElementCount != i) +			if (new_element_count != i)  			{ -				mData[i] = mData[mElementCount]; //might unref data, do not access data after this point +				mData[i] = mData[new_element_count]; //might unref data, do not access data after this point  				mData[i]->setBinIndex(i);  			} -			mData[mElementCount] = NULL; +			mData[new_element_count] = NULL;  			mData.pop_back(); -			mDataEnd = &mData[mElementCount];  		}  		else  		{  			mData.clear(); -			mData.push_back(NULL); -			mDataEnd = &mData[0];  		}  		this->notifyRemoval(data); @@ -463,7 +453,7 @@ public:  		S32 i = data->getBinIndex(); -		if (i >= 0 && i < mElementCount) +        if (i >= 0 && i < getElementCount())  		{  			if (mData[i] == data)  			{ //found it @@ -506,7 +496,8 @@ public:  	void removeByAddress(T* data)  	{ -        for (U32 i = 0; i < mElementCount; ++i) +        const U32 element_count = getElementCount(); +        for (U32 i = 0; i < element_count; ++i)  		{  			if (mData[i] == data)  			{ //we have data @@ -518,7 +509,7 @@ public:  		for (U32 i = 0; i < getChildCount(); i++)  		{	//we don't contain data, so pass this guy down -			LLOctreeNode<T>* child = (LLOctreeNode<T>*) getChild(i); +            oct_node* child = (oct_node*) getChild(i);  			child->removeByAddress(data);  		}  	} @@ -672,22 +663,20 @@ protected:  	oct_node* mParent;  	U8 mOctant; -	LLOctreeNode<T>* mChild[8]; +    oct_node* mChild[8];  	U8 mChildMap[8];  	U32 mChildCount;  	element_list mData; -	element_iter mDataEnd; -	U32 mElementCount;  };   //just like a regular node, except it might expand on insert and compress on balance -template <class T> -class LLOctreeRoot : public LLOctreeNode<T> +template <class T, typename T_PTR> +class LLOctreeRoot : public LLOctreeNode<T, T_PTR>  {  public: -	typedef LLOctreeNode<T>	BaseType; -	typedef LLOctreeNode<T>	oct_node; +    typedef LLOctreeNode<T, T_PTR> BaseType; +    typedef LLOctreeNode<T, T_PTR> oct_node;  	LLOctreeRoot(const LLVector4a& center,   				 const LLVector4a& size,  @@ -768,7 +757,7 @@ public:  			oct_node* node = this->getNodeAt(data);  			if (node == this)  			{ -				LLOctreeNode<T>::insert(data); +                oct_node::insert(data);  			}  			else if (node->isInside(data->getPositionGroup()))  			{ @@ -788,13 +777,13 @@ public:  				LLVector4a center, size;  				center = this->getCenter();  				size = this->getSize(); -				LLOctreeNode<T>::pushCenter(center, size, data); +                oct_node::pushCenter(center, size, data);  				this->setCenter(center);  				size.mul(2.f);  				this->setSize(size);  				this->updateMinMax();  			} -			LLOctreeNode<T>::insert(data); +            oct_node::insert(data);  		}  		else  		{ @@ -806,7 +795,7 @@ public:  				//expand this node  				LLVector4a newcenter(center); -				LLOctreeNode<T>::pushCenter(newcenter, size, data); +                oct_node::pushCenter(newcenter, size, data);  				this->setCenter(newcenter);  				LLVector4a size2 = size;  				size2.mul(2.f); @@ -816,11 +805,11 @@ public:  				llassert(size[0] >= gOctreeMinSize);  				//copy our children to a new branch -				LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this); +                oct_node* newnode = new oct_node(center, size, this);  				for (U32 i = 0; i < this->getChildCount(); i++)  				{ -					LLOctreeNode<T>* child = this->getChild(i); +                    oct_node* child = this->getChild(i);  					newnode->addChild(child);  				} @@ -846,8 +835,8 @@ public:  //========================  //		LLOctreeTraveler  //======================== -template <class T> -void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node) +template <class T, typename T_PTR> +void LLOctreeTraveler<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)  {  	node->accept(this);  	for (U32 i = 0; i < node->getChildCount(); i++) @@ -856,8 +845,8 @@ void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)  	}  } -template <class T> -void LLOctreeTravelerDepthFirst<T>::traverse(const LLOctreeNode<T>* node) +template <class T, typename T_PTR> +void LLOctreeTravelerDepthFirst<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)  {  	for (U32 i = 0; i < node->getChildCount(); i++)  	{ diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ac6fb9acb3..f43d07ce5e 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -371,7 +371,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons  	}  } -class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle> +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>  {  public:  	const LLVolumeFace* mFace; @@ -381,7 +381,7 @@ public:  		mFace = face;  	} -	virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch) +    virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)  	{ //this is a depth first traversal, so it's safe to assum all children have complete  		//bounding data  	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME @@ -399,8 +399,7 @@ public:  			min = *(tri->mV[0]);  			max = *(tri->mV[0]); -			for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =  -				branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) +            for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)  			{ //for each triangle in node  				//stretch by triangles in node @@ -684,7 +683,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3  	Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); -	static LLAlignedArray<LLVector4a,64> pt; +	static thread_local LLAlignedArray<LLVector4a,64> pt;  	pt.resize(mTotal) ;  	for (S32 i=mTotalOut;i<mTotal;i++) @@ -2423,6 +2422,13 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			//copy out indices              S32 num_indices = idx.size() / 2; +            const S32 indices_to_discard = num_indices % 3; +            if (indices_to_discard > 0) +            { +                // Invalid number of triangle indices +                LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL; +                num_indices -= indices_to_discard; +            }              face.resizeIndices(num_indices);              if (num_indices > 2 && !face.mIndices) @@ -2438,8 +2444,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			}  			U16* indices = (U16*) &(idx[0]); -			U32 count = idx.size()/2; -			for (U32 j = 0; j < count; ++j) +            for (U32 j = 0; j < num_indices; ++j)  			{  				face.mIndices[j] = indices[j];  			} @@ -3831,8 +3836,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,  #if DEBUG_SILHOUETTE_EDGE_MAP  			//for each triangle -			U32 count = face.mNumIndices; -			for (U32 j = 0; j < count/3; j++) { +            U32 tri_count = face.mNumIndices / 3; +            for (U32 j = 0; j < tri_count; j++) {  				//get vertices  				S32 v1 = face.mIndices[j*3+0];  				S32 v2 = face.mIndices[j*3+1]; @@ -3850,7 +3855,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,  						continue;  					} -					if (nIndex >= (S32) count/3) { +                    if (nIndex >= (S32)tri_count) {  						continue;  					}  					//get neighbor vertices @@ -4142,13 +4147,13 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en  			}  			else  			{ -				if (!face.mOctree) +                if (!face.getOctree())  				{  					face.createOctree();  				}  				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out); -				intersect.traverse(face.mOctree); +                intersect.traverse(face.getOctree());  				if (intersect.mHitFace)  				{  					hit_face = i; @@ -4703,6 +4708,7 @@ LLVolumeFace::LLVolumeFace() :  #endif      mWeightsScrubbed(FALSE),  	mOctree(NULL), +    mOctreeTriangles(NULL),  	mOptimized(FALSE)  {  	mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); @@ -4732,8 +4738,9 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)      mJointIndices(NULL),  #endif      mWeightsScrubbed(FALSE), -	mOctree(NULL) -{  +    mOctree(NULL), +    mOctreeTriangles(NULL) +{  	mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);  	mCenter = mExtents+2;  	*this = src; @@ -4873,8 +4880,7 @@ void LLVolumeFace::freeData()  	mJustWeights = NULL;  #endif -	delete mOctree; -	mOctree = NULL; +    destroyOctree();  }  BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -4882,8 +4888,7 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)  	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME  	//tree for this face is no longer valid -	delete mOctree; -	mOctree = NULL; +    destroyOctree();  	LL_CHECK_MEMORY  	BOOL ret = FALSE ; @@ -5596,21 +5601,27 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe  {  	LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME -	if (mOctree) +    if (getOctree())  	{  		return;  	} -	mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL); +    llassert(mNumIndices % 3 == 0); + +    mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, NULL);  	new LLVolumeOctreeListener(mOctree); +    const U32 num_triangles = mNumIndices / 3; +    // Initialize all the triangles we need +    mOctreeTriangles = new LLVolumeTriangle[num_triangles]; -	for (U32 i = 0; i < mNumIndices; i+= 3) +    for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index)  	{ //for each triangle -		LLPointer<LLVolumeTriangle> tri = new LLVolumeTriangle(); +        const U32 index = triangle_index * 3; +        LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index]; -		const LLVector4a& v0 = mPositions[mIndices[i]]; -		const LLVector4a& v1 = mPositions[mIndices[i+1]]; -		const LLVector4a& v2 = mPositions[mIndices[i+2]]; +		const LLVector4a& v0 = mPositions[mIndices[index]]; +		const LLVector4a& v1 = mPositions[mIndices[index + 1]]; +		const LLVector4a& v2 = mPositions[mIndices[index + 2]];  		//store pointers to vertex data  		tri->mV[0] = &v0; @@ -5618,9 +5629,9 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe  		tri->mV[2] = &v2;  		//store indices -		tri->mIndex[0] = mIndices[i]; -		tri->mIndex[1] = mIndices[i+1]; -		tri->mIndex[2] = mIndices[i+2]; +		tri->mIndex[0] = mIndices[index]; +		tri->mIndex[1] = mIndices[index + 1]; +		tri->mIndex[2] = mIndices[index + 2];  		//get minimum point  		LLVector4a min = v0; @@ -5663,6 +5674,19 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe  	}  } +void LLVolumeFace::destroyOctree() +{ +    delete mOctree; +    mOctree = NULL; +    delete[] mOctreeTriangles; +    mOctreeTriangles = NULL; +} + +const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree() const +{ +    return mOctree; +} +  void LLVolumeFace::swapData(LLVolumeFace& rhs)  { @@ -6534,6 +6558,7 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts)  void LLVolumeFace::resizeIndices(S32 num_indices)  {  	ll_aligned_free_16(mIndices); +    llassert(num_indices % 3 == 0);  	if (num_indices)  	{ @@ -6670,13 +6695,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  			else  			{  				// Get s value for tex-coord. -				if (!flat) +                S32 index = mBeginS + s; +                if (index >= profile.size()) +                { +                    // edge? +                    ss = flat ? 1.f - begin_stex : 1.f; +                } +				else if (!flat)  				{ -					ss = profile[mBeginS + s][2]; +					ss = profile[index][2];  				}  				else  				{ -					ss = profile[mBeginS + s][2] - begin_stex; +					ss = profile[index][2] - begin_stex;  				}  			} @@ -6862,7 +6893,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	LLVector4a* norm = mNormals; -	static LLAlignedArray<LLVector4a, 64> triangle_normals; +    static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals;      try      {          triangle_normals.resize(count); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 9697952f5b..3ccaed47f1 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -35,7 +35,8 @@ class LLVolumeParams;  class LLProfile;  class LLPath; -template <class T> class LLOctreeNode; +template<class T> class LLPointer; +template <class T, typename T_PTR> class LLOctreeNode;  class LLVolumeFace;  class LLVolume; @@ -910,6 +911,9 @@ public:  	bool cacheOptimize();  	void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); +    void destroyOctree(); +    // Get a reference to the octree, which may be null +    const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* getOctree() const;  	enum  	{ @@ -977,13 +981,14 @@ public:      // Which joints are rigged to, and the bounding box of any rigged      // vertices per joint.      LLJointRiggingInfoTab mJointRiggingInfoTab; -     -	LLOctreeNode<LLVolumeTriangle>* mOctree;  	//whether or not face has been cache optimized  	BOOL mOptimized;  private: +    LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* mOctree; +    LLVolumeTriangle* mOctreeTriangles; +  	BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);  	BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);  	BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE); diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index fb232d5f6c..6894d04d3c 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -75,7 +75,7 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c  } -LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node) +LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)  {  	node->addListener(this);  } @@ -85,13 +85,12 @@ LLVolumeOctreeListener::~LLVolumeOctreeListener()  } -void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,  -	LLOctreeNode<LLVolumeTriangle>* child) +void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent,  +    LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child)  {  	new LLVolumeOctreeListener(child);  } -  LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,   							   const LLVolumeFace* face, F32* closest_t,  							   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) @@ -108,7 +107,7 @@ LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& sta  	mEnd.setAdd(mStart, mDir);  } -void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>* node) +void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)  {  	LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); @@ -122,9 +121,9 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>  	}  } -void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node) +void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)  { -	for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =  +    for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter =  			node->getDataBegin(); iter != node->getDataEnd(); ++iter)  	{  		const LLVolumeTriangle* tri = *iter; @@ -219,7 +218,7 @@ const F32& LLVolumeTriangle::getBinRadius() const  //TEST CODE -void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch) +void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)  {  	LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -256,7 +255,7 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)  	}  	//children fit, check data -	for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();  +    for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();  			iter != branch->getDataEnd(); ++iter)  	{  		const LLVolumeTriangle* tri = *iter; @@ -273,4 +272,3 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)  	}  } - diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index b2bc440368..d65bca5e52 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -77,11 +77,11 @@ public:  }; -class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle> +class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle, LLVolumeTriangle*>  {      LL_ALIGN_NEW  public: -	LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node); +    LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);  	~LLVolumeOctreeListener();  	LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) @@ -96,11 +96,9 @@ public:  	}  	 //LISTENER FUNCTIONS -	virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,  -		LLOctreeNode<LLVolumeTriangle>* child); +    virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child);  	virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { } -	virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent,  -			const LLOctreeNode<LLVolumeTriangle>* child) {	} +    virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child) { }  	virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }  	virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }  	virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { } @@ -111,7 +109,7 @@ public:  	LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children  }; -class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle> +class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>  {  public:  	const LLVolumeFace* mFace; @@ -129,14 +127,14 @@ public:  								   const LLVolumeFace* face, F32* closest_t,  								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); -	void traverse(const LLOctreeNode<LLVolumeTriangle>* node); +    void traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node); -	virtual void visit(const LLOctreeNode<LLVolumeTriangle>* node); +    virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);  }; -class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle> +class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>  { -	virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch); +    virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch);  };  #endif  | 
