diff options
| author | Dave Parks <davep@lindenlab.com> | 2010-03-11 12:02:37 -0600 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2010-03-11 12:02:37 -0600 | 
| commit | 4c0e2f79219913b57424bfe136b75a6a58fb8639 (patch) | |
| tree | 784c69a07587bb5fe0ea469d7060c0196cb52caf /indra/llmath | |
| parent | d6547a9b84695b994eef5425d62d19929478109a (diff) | |
"Generate Normals" is less busted now.
Diffstat (limited to 'indra/llmath')
| -rw-r--r-- | indra/llmath/llvolume.cpp | 67 | ||||
| -rw-r--r-- | indra/llmath/llvolume.h | 33 | 
2 files changed, 97 insertions, 3 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d85c56046f..9ea3912a88 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1882,9 +1882,15 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs  	bool retval = false;  	if (rhs.mPosition == mPosition && rhs.mTexCoord == mTexCoord)  	{ -		F32 cur_angle = rhs.mNormal*mNormal; -		 -		retval = cur_angle > angle_cutoff; +		if (angle_cutoff > 1.f) +		{ +			retval = (mNormal == rhs.mNormal); +		} +		else +		{ +			F32 cur_angle = rhs.mNormal*mNormal; +			retval = cur_angle > angle_cutoff; +		}  	}  	return retval; @@ -4953,6 +4959,61 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)  	}  } +void LLVolumeFace::optimize(F32 angle_cutoff) +{ +	LLVolumeFace new_face; + +	VertexMapData::PointMap point_map; + +	//remove redundant vertices +	for (U32 i = 0; i < mIndices.size(); ++i) +	{ +		U16 index = mIndices[i]; + +		LLVolumeFace::VertexData cv = mVertices[index]; + +		BOOL found = FALSE; +		VertexMapData::PointMap::iterator point_iter = point_map.find(cv.mPosition); +		if (point_iter != point_map.end()) +		{ //duplicate point might exist +			for (U32 j = 0; j < point_iter->second.size(); ++j) +			{ +				LLVolumeFace::VertexData& tv = (point_iter->second)[j]; +				if (tv.compareNormal(cv, angle_cutoff)) +				{ +					found = TRUE; +					new_face.mIndices.push_back((point_iter->second)[j].mIndex); +					break; +				} +			} +		} + +		if (!found) +		{ +			new_face.mVertices.push_back(cv); +			U16 index = (U16) new_face.mVertices.size()-1; +			new_face.mIndices.push_back(index); + +			VertexMapData d; +			d.mPosition = cv.mPosition; +			d.mTexCoord = cv.mTexCoord; +			d.mNormal = cv.mNormal; +			d.mIndex = index; +			if (point_iter != point_map.end()) +			{ +				point_iter->second.push_back(d); +			} +			else +			{ +				point_map[d.mPosition].push_back(d); +			} +		} +	} + +	mVertices = new_face.mVertices; +	mIndices = new_face.mIndices; +} +  void	LerpPlanarVertex(LLVolumeFace::VertexData& v0,  				   LLVolumeFace::VertexData& v1,  				   LLVolumeFace::VertexData& v2, diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 36811785dc..f1c1fdceba 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -820,6 +820,39 @@ public:  		bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const;  	}; +	class VertexMapData : public LLVolumeFace::VertexData +	{ +	public: +		U16 mIndex; + +		bool operator==(const LLVolumeFace::VertexData& rhs) const +		{ +			return mPosition == rhs.mPosition && +				mTexCoord == rhs.mTexCoord && +				mNormal == rhs.mNormal; +		} + +		struct ComparePosition +		{ +			bool operator()(const LLVector3& a, const LLVector3& b) const +			{ +				if (a.mV[0] != b.mV[0]) +				{ +					return a.mV[0] < b.mV[0]; +				} +				if (a.mV[1] != b.mV[1]) +				{ +					return a.mV[1] < b.mV[1]; +				} +				return a.mV[2] < b.mV[2]; +			} +		}; + +		typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap; +	}; + +	void optimize(F32 angle_cutoff = 2.f); +	  	enum  	{  		SINGLE_MASK =	0x0001, | 
