diff options
| author | Dave Parks <davep@lindenlab.com> | 2010-05-26 03:29:19 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2010-05-26 03:29:19 -0500 | 
| commit | c98b1b3fd9341834978aff0e841714e206d28c0a (patch) | |
| tree | a7690096c11dd57119726dc4872d57aae083154d | |
| parent | e6fe3b1f1aa888e4594c89154ef895b3cf5498e9 (diff) | |
Fully aligned llvolume
| -rw-r--r-- | indra/llmath/llvolume.cpp | 353 | ||||
| -rw-r--r-- | indra/llmath/llvolume.h | 99 | ||||
| -rw-r--r-- | indra/llmath/v3math.h | 1 | ||||
| -rw-r--r-- | indra/newview/llface.cpp | 272 | ||||
| -rw-r--r-- | indra/newview/llpanelprimmediacontrols.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 3 | 
6 files changed, 468 insertions, 264 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d8fbc081fa..9b6e2488e6 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -107,22 +107,27 @@ BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLV  BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size)  { -	float fAWdU[3]; -	LLVector3 dir; -	LLVector3 diff; +	return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV); +} + +BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size) +{ +	F32 fAWdU[3]; +	F32 dir[3]; +	F32 diff[3];  	for (U32 i = 0; i < 3; i++)  	{ -		dir.mV[i] = 0.5f * (end.mV[i] - start.mV[i]); -		diff.mV[i] = (0.5f * (end.mV[i] + start.mV[i])) - center.mV[i]; -		fAWdU[i] = fabsf(dir.mV[i]); -		if(fabsf(diff.mV[i])>size.mV[i] + fAWdU[i]) return false; +		dir[i] = 0.5f * (end[i] - start[i]); +		diff[i] = (0.5f * (end[i] + start[i])) - center[i]; +		fAWdU[i] = fabsf(dir[i]); +		if(fabsf(diff[i])>size[i] + fAWdU[i]) return false;  	}  	float f; -	f = dir.mV[1] * diff.mV[2] - dir.mV[2] * diff.mV[1];    if(fabsf(f)>size.mV[1]*fAWdU[2] + size.mV[2]*fAWdU[1])  return false; -	f = dir.mV[2] * diff.mV[0] - dir.mV[0] * diff.mV[2];    if(fabsf(f)>size.mV[0]*fAWdU[2] + size.mV[2]*fAWdU[0])  return false; -	f = dir.mV[0] * diff.mV[1] - dir.mV[1] * diff.mV[0];    if(fabsf(f)>size.mV[0]*fAWdU[1] + size.mV[1]*fAWdU[0])  return false; +	f = dir[1] * diff[2] - dir[2] * diff[1];    if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1])  return false; +	f = dir[2] * diff[0] - dir[0] * diff[2];    if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0])  return false; +	f = dir[0] * diff[1] - dir[1] * diff[0];    if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0])  return false;  	return true;  } @@ -1869,6 +1874,59 @@ BOOL LLVolume::generate()  	return FALSE;  } +void LLVolumeFace::VertexData::init() +{ +	mData = (LLVector4a*) _mm_malloc(32, 16); +} + +LLVolumeFace::VertexData::VertexData() +{ +	init(); +} +	 +LLVolumeFace::VertexData::VertexData(const VertexData& rhs) +{ +	init(); +	LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); +	mTexCoord = rhs.mTexCoord; +} + +LLVolumeFace::VertexData::~VertexData() +{ +	_mm_free(mData); +} + +LLVector4a& LLVolumeFace::VertexData::getPosition() +{ +	return mData[POSITION]; +} + +LLVector4a& LLVolumeFace::VertexData::getNormal() +{ +	return mData[NORMAL]; +} + +const LLVector4a& LLVolumeFace::VertexData::getPosition() const +{ +	return mData[POSITION]; +} + +const LLVector4a& LLVolumeFace::VertexData::getNormal() const +{ +	return mData[NORMAL]; +} + + +void LLVolumeFace::VertexData::setPosition(const LLVector4a& pos) +{ +	mData[POSITION] = pos; +} + +void LLVolumeFace::VertexData::setNormal(const LLVector4a& norm) +{ +	mData[NORMAL] = norm; +} +  bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const  {  	const U8* l = (const U8*) this; @@ -2037,7 +2095,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			if (mdl[i].has("Weights"))  			{ -				face.mWeights.resize(num_verts); +				face.allocateWeights(num_verts);  				LLSD::Binary weights = mdl[i]["Weights"]; @@ -2050,13 +2108,15 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  					U8 joint = weights[idx++];  					U32 cur_influence = 0; +					LLVector4 wght(0,0,0,0); +  					while (joint != END_INFLUENCES)  					{  						U16 influence = weights[idx++];  						influence |= ((U16) weights[idx++] << 8);  						F32 w = llmin((F32) influence / 65535.f, 0.99999f); -						face.mWeights[cur_vertex].mV[cur_influence++] = (F32) joint + w; +						wght.mV[cur_influence++] = (F32) joint + w;  						if (cur_influence >= 4)  						{ @@ -2068,6 +2128,8 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  						}  					} +					face.mWeights[cur_vertex].loadua(wght.mV); +  					cur_vertex++;  				} @@ -2078,62 +2140,70 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			} -			LLVector3 min_pos; -			LLVector3 max_pos; +			LLVector3 minp; +			LLVector3 maxp;  			LLVector2 min_tc;   			LLVector2 max_tc;  -			min_pos.setValue(mdl[i]["PositionDomain"]["Min"]); -			max_pos.setValue(mdl[i]["PositionDomain"]["Max"]); +			minp.setValue(mdl[i]["PositionDomain"]["Min"]); +			maxp.setValue(mdl[i]["PositionDomain"]["Max"]); +			LLVector4a min_pos, max_pos; +			min_pos.load3(minp.mV); +			max_pos.load3(maxp.mV); +  			min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]);  			max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); -			LLVector3 pos_range = max_pos - min_pos; +			LLVector4a pos_range; +			pos_range.setSub(max_pos, min_pos);  			LLVector2 tc_range = max_tc - min_tc; -			LLVector3& min = face.mExtents[0]; -			LLVector3& max = face.mExtents[1]; - -			min = max = LLVector3(0,0,0); +			LLVector4a& min = face.mExtents[0]; +			LLVector4a& max = face.mExtents[1]; -			F32* pos_out = (F32*) face.mPositions; -			F32* norm_out = (F32*) face.mNormals; -			F32* tc_out = (F32*) face.mTexCoords; +			min.clear(); +			max.clear(); +			 +			LLVector4a* pos_out = face.mPositions; +			LLVector4a* norm_out = face.mNormals; +			LLVector2* tc_out = face.mTexCoords;  			for (U32 j = 0; j < num_verts; ++j)  			{  				U16* v = (U16*) &(pos[j*3*2]); -				pos_out[0] = (F32) v[0] / 65535.f * pos_range.mV[0] + min_pos.mV[0]; -				pos_out[1] = (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1]; -				pos_out[2] = (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]; -			 +				pos_out->set((F32) v[0], (F32) v[1], (F32) v[2]); +				pos_out->div(65535.f); +				pos_out->mul(pos_range); +				pos_out->add(min_pos);  				if (j == 0)  				{ -					min = max = LLVector3(pos_out); +					min = *pos_out; +					max = min;  				}  				else  				{ -					update_min_max(min,max,pos_out); +					min.setMin(*pos_out); +					max.setMax(*pos_out);  				} -				pos_out += 4; +				pos_out++;  				U16* n = (U16*) &(norm[j*3*2]); -				 -				norm_out[0] = (F32) n[0] / 65535.f * 2.f - 1.f; -				norm_out[1] = (F32) n[1] / 65535.f * 2.f - 1.f; -				norm_out[2] = (F32) n[2] / 65535.f * 2.f - 1.f; -				norm_out += 4; +				norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); +				norm_out->div(65535.f); +				norm_out->mul(2.f); +				norm_out->sub(1.f); +				norm_out++;  				U16* t = (U16*) &(tc[j*2*2]); -				tc_out[0] = (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0]; -				tc_out[1] =	(F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]; +				tc_out->mV[0] = (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0]; +				tc_out->mV[1] =	(F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]; -				tc_out += 8; +				tc_out++;  			} @@ -2234,8 +2304,8 @@ void LLVolume::makeTetrahedron()  		LLVector4a(x,-x,-x)  	}; -	face.mExtents[0].setVec(-x,-x,-x); -	face.mExtents[1].setVec(x,x,x); +	face.mExtents[0].splat(-x); +	face.mExtents[1].splat(x);  	LLVolumeFace::VertexData cv[3]; @@ -4166,6 +4236,18 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  								   S32 face,  								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)  { +	LLVector4a starta, enda; +	starta.load3(start.mV); +	enda.load3(end.mV); + +	return lineSegmentIntersect(starta, enda, face, intersection, tex_coord, normal, bi_normal); + +} + +S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  +								   S32 face, +								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +{  	S32 hit_face = -1;  	S32 start_face; @@ -4182,7 +4264,8 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  		end_face = face;  	} -	LLVector3 dir = end - start; +	LLVector4a dir; +	dir.setSub(end, start);  	F32 closest_t = 2.f; // must be larger than 1 @@ -4192,21 +4275,20 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  	{  		LLVolumeFace &face = mVolumeFaces[i]; -		LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f; -		LLVector3 box_size   = face.mExtents[1] - face.mExtents[0]; +		LLVector4a box_center; +		box_center.setAdd(face.mExtents[0], face.mExtents[1]); +		box_center.mul(0.5f); + +		LLVector4a box_size; +		box_size.setSub(face.mExtents[1], face.mExtents[0]); -        if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) +        if (LLLineSegmentBoxIntersect(start.getF32(), end.getF32(), box_center.getF32(), box_size.getF32()))  		{  			if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them  			{  				genBinormals(i);  			} -			LLVector4a starta, dira; - -			starta.load3(start.mV); -			dira.load3(dir.mV); -  			LLVector4a* p = (LLVector4a*) face.mPositions;  			for (U32 tri = 0; tri < face.mNumIndices/3; tri++)  @@ -4220,7 +4302,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  				if (LLTriangleRayIntersect(p[index1],  					p[index2],  					p[index3], -					starta, dira, &a, &b, &t, FALSE)) +					start, dir, &a, &b, &t, FALSE))  				{  					if ((t >= 0.f) &&      // if hit is after start  						(t <= 1.f) &&      // and before end @@ -4231,7 +4313,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  						if (intersection != NULL)  						{ -							*intersection = start + dir * closest_t; +							LLVector4a intersect = dir; +							intersect.mul(closest_t); +							intersect.add(start); +							intersection->set(intersect.getF32());  						} @@ -5029,6 +5114,107 @@ std::ostream& operator<<(std::ostream &s, const LLVolume *volumep)  	return s;  } +LLVolumeFace::LLVolumeFace() :  +	mID(0), +	mTypeMask(0), +	mBeginS(0), +	mBeginT(0), +	mNumS(0), +	mNumT(0), +	mNumVertices(0), +	mNumIndices(0), +	mPositions(NULL), +	mNormals(NULL), +	mBinormals(NULL), +	mTexCoords(NULL), +	mIndices(NULL), +	mWeights(NULL) +{ +	mExtents = (LLVector4a*) _mm_malloc(48, 16); +	mCenter = mExtents+2; +} + +LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) +{  +	mExtents = (LLVector4a*) _mm_malloc(48, 16); +	mCenter = mExtents+2; +	*this = src; +} + +LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) +{ +	if (&src == this) +	{ //self assignment, do nothing +		return *this; +	} + +	mID = src.mID; +	mTypeMask = src.mTypeMask; +	mBeginS = src.mBeginS; +	mBeginT = src.mBeginT; +	mNumS = src.mNumS; +	mNumT = src.mNumT; + +	mNumVertices = 0; +	mNumIndices = 0; +	mPositions = NULL; +	mNormals = NULL; +	mBinormals = NULL; +	mTexCoords = NULL; +	mWeights = NULL; +	mIndices = NULL; + +	LLVector4a::memcpyNonAliased16((F32*) mExtents, (F32*) src.mExtents, 12); + +	resizeVertices(src.mNumVertices); +	resizeIndices(src.mNumIndices); + +	if (mNumVertices) +	{ +		S32 vert_size = mNumVertices*4; +		S32 tc_size = (mNumVertices*8+0xF) & ~0xF; +		tc_size /= 4; +			 +		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, vert_size); + +		if (src.mBinormals) +		{ +			allocateBinormals(src.mNumVertices); +			LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size); +		} +		else +		{ +			_mm_free(mBinormals); +			mBinormals = NULL; +		} + +		if (src.mWeights) +		{ +			allocateWeights(src.mNumVertices); +			LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size); +		} +		else +		{ +			_mm_free(mWeights); +			mWeights = NULL; +		} +	} + +	if (mNumIndices) +	{ +		S32 idx_size = (mNumIndices*2+0xF) & ~0xF; +		idx_size /= 4; + +		LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); +	} +	 + +	//delete  +	return *this; +} +  LLVolumeFace::~LLVolumeFace()  {  	_mm_free(mPositions); @@ -5036,6 +5222,8 @@ LLVolumeFace::~LLVolumeFace()  	_mm_free(mTexCoords);  	_mm_free(mIndices);  	_mm_free(mBinormals); +	_mm_free(mWeights); +	_mm_free(mExtents);  }  BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -5169,8 +5357,8 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  	num_vertices = (grid_size+1)*(grid_size+1);  	num_indices = quad_count * 4; -	LLVector3& min = mExtents[0]; -	LLVector3& max = mExtents[1]; +	LLVector4a& min = mExtents[0]; +	LLVector4a& max = mExtents[1];  	S32 offset = 0;  	if (mTypeMask & TOP_MASK) @@ -5242,16 +5430,18 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  			if (gx == 0 && gy == 0)  			{ -				min = max = LLVector3(newVert.getPosition().getF32()); +				min = max = newVert.getPosition();  			}  			else  			{ -				update_min_max(min,max,newVert.getPosition().getF32()); +				min.setMin(newVert.getPosition()); +				max.setMax(newVert.getPosition());  			}  		}  	} -	mCenter = (min + max) * 0.5f; +	mCenter->setAdd(min, max); +	mCenter->mul(0.5f);   	if (!partial_build)  	{ @@ -5335,7 +5525,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	S32 max_s = volume->getProfile().getTotal();  	S32 max_t = volume->getPath().mPath.size(); -	mCenter.clearVec(); +	mCenter->clear();  	S32 offset = 0;  	if (mTypeMask & TOP_MASK) @@ -5353,8 +5543,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	LLVector2 cuv;  	LLVector2 min_uv, max_uv; -	LLVector3& min = mExtents[0]; -	LLVector3& max = mExtents[1]; +	LLVector4a& min = mExtents[0]; +	LLVector4a& max = mExtents[1];  	LLVector2* tc = (LLVector2*) mTexCoords;  	LLVector4a* pos = (LLVector4a*) mPositions; @@ -5380,25 +5570,24 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  		if (i == 0)  		{ -			min = max = mesh[i+offset].mPos; +			min = max = pos[i];  			min_uv = max_uv = tc[i];  		}  		else  		{ -			update_min_max(min,max, mesh[i+offset].mPos); +			update_min_max(min,max,pos[i]);  			update_min_max(min_uv, max_uv, tc[i]);  		}  	} -	mCenter = (min+max)*0.5f; -	cuv = (min_uv + max_uv)*0.5f; +	mCenter->setAdd(min, max); +	mCenter->mul(0.5f);  -	LLVector4a center; -	center.load3(mCenter.mV); +	cuv = (min_uv + max_uv)*0.5f;  	LLVector4a binormal;  	calc_binormal_from_triangle(binormal, -		center, cuv, +		*mCenter, cuv,  		pos[0], tc[0],  		pos[1], tc[1]);  	binormal.normalize3fast(); @@ -5407,8 +5596,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	LLVector4a d0, d1; -	d0.setSub(center, pos[0]); -	d1.setSub(center, pos[1]); +	d0.setSub(*mCenter, pos[0]); +	d1.setSub(*mCenter, pos[1]);  	if (mTypeMask & TOP_MASK)  	{ @@ -5422,12 +5611,12 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	normal.normalize3fast();  	VertexData vd; -	vd.getPosition().load3(mCenter.mV); +	vd.setPosition(*mCenter);  	vd.mTexCoord = cuv;  	if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))  	{ -		pos[num_vertices].load4a((F32*) ¢er.mQ); +		pos[num_vertices] = *mCenter;  		tc[num_vertices] = cuv;  		num_vertices++;  	} @@ -5812,6 +6001,11 @@ void LLVolumeFace::allocateBinormals(S32 num_verts)  	mBinormals = (LLVector4a*) _mm_malloc(num_verts*16, 16);  } +void LLVolumeFace::allocateWeights(S32 num_verts) +{ +	_mm_free(mWeights); +	mWeights = (LLVector4a*) _mm_malloc(num_verts*16, 16); +}  void LLVolumeFace::resizeIndices(S32 num_indices)  { @@ -5919,11 +6113,11 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  		if (offset == 0 && i == 0)  		{ -			mExtents[0] = mExtents[1] = LLVector3((F32*) &(dst_pos[i].mQ)); +			mExtents[0] = mExtents[1] = dst_pos[i];  		}  		else  		{ -			update_min_max(mExtents[0], mExtents[1], (F32*) &(dst_pos[i].mQ)); +			update_min_max(mExtents[0], mExtents[1], dst_pos[i]);  		}  	} @@ -6076,18 +6270,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	//get bounding box for this side -	LLVector3& face_min = mExtents[0]; -	LLVector3& face_max = mExtents[1]; -	mCenter.clearVec(); +	LLVector4a& face_min = mExtents[0]; +	LLVector4a& face_max = mExtents[1]; +	mCenter->clear(); -	face_min = face_max = LLVector3((F32*) &(pos[0].mQ)); +	face_min = face_max = pos[0];  	for (U32 i = 1; i < mNumVertices; ++i)  	{ -		update_min_max(face_min, face_max, (F32*) &(pos[i].mQ)); +		update_min_max(face_min, face_max, pos[i]);  	} -	mCenter = (face_min + face_max) * 0.5f; +	mCenter->setAdd(face_min, face_max); +	mCenter->mul(0.5f);  	S32 cur_index = 0;  	S32 cur_edge = 0; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index aa58d6d114..7c63266aab 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -50,12 +50,13 @@ class LLVolume;  #include "v2math.h"  #include "v3math.h"  #include "v4math.h" +#include "llvector4a.h"  #include "llquaternion.h"  #include "llstrider.h"  #include "v4coloru.h"  #include "llrefcount.h"  #include "llfile.h" -#include "llvector4a.h" +  //============================================================================ @@ -801,59 +802,19 @@ public:  		};  	private: -		void init() -		{ -			mData = (LLVector4a*) _mm_malloc(32, 16); -		} +		void init();  	public: -		VertexData() -		{ -			init(); -		} -			 -		VertexData(const VertexData& rhs) -		{ -			init(); -			LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); -			mTexCoord = rhs.mTexCoord; -		} - -		~VertexData() -		{ -			_mm_free(mData); -		} - -		LLVector4a& getPosition() -		{ -			return mData[POSITION]; -		} - -		LLVector4a& getNormal() -		{ -			return mData[NORMAL]; -		} - -		const LLVector4a& getPosition() const -		{ -			return mData[POSITION]; -		} - -		const LLVector4a& getNormal() const -		{ -			return mData[NORMAL]; -		} +		VertexData(); +		VertexData(const VertexData& rhs); +		~VertexData(); +		LLVector4a& getPosition(); +		LLVector4a& getNormal(); +		const LLVector4a& getPosition() const; +		const LLVector4a& getNormal() const; +		void setPosition(const LLVector4a& pos); +		void setNormal(const LLVector4a& norm); -		void setPosition(const LLVector4a& pos) -		{ -			mData[POSITION] = pos; -		} - -		void setNormal(const LLVector4a& norm) -		{ -			mData[NORMAL] = norm; -		} -  		LLVector2 mTexCoord;  		bool operator<(const VertexData& rhs) const; @@ -864,22 +825,9 @@ public:  		LLVector4a* mData;  	}; -	LLVolumeFace() :  -		mID(0), -		mTypeMask(0), -		mBeginS(0), -		mBeginT(0), -		mNumS(0), -		mNumT(0), -		mNumVertices(0), -		mNumIndices(0), -		mPositions(NULL), -		mNormals(NULL), -		mBinormals(NULL), -		mTexCoords(NULL), -		mIndices(NULL) -	{ -	} +	LLVolumeFace(); +	LLVolumeFace(const LLVolumeFace& src); +	LLVolumeFace& operator=(const LLVolumeFace& rhs);  	~LLVolumeFace(); @@ -890,6 +838,7 @@ public:  	void resizeVertices(S32 num_verts);  	void allocateBinormals(S32 num_verts); +	void allocateWeights(S32 num_verts);  	void resizeIndices(S32 num_indices);  	void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx); @@ -944,15 +893,15 @@ public:  public:  	S32 mID;  	U32 mTypeMask; -	LLVector3 mCenter; - +	  	// Only used for INNER/OUTER faces  	S32 mBeginS;  	S32 mBeginT;  	S32 mNumS;  	S32 mNumT; -	LLVector3 mExtents[2]; //minimum and maximum point of face +	LLVector4a* mExtents; //minimum and maximum point of face +	LLVector4a* mCenter;  	S32 mNumVertices;  	S32 mNumIndices; @@ -968,7 +917,7 @@ public:  	//list of skin weights for rigged volumes  	// format is mWeights[vertex_index].mV[influence] = <joint_index>.<weight>  	// mWeights.size() should be empty or match mVertices.size()   -	std::vector<LLVector4> mWeights; +	LLVector4a* mWeights;  private:  	BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); @@ -1051,6 +1000,13 @@ public:  							 LLVector3* normal = NULL,               // return the surface normal at the intersection point  							 LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point  		); + +	S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  +								   S32 face = 1, +								   LLVector3* intersection = NULL, +								   LLVector2* tex_coord = NULL, +								   LLVector3* normal = NULL, +								   LLVector3* bi_normal = NULL);  	// The following cleans up vertices and triangles,  	// getting rid of degenerate triangles and duplicate vertices, @@ -1124,6 +1080,7 @@ void calc_binormal_from_triangle(  		const LLVector4a& pos2,  		const LLVector2& tex2); +BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);  BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);  BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 0e7d72e958..75c860a91e 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -36,7 +36,6 @@  #include "llerror.h"  #include "llmath.h" -  #include "llsd.h"  class LLVector2;  class LLVector4; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index db3c5cca33..5cdfdbacde 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -39,6 +39,7 @@  #include "llviewercontrol.h"  #include "llvolume.h"  #include "m3math.h" +#include "llmatrix4a.h"  #include "v3color.h"  #include "lldrawpoolavatar.h" @@ -74,35 +75,43 @@ The resulting texture coordinate <u,v> is:  	u = 2(B dot P)  	v = 2(T dot P)  */ -void planarProjection(LLVector2 &tc, const LLVector3& normal, -					  const LLVector3 &mCenter, const LLVector3& vec) -{	//DONE! -	LLVector3 binormal; -	float d = normal * LLVector3(1,0,0); +void planarProjection(LLVector2 &tc, const LLVector4a& normal, +					  const LLVector4a ¢er, const LLVector4a& vec) +{	 +	LLVector4a binormal; +	F32 d = normal[0]; +  	if (d >= 0.5f || d <= -0.5f)  	{ -		binormal = LLVector3(0,1,0); -		if (normal.mV[0] < 0) +		if (d < 0)  		{ -			binormal = -binormal; +			binormal.set(0,-1,0); +		} +		else +		{ +			binormal.set(0, 1, 0);  		}  	}  	else  	{ -        binormal = LLVector3(1,0,0); -		if (normal.mV[1] > 0) +        if (normal[1] > 0) +		{ +			binormal.set(-1,0,0); +		} +		else  		{ -			binormal = -binormal; +			binormal.set(1,0,0);  		}  	} -	LLVector3 tangent = binormal % normal; +	LLVector4a tangent; +	tangent.setCross3(binormal,normal); -	tc.mV[1] = -((tangent*vec)*2 - 0.5f); -	tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f); +	tc.mV[1] = -((tangent.dot3(vec))*2 - 0.5f); +	tc.mV[0] = 1.0f+((binormal.dot3(vec))*2 - 0.5f);  } -void sphericalProjection(LLVector2 &tc, const LLVector3& normal, -						 const LLVector3 &mCenter, const LLVector3& vec) +void sphericalProjection(LLVector2 &tc, const LLVector4a& normal, +						 const LLVector4a &mCenter, const LLVector4a& vec)  {	//BROKEN  	/*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; @@ -113,7 +122,7 @@ void sphericalProjection(LLVector2 &tc, const LLVector3& normal,  	}*/  } -void cylindricalProjection(LLVector2 &tc, const LLVector3& normal, const LLVector3 &mCenter, const LLVector3& vec) +void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec)  {	//BROKEN  	/*LLVector3 binormal;  	float d = vd.mNormal * LLVector3(1,0,0); @@ -371,7 +380,14 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)  	if (align)  	{  		//allocate vertices in blocks of 4 for alignment -		S32 num_vertices = (num_vertices + 0x3) & ~0x3; +		num_vertices = (num_vertices + 0x3) & ~0x3; +	} +	else +	{ +		if (mDrawablep->getVOVolume()) +		{ +			llerrs << "WTF?" << llendl; +		}  	}  	if (mGeomCount != num_vertices || @@ -722,6 +738,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		//	mLastVertexBuffer = NULL;  		//} +		//VECTORIZE THIS  		LLVector3 min,max;  		if (f >= volume.getNumVolumeFaces()) @@ -732,8 +749,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		else  		{  			const LLVolumeFace &face = volume.getVolumeFace(f); -			min = face.mExtents[0]; -			max = face.mExtents[1]; +			min.set(face.mExtents[0].getF32()); +			max.set(face.mExtents[1].getF32());  		}  		//min, max are in volume space, convert to drawable render space @@ -824,18 +841,26 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,  		return surface_coord;  	} +	//VECTORIZE THIS  	// see if we have a non-default mapping      U8 texgen = getTextureEntry()->getTexGen();  	if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)  	{ -		LLVector3 center = mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter; +		LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter); -		LLVector3 scale  = (mDrawablep->getVOVolume()->isVolumeGlobal()) ? LLVector3(1,1,1) : mVObjp->getScale(); -		LLVector3 volume_position = mDrawablep->getVOVolume()->agentPositionToVolume(position); -		volume_position.scaleVec(scale); +		LLVector4a volume_position; +		volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV); -		LLVector3 volume_normal   = mDrawablep->getVOVolume()->agentDirectionToVolume(normal); -		volume_normal.normalize(); +		if (!mDrawablep->getVOVolume()->isVolumeGlobal()) +		{ +			LLVector4a scale; +			scale.load3(mVObjp->getScale().mV); +			volume_position.mul(scale); +		} +		 +		LLVector4a volume_normal; +		volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV); +		volume_normal.normalize3fast();  		switch (texgen)  		{ @@ -928,7 +953,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom");  BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							   const S32 &f, -								const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, +								const LLMatrix4& mat_vert_in, const LLMatrix3& mat_norm_in,  								const U16 &index_offset,  								bool force_rebuild)  { @@ -960,14 +985,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		}  	} -	LLStrider<LLVector3> vertices; +	LLStrider<LLVector3> vert; +	LLVector4a* vertices = NULL;  	LLStrider<LLVector2> tex_coords;  	LLStrider<LLVector2> tex_coords2; -	LLStrider<LLVector3> normals; +	LLVector4a* normals = NULL; +	LLStrider<LLVector3> norm;  	LLStrider<LLColor4U> colors; -	LLStrider<LLVector3> binormals; +	LLVector4a* binormals = NULL; +	LLStrider<LLVector3> binorm;  	LLStrider<U16> indicesp; -	LLStrider<LLVector4> weights; +	LLVector4a* weights = NULL; +	LLStrider<LLVector4> wght;  	BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME); @@ -982,11 +1011,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		scale = mVObjp->getScale();  	} -	BOOL rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION); -	BOOL rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR); -	BOOL rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); -	BOOL rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); -	BOOL rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL); +	bool rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION); +	bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR); +	bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); +	bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); +	bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL);  	bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);  	const LLTextureEntry *tep = mVObjp->getTE(f); @@ -994,19 +1023,23 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	if (rebuild_pos)  	{ -		mVertexBuffer->getVertexStrider(vertices, mGeomIndex); +		mVertexBuffer->getVertexStrider(vert, mGeomIndex); +		vertices = (LLVector4a*) vert.get();  	}  	if (rebuild_normal)  	{ -		mVertexBuffer->getNormalStrider(normals, mGeomIndex); +		mVertexBuffer->getNormalStrider(norm, mGeomIndex); +		normals = (LLVector4a*) norm.get();  	}  	if (rebuild_binormal)  	{ -		mVertexBuffer->getBinormalStrider(binormals, mGeomIndex); +		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex); +		binormals = (LLVector4a*) binorm.get();  	}  	if (rebuild_weights)  	{ -		mVertexBuffer->getWeight4Strider(weights, mGeomIndex); +		mVertexBuffer->getWeight4Strider(wght, mGeomIndex); +		weights = (LLVector4a*) wght.get();  	}  	F32 tcoord_xoffset = 0.f ; @@ -1058,8 +1091,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	LLVector2 tmin, tmax; -	 -  	if (rebuild_tcoord)  	{  		if (tep) @@ -1142,9 +1173,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	//bump setup -	LLVector3 binormal_dir( -sin_ang, cos_ang, 0 ); -	LLVector3 bump_s_primary_light_ray; -	LLVector3 bump_t_primary_light_ray; +	LLVector4a binormal_dir( -sin_ang, cos_ang, 0 ); +	LLVector4a bump_s_primary_light_ray; +	LLVector4a bump_t_primary_light_ray;  	LLQuaternion bump_quat;  	if (mDrawablep->isActive()) @@ -1196,8 +1227,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		LLVector3   moon_ray = gSky.getMoonDirection();  		LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; -		bump_s_primary_light_ray = offset_multiple * s_scale * primary_light_ray; -		bump_t_primary_light_ray = offset_multiple * t_scale * primary_light_ray; +		bump_s_primary_light_ray; +		bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); +		bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);  	}  	U8 texgen = getTextureEntry()->getTexGen(); @@ -1206,45 +1238,47 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		mVObjp->getVolume()->genBinormals(f);  	} +	LLMatrix4a mat_normal; + +	if (rebuild_normal || rebuild_binormal || rebuild_tcoord) +	{ +		mat_normal.loadu(mat_norm_in); +	} +	  	//if it's not fullbright and has no normals, bake sunlight based on face normal  	bool bake_sunlight = !getTextureEntry()->getFullbright() &&  		!mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); -	//VECTORIZE THIS -	for (S32 i = 0; i < num_vertices; i++) +	if (rebuild_tcoord)  	{ -		LLVector3 vf_binormal; -		if (vf.mBinormals) -		{ -			vf_binormal.setVec(vf.mBinormals[i].getF32()); -		} +		LLVector4a scalea; +		scalea.load3(scale.mV); -		LLVector3 vf_normal; -		vf_normal.set(vf.mNormals[i].getF32()); -		LLVector3 vf_position; -		vf_position.set(vf.mPositions[i].getF32()); - -		if (rebuild_tcoord) -		{ +		for (S32 i = 0; i < num_vertices; i++) +		{	  			LLVector2 tc(vf.mTexCoords[i]); +			LLVector4a& norm = vf.mNormals[i]; +			 +			LLVector4a& center = *(vf.mCenter); +  			if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)  			{ -				LLVector3 vec = vf_position; +				LLVector4a vec = vf.mPositions[i]; -				vec.scaleVec(scale); +				vec.mul(scalea);  				switch (texgen)  				{  					case LLTextureEntry::TEX_GEN_PLANAR: -						planarProjection(tc, vf_normal, vf.mCenter, vec); +						planarProjection(tc, norm, center, vec);  						break;  					case LLTextureEntry::TEX_GEN_SPHERICAL: -						sphericalProjection(tc, vf_normal, vf.mCenter, vec); +						sphericalProjection(tc, norm, center, vec);  						break;  					case LLTextureEntry::TEX_GEN_CYLINDRICAL: -						cylindricalProjection(tc, vf_normal, vf.mCenter, vec); +						cylindricalProjection(tc, norm, center, vec);  						break;  					default:  						break; @@ -1351,68 +1385,84 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			*tex_coords++ = tc; -		 +			  			if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))  			{ -				LLVector3 tangent = vf_binormal % vf_normal; - -				LLMatrix3 tangent_to_object; -				tangent_to_object.setRows(tangent, vf_binormal, vf_normal); -				LLVector3 binormal = binormal_dir * tangent_to_object; -				binormal = binormal * mat_normal; -				 +				LLVector4a tangent; +				tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); + +				LLMatrix4a tangent_to_object; +				tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); +				LLVector4a t; +				tangent_to_object.rotate(binormal_dir, t); +				LLVector4a binormal; +				mat_normal.rotate(t, binormal); +					 +				//VECTORIZE THIS  				if (mDrawablep->isActive())  				{ -					binormal *= bump_quat; +					LLVector3 t; +					t.set(binormal.getF32()); +					t *= bump_quat; +					binormal.load3(t.mV);  				} -				binormal.normVec(); -				tc += LLVector2( bump_s_primary_light_ray * tangent, bump_t_primary_light_ray * binormal ); +				binormal.normalize3fast(); +				tc += LLVector2( bump_s_primary_light_ray.dot3(tangent), bump_t_primary_light_ray.dot3(binormal) );  				*tex_coords2++ = tc;  			}	  		} -			 -		if (rebuild_pos) -		{ -			*vertices++ = vf_position * mat_vert; -		} -		 -		if (rebuild_normal) -		{ -			LLVector3 normal = vf_normal * mat_normal; -			normal.normVec(); -			 -			*normals++ = normal; +	} + +	if (rebuild_pos) +	{ +		LLMatrix4a mat_vert; +		mat_vert.loadu(mat_vert_in); + +		for (S32 i = 0; i < num_vertices; i++) +		{	 +			mat_vert.affineTransform(vf.mPositions[i], vertices[i]);  		} +	} -		if (rebuild_binormal) -		{ -			LLVector3 binormal = vf_binormal * mat_normal; -			binormal.normVec(); -			*binormals++ = binormal; +	if (rebuild_normal) +	{ +		for (S32 i = 0; i < num_vertices; i++) +		{	 +			LLVector4a normal; +			mat_normal.rotate(vf.mNormals[i], normal); +			normal.normalize3fast(); +			normals[i] = normal;  		} +	} -		if (rebuild_weights && vf.mWeights.size() > i) -		{ -			(*weights++) = vf.mWeights[i]; +	if (rebuild_binormal) +	{ +		for (S32 i = 0; i < num_vertices; i++) +		{	 +			LLVector4a binormal; +			mat_normal.rotate(vf.mBinormals[i], binormal); +			binormal.normalize3fast(); +			binormals[i] = binormal;  		} +	} +	 +	if (rebuild_weights && vf.mWeights) +	{ +		LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices/4); +	} -		if (rebuild_color) -		{ -			if (bake_sunlight) -			{ -				LLVector3 normal = vf_normal * mat_normal; -				normal.normVec(); -				 -				F32 da = normal * gPipeline.mSunDir; +	if (rebuild_color) +	{ +		LLVector4a src; -				*colors++ = LLColor4U(U8(color.mV[0]*da), U8(color.mV[1]*da), U8(color.mV[2]*da), color.mV[3]); -			} -			else -			{ -				*colors++ = color;		 -			} +		src.splat(reinterpret_cast<F32&>(color.mAll)); + +		F32* dst = (F32*) colors.get(); +		for (S32 i = 0; i < num_vertices; i+=4) +		{	 +			LLVector4a::copy4a(dst+i, (F32*) &src);  		}  	} diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 0648d99685..a5804aa04e 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -574,7 +574,9 @@ void LLPanelPrimMediaControls::updateShape()  		{  			const LLVolumeFace& vf = volume->getVolumeFace(mTargetObjectFace); -			const LLVector3* ext = vf.mExtents; +			LLVector3 ext[2]; +			ext[0].set(vf.mExtents[0].getF32()); +			ext[1].set(vf.mExtents[1].getF32());  			LLVector3 center = (ext[0]+ext[1])*0.5f;  			LLVector3 size = (ext[1]-ext[0])*0.5f; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8022f81f19..c03ec67c79 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1602,7 +1602,8 @@ void LLVOVolume::updateFaceSize(S32 idx)  	else  	{  		const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); -		facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices); +		facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,  +						true); // <--- volume faces should be padded for 16-byte alignment  	}  }  | 
