diff options
Diffstat (limited to 'indra/llmath')
| -rwxr-xr-x[-rw-r--r--] | indra/llmath/llvolume.cpp | 158 | 
1 files changed, 128 insertions, 30 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 21cc9b22f2..2893e746e9 100644..100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -32,6 +32,7 @@  #if !LL_WINDOWS  #include <stdint.h>  #endif +#include <cmath>  #include "llerror.h"  #include "llmemtype.h" @@ -2379,11 +2380,16 @@ bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)co  bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const  {  	bool retval = false; -	if (rhs.mData[POSITION].equals3(mData[POSITION]) && rhs.mTexCoord == mTexCoord) + +	const F32 epsilon = 0.00001f; + +	if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) &&  +		fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && +		fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon)  	{  		if (angle_cutoff > 1.f)  		{ -			retval = (mData[NORMAL].equals3(rhs.mData[NORMAL])); +			retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon));  		}  		else  		{ @@ -2499,9 +2505,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			}  			{ -				U16* n = (U16*) &(norm[0]); -				if(n) +				if (!norm.empty())  				{ +					U16* n = (U16*) &(norm[0]);  					for (U32 j = 0; j < num_verts; ++j)  					{  						norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); @@ -2512,12 +2518,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  						n += 3;  					}  				} +				else +				{ +					memset(norm_out, 0, sizeof(LLVector4a)*num_verts); +				}  			}  			{ -				U16* t = (U16*) &(tc[0]); -				if(t) +				if (!tc.empty())  				{ +					U16* t = (U16*) &(tc[0]);  					for (U32 j = 0; j < num_verts; j+=2)  					{  						if (j < num_verts-1) @@ -2538,6 +2548,10 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  						tc_out++;  					}  				} +				else +				{ +					memset(tc_out, 0, sizeof(LLVector2)*num_verts); +				}  			}  			if (mdl[i].has("Weights")) @@ -2662,6 +2676,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  					min.setMin(min, face.mPositions[i]);  					max.setMax(max, face.mPositions[i]);  				} + +				if (face.mTexCoords) +				{ +					LLVector2& min_tc = face.mTexCoordExtents[0]; +					LLVector2& max_tc = face.mTexCoordExtents[1]; + +					min_tc = face.mTexCoords[0]; +					max_tc = face.mTexCoords[0]; + +					for (U32 j = 1; j < face.mNumVertices; ++j) +					{ +						update_min_max(min_tc, max_tc, face.mTexCoords[j]); +					} +				} +				else +				{ +					face.mTexCoordExtents[0].set(0,0); +					face.mTexCoordExtents[1].set(1,1); +				}  			}  		}  	} @@ -2741,11 +2774,13 @@ void LLVolume::makeTetrahedron()  	n[2] = cv[2].getNormal();  	n += 3; -	tc[0] = cv[0].mTexCoord; -	tc[1] = cv[1].mTexCoord; -	tc[2] = cv[2].mTexCoord; -	tc += 3; - +	if(tc) +	{ +		tc[0] = cv[0].mTexCoord; +		tc[1] = cv[1].mTexCoord; +		tc[2] = cv[2].mTexCoord; +		tc += 3; +	}  	//side 2  	cv[0].setPosition(p[3]); @@ -2764,11 +2799,14 @@ void LLVolume::makeTetrahedron()  	n[2] = cv[2].getNormal();  	n += 3; -	tc[0] = cv[0].mTexCoord; -	tc[1] = cv[1].mTexCoord; -	tc[2] = cv[2].mTexCoord; -	tc += 3; -	 +	if(tc) +	{ +		tc[0] = cv[0].mTexCoord; +		tc[1] = cv[1].mTexCoord; +		tc[2] = cv[2].mTexCoord; +		tc += 3; +	} +  	//side 3  	cv[0].setPosition(p[3]);  	cv[1].setPosition(p[1]); @@ -2786,10 +2824,13 @@ void LLVolume::makeTetrahedron()  	n[2] = cv[2].getNormal();  	n += 3; -	tc[0] = cv[0].mTexCoord; -	tc[1] = cv[1].mTexCoord; -	tc[2] = cv[2].mTexCoord; -	tc += 3; +	if(tc) +	{ +		tc[0] = cv[0].mTexCoord; +		tc[1] = cv[1].mTexCoord; +		tc[2] = cv[2].mTexCoord; +		tc += 3; +	}  	//side 4  	cv[0].setPosition(p[2]); @@ -2808,10 +2849,13 @@ void LLVolume::makeTetrahedron()  	n[2] = cv[2].getNormal();  	n += 3; -	tc[0] = cv[0].mTexCoord; -	tc[1] = cv[1].mTexCoord; -	tc[2] = cv[2].mTexCoord; -	tc += 3; +	if(tc) +	{ +		tc[0] = cv[0].mTexCoord; +		tc[1] = cv[1].mTexCoord; +		tc[2] = cv[2].mTexCoord; +		tc += 3; +	}  	//set index buffer  	for (U16 i = 0; i < 12; i++) @@ -5580,7 +5624,16 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size);  		LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); -		LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); + +		if(src.mTexCoords) +		{ +			LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); +		} +		else +		{ +			ll_aligned_free_16(mTexCoords) ; +			mTexCoords = NULL ; +		}  		if (src.mBinormals) @@ -5702,8 +5755,23 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)  void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv)  {  	cv.setPosition(mPositions[index]); -	cv.setNormal(mNormals[index]); -	cv.mTexCoord = mTexCoords[index]; +	if (mNormals) +	{ +		cv.setNormal(mNormals[index]); +	} +	else +	{ +		cv.getNormal().clear(); +	} + +	if (mTexCoords) +	{ +		cv.mTexCoord = mTexCoords[index]; +	} +	else +	{ +		cv.mTexCoord.clear(); +	}  }  bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const @@ -5733,7 +5801,10 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  	LLVolumeFace new_face;  	//map of points to vector of vertices at that point -	VertexMapData::PointMap point_map; +	std::map<U64, std::vector<VertexMapData> > point_map; + +	LLVector4a range; +	range.setSub(mExtents[1],mExtents[0]);  	//remove redundant vertices  	for (U32 i = 0; i < mNumIndices; ++i) @@ -5744,7 +5815,19 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  		getVertexData(index, cv);  		BOOL found = FALSE; -		VertexMapData::PointMap::iterator point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr())); + +		LLVector4a pos; +		pos.setSub(mPositions[index], mExtents[0]); +		pos.div(range); + +		U64 pos64 = 0; + +		pos64 = (U16) (pos[0]*65535); +		pos64 = pos64 | (((U64) (pos[1]*65535)) << 16); +		pos64 = pos64 | (((U64) (pos[2]*65535)) << 32); + +		std::map<U64, std::vector<VertexMapData> >::iterator point_iter = point_map.find(pos64); +		  		if (point_iter != point_map.end())  		{ //duplicate point might exist  			for (U32 j = 0; j < point_iter->second.size(); ++j) @@ -5776,11 +5859,26 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  			}  			else  			{ -				point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d); +				point_map[pos64].push_back(d);  			}  		}  	} +	llassert(new_face.mNumIndices == mNumIndices); +	llassert(new_face.mNumVertices <= mNumVertices); + +	if (angle_cutoff > 1.f && !mNormals) +	{ +		ll_aligned_free_16(new_face.mNormals); +		new_face.mNormals = NULL; +	} + +	if (!mTexCoords) +	{ +		ll_aligned_free_16(new_face.mTexCoords); +		new_face.mTexCoords = NULL; +	} +  	swapData(new_face);  } | 
