diff options
44 files changed, 718 insertions, 609 deletions
| diff --git a/doc/contributions.txt b/doc/contributions.txt index b942bc4c19..66ccb404a8 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -404,6 +404,7 @@ Ganymedes Costagravas  Geenz Spad  	STORM-1823  	STORM-1900 +	NORSPEC-229  Gene Frostbite  GeneJ Composer  Geneko Nemeth diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3f06e6b99e..bf03c971cd 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2079,9 +2079,9 @@ void LLVolume::regen()  	createVolumeFaces();  } -void LLVolume::genBinormals(S32 face) +void LLVolume::genTangents(S32 face)  { -	mVolumeFaces[face].createBinormals(); +	mVolumeFaces[face].createTangents();  }  LLVolume::~LLVolume() @@ -4392,7 +4392,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,  				segments.push_back(vertices.size());  #if DEBUG_SILHOUETTE_BINORMALS  				vertices.push_back(face.mVertices[j].getPosition()); -				vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mBinormal*0.1f); +				vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f);  				normals.push_back(LLVector3(0,0,1));  				normals.push_back(LLVector3(0,0,1));  				segments.push_back(vertices.size()); @@ -4508,22 +4508,9 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,  	}  } -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) +								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out)  {  	S32 hit_face = -1; @@ -4561,9 +4548,9 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en          if (LLLineSegmentBoxIntersect(start, end, box_center, box_size))  		{ -			if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them +			if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them  			{ -				genBinormals(i); +				genTangents(i);  			}  			if (isUnique()) @@ -4597,7 +4584,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en  								LLVector4a intersect = dir;  								intersect.mul(closest_t);  								intersect.add(start); -								intersection->set(intersect.getF32ptr()); +								*intersection = intersect;  							} @@ -4612,19 +4599,42 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en  							if (normal!= NULL)  							{ -								LLVector4* norm = (LLVector4*) face.mNormals; - -								*normal		= ((1.f - a - b)  * LLVector3(norm[idx0]) +  -									a              * LLVector3(norm[idx1]) + -									b              * LLVector3(norm[idx2])); +								LLVector4a* norm = face.mNormals; +								 +								LLVector4a n1,n2,n3; +								n1 = norm[idx0]; +								n1.mul(1.f-a-b); +								 +								n2 = norm[idx1]; +								n2.mul(a); +								 +								n3 = norm[idx2]; +								n3.mul(b); + +								n1.add(n2); +								n1.add(n3); +								 +								*normal		= n1;   							} -							if (bi_normal != NULL) +							if (tangent_out != NULL)  							{ -								LLVector4* binormal = (LLVector4*) face.mBinormals; -								*bi_normal = ((1.f - a - b)  * LLVector3(binormal[idx0]) +  -										a              * LLVector3(binormal[idx1]) + -										b              * LLVector3(binormal[idx2])); +								LLVector4a* tangents = face.mTangents; +								 +								LLVector4a t1,t2,t3; +								t1 = tangents[idx0]; +								t1.mul(1.f-a-b); +								 +								t2 = tangents[idx1]; +								t2.mul(a); +								 +								t3 = tangents[idx2]; +								t3.mul(b); + +								t1.add(t2); +								t1.add(t3); +								 +								*tangent_out = t1;   							}  						}  					} @@ -4637,7 +4647,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en  					face.createOctree();  				} -				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); +				LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);  				intersect.traverse(face.mOctree);  				if (intersect.mHitFace)  				{ @@ -5183,7 +5193,7 @@ LLVolumeFace::LLVolumeFace() :  	mNumIndices(0),  	mPositions(NULL),  	mNormals(NULL), -	mBinormals(NULL), +	mTangents(NULL),  	mTexCoords(NULL),  	mIndices(NULL),  	mWeights(NULL), @@ -5206,7 +5216,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)  	mNumIndices(0),  	mPositions(NULL),  	mNormals(NULL), -	mBinormals(NULL), +	mTangents(NULL),  	mTexCoords(NULL),  	mIndices(NULL),  	mWeights(NULL), @@ -5264,15 +5274,15 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		} -		if (src.mBinormals) +		if (src.mTangents)  		{ -			allocateBinormals(src.mNumVertices); -			LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size); +			allocateTangents(src.mNumVertices); +			LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size);  		}  		else  		{ -			ll_aligned_free_16(mBinormals); -			mBinormals = NULL; +			ll_aligned_free_16(mTangents); +			mTangents = NULL;  		}  		if (src.mWeights) @@ -5316,8 +5326,8 @@ void LLVolumeFace::freeData()  	mTexCoords = NULL;  	ll_aligned_free_16(mIndices);  	mIndices = NULL; -	ll_aligned_free_16(mBinormals); -	mBinormals = NULL; +	ll_aligned_free_16(mTangents); +	mTangents = NULL;  	ll_aligned_free_16(mWeights);  	mWeights = NULL; @@ -5897,7 +5907,7 @@ void LLVolumeFace::cacheOptimize()  	}  	LLVector4a* binorm = NULL; -	if (mBinormals) +	if (mTangents)  	{  		binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  	} @@ -5922,9 +5932,9 @@ void LLVolumeFace::cacheOptimize()  			{  				wght[cur_idx] = mWeights[idx];  			} -			if (mBinormals) +			if (mTangents)  			{ -				binorm[cur_idx] = mBinormals[idx]; +				binorm[cur_idx] = mTangents[idx];  			}  			cur_idx++; @@ -5940,13 +5950,13 @@ void LLVolumeFace::cacheOptimize()  	ll_aligned_free_16(mNormals);  	ll_aligned_free_16(mTexCoords);  	ll_aligned_free_16(mWeights); -	ll_aligned_free_16(mBinormals); +	ll_aligned_free_16(mTangents);  	mPositions = pos;  	mNormals = norm;  	mTexCoords = tc;  	mWeights = wght; -	mBinormals = binorm; +	mTangents = binorm;  	//std::string result = llformat("ACMR pre/post: %.3f/%.3f  --  %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);  	//llinfos << result << llendl; @@ -6027,7 +6037,7 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs)  {  	llswap(rhs.mPositions, mPositions);  	llswap(rhs.mNormals, mNormals); -	llswap(rhs.mBinormals, mBinormals); +	llswap(rhs.mTangents, mTangents);  	llswap(rhs.mTexCoords, mTexCoords);  	llswap(rhs.mIndices,mIndices);  	llswap(rhs.mNumVertices, mNumVertices); @@ -6116,22 +6126,11 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  			corners[2].mTexCoord=swap;  		} -		LLVector4a binormal; -		 -		calc_binormal_from_triangle( binormal, -			corners[0].getPosition(), corners[0].mTexCoord, -			corners[1].getPosition(), corners[1].mTexCoord, -			corners[2].getPosition(), corners[2].mTexCoord); -		 -		binormal.normalize3fast(); -  		S32 size = (grid_size+1)*(grid_size+1);  		resizeVertices(size); -		allocateBinormals(size); - +		  		LLVector4a* pos = (LLVector4a*) mPositions;  		LLVector4a* norm = (LLVector4a*) mNormals; -		LLVector4a* binorm = (LLVector4a*) mBinormals;  		LLVector2* tc = (LLVector2*) mTexCoords;  		for(int gx = 0;gx<grid_size+1;gx++) @@ -6150,8 +6149,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  				*pos++ = newVert.getPosition();  				*norm++ = baseVert.getNormal();  				*tc++ = newVert.mTexCoord; -				*binorm++ = binormal; - +				  				if (gx == 0 && gy == 0)  				{  					min = newVert.getPosition(); @@ -6227,8 +6225,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))  	{  		resizeVertices(num_vertices+1); -		allocateBinormals(num_vertices+1);	 - +		  		if (!partial_build)  		{  			resizeIndices(num_indices+3); @@ -6237,8 +6234,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	else  	{  		resizeVertices(num_vertices); -		allocateBinormals(num_vertices); - +		  		if (!partial_build)  		{  			resizeIndices(num_indices); @@ -6272,8 +6268,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	LLVector2* tc = (LLVector2*) mTexCoords;  	LLVector4a* pos = (LLVector4a*) mPositions;  	LLVector4a* norm = (LLVector4a*) mNormals; -	LLVector4a* binorm = (LLVector4a*) mBinormals; - +	  	// Copy the vertices into the array  	for (S32 i = 0; i < num_vertices; i++)  	{ @@ -6309,13 +6304,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	cuv = (min_uv + max_uv)*0.5f; -	LLVector4a binormal; -	calc_binormal_from_triangle(binormal, -		*mCenter, cuv, -		pos[0], tc[0], -		pos[1], tc[1]); -	binormal.normalize3fast(); -  	LLVector4a normal;  	LLVector4a d0, d1; @@ -6347,7 +6335,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	for (S32 i = 0; i < num_vertices; i++)  	{ -		binorm[i].load4a(binormal.getF32ptr());  		norm[i].load4a(normal.getF32ptr());  	} @@ -6589,59 +6576,65 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	return TRUE;  } -void LLVolumeFace::createBinormals() +void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, +        const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); + +void LLVolumeFace::createTangents()  { -	if (!mBinormals) +	if (!mTangents)  	{ -		allocateBinormals(mNumVertices); +		allocateTangents(mNumVertices); -		//generate binormals -		LLVector4a* pos = mPositions; -		LLVector2* tc = (LLVector2*) mTexCoords; -		LLVector4a* binorm = (LLVector4a*) mBinormals; +		//generate tangents +		//LLVector4a* pos = mPositions; +		//LLVector2* tc = (LLVector2*) mTexCoords; +		LLVector4a* binorm = (LLVector4a*) mTangents; -		LLVector4a* end = mBinormals+mNumVertices; +		LLVector4a* end = mTangents+mNumVertices;  		while (binorm < end)  		{  			(*binorm++).clear();  		} -		binorm = mBinormals; +		binorm = mTangents; + +		CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents); -		for (U32 i = 0; i < mNumIndices/3; i++)  +		/*for (U32 i = 0; i < mNumIndices/3; i++)   		{	//for each triangle  			const U16& i0 = mIndices[i*3+0];  			const U16& i1 = mIndices[i*3+1];  			const U16& i2 = mIndices[i*3+2]; -			//calculate binormal -			LLVector4a binormal; -			calc_binormal_from_triangle(binormal, +			//calculate tangent +			LLVector4a tangent; +			calc_tangent_from_triangle(tangent,  										pos[i0], tc[i0],  										pos[i1], tc[i1],  										pos[i2], tc[i2]);  			//add triangle normal to vertices -			binorm[i0].add(binormal); -			binorm[i1].add(binormal); -			binorm[i2].add(binormal); +			binorm[i0].add(tangent); +			binorm[i1].add(tangent); +			binorm[i2].add(tangent);  			//even out quad contributions  			if (i % 2 == 0)   			{ -				binorm[i2].add(binormal); +				binorm[i2].add(tangent);  			}  			else   			{ -				binorm[i1].add(binormal); +				binorm[i1].add(tangent);  			} -		} +		}*/ + -		//normalize binormals +		//normalize tangents  		for (U32 i = 0; i < mNumVertices; i++)   		{ -			binorm[i].normalize3fast(); +			//binorm[i].normalize3fast();  			//bump map/planar projection code requires normals to be normalized  			mNormals[i].normalize3fast();  		} @@ -6652,10 +6645,10 @@ void LLVolumeFace::resizeVertices(S32 num_verts)  {  	ll_aligned_free_16(mPositions);  	ll_aligned_free_16(mNormals); -	ll_aligned_free_16(mBinormals); +	ll_aligned_free_16(mTangents);  	ll_aligned_free_16(mTexCoords); -	mBinormals = NULL; +	mTangents = NULL;  	if (num_verts)  	{ @@ -6705,9 +6698,9 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con  	ll_assert_aligned(mTexCoords,16); -	//just clear binormals -	ll_aligned_free_16(mBinormals); -	mBinormals = NULL; +	//just clear tangents +	ll_aligned_free_16(mTangents); +	mTangents = NULL;  	mPositions[mNumVertices] = pos;  	mNormals[mNumVertices] = norm; @@ -6716,10 +6709,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con  	mNumVertices++;	  } -void LLVolumeFace::allocateBinormals(S32 num_verts) +void LLVolumeFace::allocateTangents(S32 num_verts)  { -	ll_aligned_free_16(mBinormals); -	mBinormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); +	ll_aligned_free_16(mTangents); +	mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  }  void LLVolumeFace::allocateWeights(S32 num_verts) @@ -7231,53 +7224,87 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	return TRUE;  } -// Finds binormal based on three vertices with texture coordinates. -// Fills in dummy values if the triangle has degenerate texture coordinates. -void calc_binormal_from_triangle(LLVector4a& binormal, - -	const LLVector4a& pos0, -	const LLVector2& tex0, -	const LLVector4a& pos1, -	const LLVector2& tex1, -	const LLVector4a& pos2, -	const LLVector2& tex2) -{ -	LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] ); -	LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] ); -	LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] ); -	 -	LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] ); -	LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] ); -	LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] ); - -	LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] ); -	LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] ); -	LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] ); -	 -	LLVector4a lhs, rhs; - -	LLVector4a r0;  -	lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2); -	r0.setCross3(lhs, rhs); +//adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html +void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, +        const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) +{ +    //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; +	LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); + +    LLVector4a* tan2 = tan1 + vertexCount; + +	memset(tan1, 0, vertexCount*2*sizeof(LLVector4a)); +         +    for (U32 a = 0; a < triangleCount; a++) +    { +        U32 i1 = *index_array++; +        U32 i2 = *index_array++; +        U32 i3 = *index_array++; +         +        const LLVector4a& v1 = vertex[i1]; +        const LLVector4a& v2 = vertex[i2]; +        const LLVector4a& v3 = vertex[i3]; +         +        const LLVector2& w1 = texcoord[i1]; +        const LLVector2& w2 = texcoord[i2]; +        const LLVector2& w3 = texcoord[i3]; +         +		const F32* v1ptr = v1.getF32ptr(); +		const F32* v2ptr = v2.getF32ptr(); +		const F32* v3ptr = v3.getF32ptr(); -	LLVector4a r1; -	lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2); -	r1.setCross3(lhs, rhs); - -	LLVector4a r2; -	lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2); -	r2.setCross3(lhs, rhs); +        float x1 = v2ptr[0] - v1ptr[0]; +        float x2 = v3ptr[0] - v1ptr[0]; +        float y1 = v2ptr[1] - v1ptr[1]; +        float y2 = v3ptr[1] - v1ptr[1]; +        float z1 = v2ptr[2] - v1ptr[2]; +        float z2 = v3ptr[2] - v1ptr[2]; +         +        float s1 = w2.mV[0] - w1.mV[0]; +        float s2 = w3.mV[0] - w1.mV[0]; +        float t1 = w2.mV[1] - w1.mV[1]; +        float t2 = w3.mV[1] - w1.mV[1]; +         +        float r = 1.0F / (s1 * t2 - s2 * t1); +        LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, +                (t2 * z1 - t1 * z2) * r); +        LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, +                (s1 * z2 - s2 * z1) * r); +         +        tan1[i1].add(sdir); +        tan1[i2].add(sdir); +        tan1[i3].add(sdir); +         +        tan2[i1].add(tdir); +        tan2[i2].add(tdir); +        tan2[i3].add(tdir); +    } +     +    for (U32 a = 0; a < vertexCount; a++) +    { +        LLVector4a n = normal[a]; +        const LLVector4a& t = tan1[a]; +         +		LLVector4a ncrosst; +		ncrosst.setCross3(n,t); + +        // Gram-Schmidt orthogonalize +        n.mul(n.dot3(t).getF32()); + +		LLVector4a tsubn; +		tsubn.setSub(t,n); + +		tsubn.normalize3fast(); +		 +        // Calculate handedness +		F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f; +		 +		tsubn.getF32ptr()[3] = handedness; -	if( r0[VX] && r1[VX] && r2[VX] ) -	{ -		binormal.set( -				-r0[VZ] / r0[VX], -				-r1[VZ] / r1[VX], -				-r2[VZ] / r2[VX]); -		// binormal.normVec(); -	} -	else -	{ -		binormal.set( 0, 1 , 0 ); -	} +        tangent[a] = tsubn; +    } +     +	ll_aligned_free_16(tan1);  } + + diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c845556557..164b8d6652 100755 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -844,12 +844,12 @@ private:  public:  	BOOL create(LLVolume* volume, BOOL partial_build = FALSE); -	void createBinormals(); +	void createTangents();  	void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);  	void resizeVertices(S32 num_verts); -	void allocateBinormals(S32 num_verts); +	void allocateTangents(S32 num_verts);  	void allocateWeights(S32 num_verts);  	void resizeIndices(S32 num_indices);  	void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx); @@ -916,7 +916,7 @@ public:  	LLVector4a* mPositions;  	LLVector4a* mNormals; -	LLVector4a* mBinormals; +	LLVector4a* mTangents;  	LLVector2*  mTexCoords;  	U16* mIndices; @@ -980,7 +980,7 @@ public:  	void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }  	void regen(); -	void genBinormals(S32 face); +	void genTangents(S32 face);  	BOOL isConvex() const;  	BOOL isCap(S32 face); @@ -1008,21 +1008,14 @@ public:  	//get the face index of the face that intersects with the given line segment at the point   	//closest to start.  Moves end to the point of intersection.  Returns -1 if no intersection.  	//Line segment must be in volume space. -	S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  							 S32 face = -1,                          // which face to check, -1 = ALL_SIDES -							 LLVector3* intersection = NULL,         // return the intersection point +							 LLVector4a* intersection = NULL,         // return the intersection point  							 LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -							 LLVector3* normal = NULL,               // return the surface normal at the intersection point -							 LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +							 LLVector4a* normal = NULL,               // return the surface normal at the intersection point +							 LLVector4a* tangent = NULL             // return the surface tangent 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); -	  	LLFaceID generateFaceMask();  	BOOL isFaceMaskValid(LLFaceID face_mask); @@ -1081,21 +1074,12 @@ public:  std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); -void calc_binormal_from_triangle( -		LLVector4a& binormal, -		const LLVector4a& pos0, -		const LLVector2& tex0, -		const LLVector4a& pos1, -		const LLVector2& tex1, -		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 LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size); -BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, -							F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided); +//BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, +//							F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);  BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,  							F32& intersection_a, F32& intersection_b, F32& intersection_t); diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index cc83cb7235..0728b49c1f 100755 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -94,14 +94,14 @@ void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTria  LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,   							   const LLVolumeFace* face, F32* closest_t, -							   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +							   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)     : mFace(face),       mStart(start),  	 mDir(dir),  	 mIntersection(intersection),  	 mTexCoord(tex_coord),  	 mNormal(normal), -	 mBinormal(bi_normal), +	 mTangent(tangent),  	 mClosestT(closest_t),  	 mHitFace(false)  { @@ -112,13 +112,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>  {  	LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); -	/*const F32* start = mStart.getF32(); -	const F32* end = mEnd.getF32(); -	const F32* center = vl->mBounds[0].getF32(); -	const F32* size = vl->mBounds[1].getF32();*/ - -	//if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) -	if (LLLineSegmentBoxIntersect(mStart.getF32ptr(), mEnd.getF32ptr(), vl->mBounds[0].getF32ptr(), vl->mBounds[1].getF32ptr())) +	if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))  	{  		node->accept(this);  		for (S32 i = 0; i < node->getChildCount(); ++i) @@ -152,34 +146,60 @@ void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* n  					LLVector4a intersect = mDir;  					intersect.mul(*mClosestT);  					intersect.add(mStart); -					mIntersection->set(intersect.getF32ptr()); +					*mIntersection = intersect;  				} +				U32 idx0 = tri->mIndex[0]; +				U32 idx1 = tri->mIndex[1]; +				U32 idx2 = tri->mIndex[2];  				if (mTexCoord != NULL)  				{  					LLVector2* tc = (LLVector2*) mFace->mTexCoords; -					*mTexCoord = ((1.f - a - b)  * tc[tri->mIndex[0]] + -						a              * tc[tri->mIndex[1]] + -						b              * tc[tri->mIndex[2]]); +					*mTexCoord = ((1.f - a - b)  * tc[idx0] + +						a              * tc[idx1] + +						b              * tc[idx2]);  				}  				if (mNormal != NULL)  				{ -					LLVector4* norm = (LLVector4*) mFace->mNormals; - -					*mNormal    = ((1.f - a - b)  * LLVector3(norm[tri->mIndex[0]]) +  -						a              * LLVector3(norm[tri->mIndex[1]]) + -						b              * LLVector3(norm[tri->mIndex[2]])); +					LLVector4a* norm = mFace->mNormals; +								 +					LLVector4a n1,n2,n3; +					n1 = norm[idx0]; +					n1.mul(1.f-a-b); +								 +					n2 = norm[idx1]; +					n2.mul(a); +								 +					n3 = norm[idx2]; +					n3.mul(b); + +					n1.add(n2); +					n1.add(n3); +								 +					*mNormal		= n1;   				} -				if (mBinormal != NULL) +				if (mTangent != NULL)  				{ -					LLVector4* binormal = (LLVector4*) mFace->mBinormals; -					*mBinormal = ((1.f - a - b)  * LLVector3(binormal[tri->mIndex[0]]) +  -							a              * LLVector3(binormal[tri->mIndex[1]]) + -							b              * LLVector3(binormal[tri->mIndex[2]])); +					LLVector4a* tangents = mFace->mTangents; +								 +					LLVector4a t1,t2,t3; +					t1 = tangents[idx0]; +					t1.mul(1.f-a-b); +								 +					t2 = tangents[idx1]; +					t2.mul(a); +								 +					t3 = tangents[idx2]; +					t3.mul(b); + +					t1.add(t2); +					t1.add(t3); +								 +					*mTangent = t1;   				}  			}  		} diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 9ae34a0c4e..80d6ced36d 100755 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -137,16 +137,16 @@ public:  	LLVector4a mStart;  	LLVector4a mDir;  	LLVector4a mEnd; -	LLVector3* mIntersection; +	LLVector4a* mIntersection;  	LLVector2* mTexCoord; -	LLVector3* mNormal; -	LLVector3* mBinormal; +	LLVector4a* mNormal; +	LLVector4a* mTangent;  	F32* mClosestT;  	bool mHitFace;  	LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,   								   const LLVolumeFace* face, F32* closest_t, -								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal); +								   LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);  	void traverse(const LLOctreeNode<LLVolumeTriangle>* node); diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 37b9c0e0e0..fea4ee2819 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -977,7 +977,7 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedAttribs.push_back("texcoord3");  	mReservedAttribs.push_back("diffuse_color");  	mReservedAttribs.push_back("emissive"); -	mReservedAttribs.push_back("binormal"); +	mReservedAttribs.push_back("tangent");  	mReservedAttribs.push_back("weight");  	mReservedAttribs.push_back("weight4");  	mReservedAttribs.push_back("clothing"); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 08f2d30aa4..01541026b1 100755 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -342,7 +342,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =  	sizeof(LLVector2), // TYPE_TEXCOORD3,  	sizeof(LLColor4U), // TYPE_COLOR,  	sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently -	sizeof(LLVector4), // TYPE_BINORMAL, +	sizeof(LLVector4), // TYPE_TANGENT,  	sizeof(F32),	   // TYPE_WEIGHT,  	sizeof(LLVector4), // TYPE_WEIGHT4,  	sizeof(LLVector4), // TYPE_CLOTHWEIGHT, @@ -359,7 +359,7 @@ static std::string vb_type_name[] =  	"TYPE_TEXCOORD3",  	"TYPE_COLOR",  	"TYPE_EMISSIVE", -	"TYPE_BINORMAL", +	"TYPE_TANGENT",  	"TYPE_WEIGHT",  	"TYPE_WEIGHT4",  	"TYPE_CLOTHWEIGHT", @@ -542,16 +542,16 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  				}  			} -			if (sLastMask & MAP_BINORMAL) +			if (sLastMask & MAP_TANGENT)  			{ -				if (!(data_mask & MAP_BINORMAL)) +				if (!(data_mask & MAP_TANGENT))  				{  					glClientActiveTextureARB(GL_TEXTURE2_ARB);  					glDisableClientState(GL_TEXTURE_COORD_ARRAY);  					glClientActiveTextureARB(GL_TEXTURE0_ARB);  				}  			} -			else if (data_mask & MAP_BINORMAL) +			else if (data_mask & MAP_TANGENT)  			{  				glClientActiveTextureARB(GL_TEXTURE2_ARB);  				glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1354,7 +1354,7 @@ void LLVertexBuffer::setupVertexArray()  		2, //TYPE_TEXCOORD3,  		4, //TYPE_COLOR,  		4, //TYPE_EMISSIVE, -		3, //TYPE_BINORMAL, +		4, //TYPE_TANGENT,  		1, //TYPE_WEIGHT,  		4, //TYPE_WEIGHT4,  		4, //TYPE_CLOTHWEIGHT, @@ -1371,7 +1371,7 @@ void LLVertexBuffer::setupVertexArray()  		GL_FLOAT, //TYPE_TEXCOORD3,  		GL_UNSIGNED_BYTE, //TYPE_COLOR,  		GL_UNSIGNED_BYTE, //TYPE_EMISSIVE, -		GL_FLOAT,   //TYPE_BINORMAL, +		GL_FLOAT,   //TYPE_TANGENT,  		GL_FLOAT, //TYPE_WEIGHT,  		GL_FLOAT, //TYPE_WEIGHT4,  		GL_FLOAT, //TYPE_CLOTHWEIGHT, @@ -1388,7 +1388,7 @@ void LLVertexBuffer::setupVertexArray()  		false, //TYPE_TEXCOORD3,  		false, //TYPE_COLOR,  		false, //TYPE_EMISSIVE, -		false, //TYPE_BINORMAL, +		false, //TYPE_TANGENT,  		false, //TYPE_WEIGHT,  		false, //TYPE_WEIGHT4,  		false, //TYPE_CLOTHWEIGHT, @@ -1405,7 +1405,7 @@ void LLVertexBuffer::setupVertexArray()  		GL_FALSE, //TYPE_TEXCOORD3,  		GL_TRUE, //TYPE_COLOR,  		GL_TRUE, //TYPE_EMISSIVE, -		GL_FALSE,   //TYPE_BINORMAL, +		GL_FALSE,   //TYPE_TANGENT,  		GL_FALSE, //TYPE_WEIGHT,  		GL_FALSE, //TYPE_WEIGHT4,  		GL_FALSE, //TYPE_CLOTHWEIGHT, @@ -2078,9 +2078,13 @@ bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index,  {  	return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range); +	return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range); +} +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range) +{ +	return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);  }  bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)  { @@ -2390,11 +2394,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  			void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);  			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{ -			S32 loc = TYPE_BINORMAL; -			void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]); -			glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); +			S32 loc = TYPE_TANGENT; +			void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); +			glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);  		}  		if (data_mask & MAP_TEXCOORD0)  		{ @@ -2472,10 +2476,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{  			glClientActiveTextureARB(GL_TEXTURE2_ARB); -			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); +			glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		}  		if (data_mask & MAP_TEXCOORD0) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 1be9b79e84..04806c1d8c 100755 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -174,7 +174,7 @@ public:  		TYPE_TEXCOORD3,  		TYPE_COLOR,  		TYPE_EMISSIVE, -		TYPE_BINORMAL, +		TYPE_TANGENT,  		TYPE_WEIGHT,  		TYPE_WEIGHT4,  		TYPE_CLOTHWEIGHT, @@ -192,7 +192,7 @@ public:  		MAP_COLOR = (1<<TYPE_COLOR),  		MAP_EMISSIVE = (1<<TYPE_EMISSIVE),  		// These use VertexAttribPointer and should possibly be made generic -		MAP_BINORMAL = (1<<TYPE_BINORMAL), +		MAP_TANGENT = (1<<TYPE_TANGENT),  		MAP_WEIGHT = (1<<TYPE_WEIGHT),  		MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),  		MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), @@ -252,7 +252,8 @@ public:  	bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); -	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl index 8ba75010a2..10144f3e16 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -30,7 +30,7 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent;  VARYING vec3 vary_mat0;  VARYING vec3 vary_mat1; @@ -52,8 +52,8 @@ void main()  	vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); -	vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz); -	vec3 t = cross(b, n); +	vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); +	vec3 b = cross(n, t) * tangent.w;  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index c8d38bb8f7..9f9749394e 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -31,7 +31,7 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent;  VARYING vec3 vary_mat0;  VARYING vec3 vary_mat1; @@ -46,8 +46,8 @@ void main()  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	vec3 n = normalize(normal_matrix * normal); -	vec3 b = normalize(normal_matrix * binormal); -	vec3 t = cross(b, n); +	vec3 t = normalize(normal_matrix * tangent.xyz); +	vec3 b = cross(n, t) * tangent.w;  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 17aa0e32a7..df8e7a6c0b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -495,7 +495,7 @@ void main()  	//final_color.rgb *= 1 - spec.a * env_intensity;  	//final_specular.rgb *= specular_color.rgb; -	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), spec.a * env_intensity, 0.0); +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);  	final_specular.a = specular_color.a * norm.a;  #else  	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index 0638dcfa55..b25032866b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -56,7 +56,7 @@ ATTRIBUTE vec2 texcoord0;  #if HAS_NORMAL_MAP -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent;  ATTRIBUTE vec2 texcoord1;  VARYING vec3 vary_mat0; @@ -110,8 +110,8 @@ void main()  #if HAS_SKIN  	vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);  #if HAS_NORMAL_MAP -	vec3 b = normalize((mat*vec4(binormal.xyz+position.xyz,1.0)).xyz-pos.xyz); -	vec3 t = cross(b, n); +	vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); +	vec3 b = cross(n, t)*tangent.w;  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y); @@ -122,8 +122,9 @@ vary_normal  = n;  #else //HAS_SKIN  	vec3 n = normalize(normal_matrix * normal);  #if HAS_NORMAL_MAP -	vec3 b = normalize(normal_matrix * binormal); -	vec3 t = cross(b, n); +	vec3 t = normalize(normal_matrix * tangent.xyz); +	vec3 b = cross(n,t)*tangent.w; +	//vec3 t = cross(b,n) * binormal.w;  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl index 44f1aa34a0..449d8d8b4e 100755 --- a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl +++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl @@ -25,12 +25,12 @@  uniform mat3 normal_matrix; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent; -VARYING vec4 binormal_out; +VARYING vec4 tangent_out;  void main()  { -	binormal_out = vec4(normal_matrix * binormal, 0.0); +	tangent_out = vec4(normal_matrix * tangent.xyz), tangent.w);  } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 5ed8bbca50..c832e1401d 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -239,7 +239,7 @@ void LLDrawPoolAlpha::render(S32 pass)  	if (mVertexShaderLevel > 0)  	{ -		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); +		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);  	}  	else  	{ diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index bb9126c162..7d0368a945 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -207,7 +207,7 @@ public:  		RIGGED_NORMMAP_VMASK =  						LLVertexBuffer::MAP_VERTEX |   						LLVertexBuffer::MAP_NORMAL |  -						LLVertexBuffer::MAP_BINORMAL |  +						LLVertexBuffer::MAP_TANGENT |   						LLVertexBuffer::MAP_TEXCOORD0 |  						LLVertexBuffer::MAP_TEXCOORD1 |  						LLVertexBuffer::MAP_COLOR | @@ -218,7 +218,7 @@ public:  		RIGGED_NORMSPEC_VMASK =  						LLVertexBuffer::MAP_VERTEX |   						LLVertexBuffer::MAP_NORMAL |  -						LLVertexBuffer::MAP_BINORMAL |  +						LLVertexBuffer::MAP_TANGENT |   						LLVertexBuffer::MAP_TEXCOORD0 |  						LLVertexBuffer::MAP_TEXCOORD1 |  						LLVertexBuffer::MAP_TEXCOORD2 | @@ -247,7 +247,7 @@ public:  		RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX |   							 LLVertexBuffer::MAP_NORMAL |   							 LLVertexBuffer::MAP_TEXCOORD0 | -							 LLVertexBuffer::MAP_BINORMAL | +							 LLVertexBuffer::MAP_TANGENT |  							 LLVertexBuffer::MAP_COLOR |  							 LLVertexBuffer::MAP_WEIGHT4,  		RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |  diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 29076de54b..7152a34094 100755 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -856,7 +856,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)  	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);  	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); -	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; +	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;  	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	  	{ diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h index cfbd13f335..eae1aba87c 100644 --- a/indra/newview/lldrawpoolmaterials.h +++ b/indra/newview/lldrawpoolmaterials.h @@ -52,7 +52,7 @@ public:  		LLVertexBuffer::MAP_TEXCOORD1 |  		LLVertexBuffer::MAP_TEXCOORD2 |  		LLVertexBuffer::MAP_COLOR | -		LLVertexBuffer::MAP_BINORMAL +		LLVertexBuffer::MAP_TANGENT  	};  	/*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 63919630fc..46d6a1a97f 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -106,41 +106,6 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal,  	tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f);  } -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; -	 -	tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f; -	if (vd.mNormal.mV[1] > 0) -	{ -		tc.mV[1] = 1.0f-tc.mV[1]; -	}*/ -} - -void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec) -{	//BROKEN -	/*LLVector3 binormal; -	float d = vd.mNormal * LLVector3(1,0,0); -	if (d >= 0.5f || d <= -0.5f) -	{ -		binormal = LLVector3(0,1,0); -	} -	else{ -		binormal = LLVector3(1,0,0); -	} -	LLVector3 tangent = binormal % vd.mNormal; - -	tc.mV[1] = -((tangent*vec)*2 - 0.5f); - -	tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f; - -	if (vd.mNormal.mV[1] < 0) -	{ -		tc.mV[0] = 1.0f-tc.mV[0]; -	}*/ -} -  ////////////////////  //  // LLFace implementation @@ -937,7 +902,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  // integrated with getGeometryVolume() for its texture coordinate  // generation - but i'll leave that to someone more familiar  // with the implications. -LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal) +LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal)  {  	LLVector2 tc = surface_coord; @@ -957,7 +922,9 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,  		LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);  		LLVector4a volume_position; -		volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV); +		LLVector3 v_position(position.getF32ptr()); + +		volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV);  		if (!mDrawablep->getVOVolume()->isVolumeGlobal())  		{ @@ -967,23 +934,14 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,  		}  		LLVector4a volume_normal; -		volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV); +		LLVector3 v_normal(normal.getF32ptr()); +		volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV);  		volume_normal.normalize3fast(); -		switch (texgen) +		if (texgen == LLTextureEntry::TEX_GEN_PLANAR)  		{ -		case LLTextureEntry::TEX_GEN_PLANAR:  			planarProjection(tc, volume_normal, center, volume_position); -			break; -		case LLTextureEntry::TEX_GEN_SPHERICAL: -			sphericalProjection(tc, volume_normal, center, volume_position); -			break; -		case LLTextureEntry::TEX_GEN_CYLINDRICAL: -			cylindricalProjection(tc, volume_normal, center, volume_position); -			break; -		default: -			break; -		}		 +		}  	}  	if (mTextureMatrix)	// if we have a texture matrix, use it @@ -1010,7 +968,12 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po  	const LLMatrix4& vol_mat = getWorldMatrix();  	const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);  	const LLVector4a& normal4a = vf.mNormals[0]; -	const LLVector4a& binormal4a = vf.mBinormals[0]; +	const LLVector4a& tangent = vf.mTangents[0]; + +	LLVector4a binormal4a; +	binormal4a.setCross3(normal4a, tangent); +	binormal4a.mul(tangent.getF32ptr()[3]); +  	LLVector2 projected_binormal;  	planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);  	projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform() @@ -1138,7 +1101,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  {  	LLFastTimer t(FTM_FACE_GEOM_VOLUME);  	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | -				LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL; +				LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;  	if (vf.mWeights)  	{ @@ -1151,11 +1114,11 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  	buff->allocateBuffer(vf.mNumVertices, 0, true);  	LLStrider<LLVector4a> f_vert; -	LLStrider<LLVector3> f_binorm; +	LLStrider<LLVector4a> f_tangent;  	LLStrider<LLVector3> f_norm;  	LLStrider<LLVector2> f_tc; -	buff->getBinormalStrider(f_binorm); +	buff->getTangentStrider(f_tangent);  	buff->getVertexStrider(f_vert);  	buff->getNormalStrider(f_norm);  	buff->getTexCoord0Strider(f_tc); @@ -1163,7 +1126,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  	for (U32 i = 0; i < vf.mNumVertices; ++i)  	{  		*f_vert++ = vf.mPositions[i]; -		(*f_binorm++).set(vf.mBinormals[i].getF32ptr()); +		*f_tangent++ = vf.mTangents[i];  		*f_tc++ = vf.mTexCoords[i];  		(*f_norm++).set(vf.mNormals[i].getF32ptr());  	} @@ -1205,7 +1168,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights"); -static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TANGENT("Binormal");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail");  static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos"); @@ -1271,7 +1234,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	LLStrider<LLVector2> tex_coords2;  	LLStrider<LLVector3> norm;  	LLStrider<LLColor4U> colors; -	LLStrider<LLVector3> binorm; +	LLStrider<LLVector3> tangent;  	LLStrider<U16> indicesp;  	LLStrider<LLVector4> wght; @@ -1293,7 +1256,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);  	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_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);  	bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);  	const LLTextureEntry *tep = mVObjp->getTE(f); @@ -1441,7 +1404,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)  		{ -			mVObjp->getVolume()->genBinormals(f); +			mVObjp->getVolume()->genTangents(f);  			LLFace::cacheFaceInVRAM(vf);  			buff = (LLVertexBuffer*) vf.mVertexBuffer.get();  		}		 @@ -1526,15 +1489,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			glEndTransformFeedback();  		} -		if (rebuild_binormal) +		if (rebuild_tangent)  		{ -			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); -			gTransformBinormalProgram.bind(); +			LLFastTimer t(FTM_FACE_GEOM_TANGENT); +			gTransformTangentProgram.bind(); -			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount); +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);  			glBeginTransformFeedback(GL_POINTS); -			buff->setBuffer(LLVertexBuffer::MAP_BINORMAL); +			buff->setBuffer(LLVertexBuffer::MAP_TANGENT);  			push_for_transform(buff, vf.mNumVertices, mGeomCount);  			glEndTransformFeedback();  		} @@ -1596,7 +1559,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			if (bump_code)  			{ -				mVObjp->getVolume()->genBinormals(f); +				mVObjp->getVolume()->genTangents(f);  				F32 offset_multiple;   				switch( bump_code )  				{ @@ -1645,7 +1608,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			U8 texgen = getTextureEntry()->getTexGen();  			if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)  			{ //planar texgen needs binormals -				mVObjp->getVolume()->genBinormals(f); +				mVObjp->getVolume()->genTangents(f);  			}  			U8 tex_mode = 0; @@ -1887,20 +1850,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							vec.mul(scalea); -							switch (texgen) +							if (texgen == LLTextureEntry::TEX_GEN_PLANAR)  							{ -								case LLTextureEntry::TEX_GEN_PLANAR: -									planarProjection(tc, norm, center, vec); -									break; -								case LLTextureEntry::TEX_GEN_SPHERICAL: -									sphericalProjection(tc, norm, center, vec); -									break; -								case LLTextureEntry::TEX_GEN_CYLINDRICAL: -									cylindricalProjection(tc, norm, center, vec); -									break; -								default: -									break; -							}		 +								planarProjection(tc, norm, center, vec); +							}  						}  						if (tex_mode && mTextureMatrix) @@ -1934,11 +1887,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					for (S32 i = 0; i < num_vertices; i++)  					{ -						LLVector4a tangent; -						tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); +						LLVector4a tangent = vf.mTangents[i]; +						LLVector4a binorm; +						binorm.setCross3(vf.mNormals[i], tangent); +						binorm.mul(tangent.getF32ptr()[3]); +						  						LLMatrix4a tangent_to_object; -						tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); +						tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);  						LLVector4a t;  						tangent_to_object.rotate(binormal_dir, t);  						LLVector4a binormal; @@ -2056,21 +2012,28 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			}  		} -		if (rebuild_binormal) +		if (rebuild_tangent)  		{ -			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); -			mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); -			F32* binormals = (F32*) binorm.get(); +			LLFastTimer t(FTM_FACE_GEOM_TANGENT); +			mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); +			F32* tangents = (F32*) tangent.get(); -			mVObjp->getVolume()->genBinormals(f); +			mVObjp->getVolume()->genTangents(f); +			LLVector4Logical mask; +			mask.clear(); +			mask.setElement<3>(); +  			for (S32 i = 0; i < num_vertices; i++)  			{ -				LLVector4a binormal; -				mat_normal.rotate(vf.mBinormals[i], binormal); -				binormal.normalize3fast(); -				binormal.store4a(binormals); -				binormals += 4; +				LLVector4a tangent_out; +				mat_normal.rotate(vf.mTangents[i], tangent_out); +				tangent_out.normalize3fast(); +				 +				tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out); +				tangent_out.store4a(tangents); +				 +				tangents += 4;  			}  			if (map_range) diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 453d2c23d4..0687544d53 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -118,7 +118,7 @@ public:  	LLXformMatrix*	getXform()			const	{ return mXform; }  	BOOL			hasGeometry()		const	{ return mGeomCount > 0; }  	LLVector3		getPositionAgent()	const; -	LLVector2       surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal); +	LLVector2       surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);  	void 			getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;  	bool			calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,  										LLVector2* st_scale, F32* st_rot) const; diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 7e1025c41b..825c2b31be 100755 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -202,7 +202,7 @@ void LLHUDIcon::render()  	renderIcon(FALSE);  } -BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection) +BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)  {  	if (mHidden)  		return FALSE; @@ -275,23 +275,18 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  	LLVector4a upper_right;  	upper_right.setAdd(lower_right, y_scalea); -	LLVector4a enda; -	enda.load3(end.mV); -	LLVector4a starta; -	starta.load3(start.mV);  	LLVector4a dir; -	dir.setSub(enda, starta); +	dir.setSub(end, start);  	F32 a,b,t; -	if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, a,b,t) || -		LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, a,b,t)) +	if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, a,b,t) || +		LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, a,b,t))  	{  		if (intersection)  		{  			dir.mul(t); -			starta.add(dir); -			*intersection = LLVector3(starta.getF32ptr()); +			intersection->setAdd(start, dir);  		}  		return TRUE;  	} @@ -331,12 +326,12 @@ LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)  }  //static -LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection) +LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)  {  	icon_instance_t::iterator icon_it; -	LLVector3 local_end = end; -	LLVector3 position; +	LLVector4a local_end = end; +	LLVector4a position;  	LLHUDIcon* ret = NULL;  	for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it) diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 644daa0299..557252ab0b 100755 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -62,7 +62,7 @@ public:  	static S32 generatePickIDs(S32 start_id, S32 step_size);  	static LLHUDIcon* handlePick(S32 pick_id); -	static LLHUDIcon* lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection); +	static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);  	static void updateAll();  	static void cleanupDeadIcons(); @@ -73,7 +73,7 @@ public:  	BOOL getHidden() const { return mHidden; }  	void setHidden( BOOL hide ) { mHidden = hide; } -	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection); +	BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);  protected:  	LLHUDIcon(const U8 type); diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 3336097955..c3b49f739a 100755 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -116,7 +116,7 @@ LLHUDNameTag::~LLHUDNameTag()  } -BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render) +BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render)  {  	if (!mVisible || mHidden)  	{ @@ -199,15 +199,23 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&  		bg_pos + height_vec,  	}; -	LLVector3 dir = end-start; +	LLVector4a dir; +	dir.setSub(end,start);  	F32 a, b, t; -	if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || -		LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) +	LLVector4a v0,v1,v2,v3; +	v0.load3(v[0].mV); +	v1.load3(v[1].mV); +	v2.load3(v[2].mV); +	v3.load3(v[3].mV); + +	if (LLTriangleRayIntersect(v0, v1, v2, start, dir, a, b, t) || +		LLTriangleRayIntersect(v2, v3, v0, start, dir, a, b, t) )  	{  		if (t <= 1.f)  		{ -			intersection = start + dir*t; +			dir.mul(t); +			intersection.setAdd(start, dir);  			return TRUE;  		}  	} diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 72647d5b26..38a4f18415 100755 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -124,7 +124,7 @@ public:  	void setHidden( BOOL hide ) { mHidden = hide; }  	void shift(const LLVector3& offset); -	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE); +	BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render = FALSE);  	static void shiftAll(const LLVector3& offset);  	static void addPickable(std::set<LLViewerObject*> &pick_list); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 252f129133..78401020a6 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3039,9 +3039,9 @@ void renderNormals(LLDrawable* drawablep)  				gGL.vertex3fv(face.mPositions[j].getF32ptr());  				gGL.vertex3fv(p.getF32ptr()); -				if (face.mBinormals) +				if (face.mTangents)  				{ -					n.setMul(face.mBinormals[j], scale); +					n.setMul(face.mTangents[j], scale);  					p.setAdd(face.mPositions[j], n);  					gGL.diffuseColor4f(0,1,1,1); @@ -3888,11 +3888,17 @@ void renderRaycast(LLDrawable* drawablep)  					gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);					  					gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); -					LLVector3 start, end; +					LLVector4a start, end;  					if (transform)  					{ -						start = vobj->agentPositionToVolume(gDebugRaycastStart); -						end = vobj->agentPositionToVolume(gDebugRaycastEnd); +						LLVector3 v_start(gDebugRaycastStart.getF32ptr()); +						LLVector3 v_end(gDebugRaycastEnd.getF32ptr()); + +						v_start = vobj->agentPositionToVolume(v_start); +						v_end = vobj->agentPositionToVolume(v_end); + +						start.load3(v_start.mV); +						end.load3(v_end.mV);  					}  					else  					{ @@ -3900,11 +3906,8 @@ void renderRaycast(LLDrawable* drawablep)  						end = gDebugRaycastEnd;  					} -					LLVector4a starta, enda; -					starta.load3(start.mV); -					enda.load3(end.mV);  					LLVector4a dir; -					dir.setSub(enda, starta); +					dir.setSub(end, start);  					gGL.flush();  					glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);				 @@ -3927,7 +3930,7 @@ void renderRaycast(LLDrawable* drawablep)  							((LLVolumeFace*) &face)->createOctree();   						} -						LLRenderOctreeRaycast render(starta, dir, &t); +						LLRenderOctreeRaycast render(start, dir, &t);  						render.traverse(face.mOctree);  					} @@ -3952,10 +3955,18 @@ void renderRaycast(LLDrawable* drawablep)  			// draw intersection point  			gGL.pushMatrix();  			gGL.loadMatrix(gGLModelView); -			LLVector3 translate = gDebugRaycastIntersection; +			LLVector3 translate(gDebugRaycastIntersection.getF32ptr());  			gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);  			LLCoordFrame orient; -			orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal); +			LLVector4a debug_binormal; +			 +			debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent); +			debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]); + +			LLVector3 normal(gDebugRaycastNormal.getF32ptr()); +			LLVector3 binormal(debug_binormal.getF32ptr()); +						 +			orient.lookDir(normal, binormal);  			LLMatrix4 rotation;  			orient.getRotMatrixToParent(rotation);  			gGL.multMatrix((float*)rotation.mMatrix); @@ -4457,28 +4468,30 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)  	return TRUE;  } +LL_ALIGN_PREFIX(16)  class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler  {  public: -	LLVector3 mStart; -	LLVector3 mEnd; +	LL_ALIGN_16(LLVector4a mStart); +	LL_ALIGN_16(LLVector4a mEnd); +  	S32       *mFaceHit; -	LLVector3 *mIntersection; +	LLVector4a *mIntersection;  	LLVector2 *mTexCoord; -	LLVector3 *mNormal; -	LLVector3 *mBinormal; +	LLVector4a *mNormal; +	LLVector4a *mTangent;  	LLDrawable* mHit;  	BOOL mPickTransparent; -	LLOctreeIntersect(LLVector3 start, LLVector3 end, BOOL pick_transparent, -					  S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal) +	LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, +					  S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  		: mStart(start),  		  mEnd(end),  		  mFaceHit(face_hit),  		  mIntersection(intersection),  		  mTexCoord(tex_coord),  		  mNormal(normal), -		  mBinormal(binormal), +		  mTangent(tangent),  		  mHit(NULL),  		  mPickTransparent(pick_transparent)  	{ @@ -4509,23 +4522,22 @@ public:  			size = group->mBounds[1];  			center = group->mBounds[0]; -			LLVector3 local_start = mStart; -			LLVector3 local_end   = mEnd; +			LLVector4a local_start = mStart; +			LLVector4a local_end   = mEnd;  			if (group->mSpatialPartition->isBridge())  			{  				LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix();  				local_matrix.invert(); -				 -				local_start = mStart * local_matrix; -				local_end   = mEnd   * local_matrix; -			} -			LLVector4a start, end; -			start.load3(local_start.mV); -			end.load3(local_end.mV); +				LLMatrix4a local_matrix4a; +				local_matrix4a.loadu(local_matrix); -			if (LLLineSegmentBoxIntersect(start, end, center, size)) +				local_matrix4a.affineTransform(mStart, local_start); +				local_matrix4a.affineTransform(mEnd, local_end); +			} + +			if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))  			{  				check(child);  			} @@ -4556,14 +4568,14 @@ public:  			if (vobj)  			{ -				LLVector3 intersection; +				LLVector4a intersection;  				bool skip_check = false;  				if (vobj->isAvatar())  				{  					LLVOAvatar* avatar = (LLVOAvatar*) vobj;  					if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools))  					{ -						LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal); +						LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);  						if (hit)  						{  							mEnd = intersection; @@ -4579,7 +4591,7 @@ public:  					}  				} -				if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) +				if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))  				{  					mEnd = intersection;  // shorten ray so we only find CLOSER hits  					if (mIntersection) @@ -4594,19 +4606,19 @@ public:  		return false;  	} -}; +} LL_ALIGN_POSTFIX(16); -LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  													 BOOL pick_transparent,													  													 S32* face_hit,                   // return the face hit -													 LLVector3* intersection,         // return the intersection point +													 LLVector4a* intersection,         // return the intersection point  													 LLVector2* tex_coord,            // return the texture coordinates of the intersection point -													 LLVector3* normal,               // return the surface normal at the intersection point -													 LLVector3* bi_normal             // return the surface bi-normal at the intersection point +													 LLVector4a* normal,               // return the surface normal at the intersection point +													 LLVector4a* tangent			// return the surface tangent at the intersection point  	)  { -	LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal); +	LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);  	LLDrawable* drawable = intersect.check(mOctree);  	return drawable; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 8ccc3efd66..9732be90af 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -204,7 +204,7 @@ public:  	};  }; -LL_ALIGN_PREFIX(16) +LL_ALIGN_PREFIX(64)  class LLSpatialGroup : public LLOctreeListener<LLDrawable>  {  	friend class LLSpatialPartition; @@ -490,13 +490,13 @@ public:  	LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);  	BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp); -	LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									 BOOL pick_transparent,   									 S32* face_hit,                          // return the face hit -									 LLVector3* intersection = NULL,         // return the intersection point +									 LLVector4a* intersection = NULL,         // return the intersection point  									 LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -									 LLVector3* normal = NULL,               // return the surface normal at the intersection point -									 LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +									 LLVector4a* normal = NULL,               // return the surface normal at the intersection point +									 LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 4e233d479a..198b13ee06 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3821,19 +3821,19 @@ LLViewerObject* LLViewerObject::getRootEdit() const  } -BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  										  S32 face,  										  BOOL pick_transparent,  										  S32* face_hit, -										  LLVector3* intersection, +										  LLVector4a* intersection,  										  LLVector2* tex_coord, -										  LLVector3* normal, -										  LLVector3* bi_normal) +										  LLVector4a* normal, +										  LLVector4a* tangent)  {  	return false;  } -BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end) +BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end)  {  	if (mDrawable.isNull() || mDrawable->isDead())  	{ @@ -3850,11 +3850,7 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect  	size.setSub(ext[1], ext[0]);  	size.mul(0.5f); -	LLVector4a starta, enda; -	starta.load3(start.mV); -	enda.load3(end.mV); - -	return LLLineSegmentBoxIntersect(starta, enda, center, size); +	return LLLineSegmentBoxIntersect(start, end, center, size);  }  U8 LLViewerObject::getMediaType() const diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bcb74a8d1f..932846c211 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -258,17 +258,17 @@ public:  	//detect if given line segment (in agent space) intersects with this viewer object.  	//returns TRUE if intersection detected and returns information about intersection -	virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES  									  BOOL pick_transparent = FALSE,  									  S32* face_hit = NULL,                   // which face was hit -									  LLVector3* intersection = NULL,         // return the intersection point +									  LLVector4a* intersection = NULL,         // return the intersection point  									  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -									  LLVector3* normal = NULL,               // return the surface normal at the intersection point -									  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +									  LLVector4a* normal = NULL,               // return the surface normal at the intersection point +									  LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		); -	virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end); +	virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end);  	virtual const LLVector3d getPositionGlobal() const;  	virtual const LLVector3 &getPositionRegion() const; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5f08e8ca2e..636214290d 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -68,7 +68,7 @@ LLGLSLShader			gTransformPositionProgram;  LLGLSLShader			gTransformTexCoordProgram;  LLGLSLShader			gTransformNormalProgram;  LLGLSLShader			gTransformColorProgram; -LLGLSLShader			gTransformBinormalProgram; +LLGLSLShader			gTransformTangentProgram;  //utility shaders  LLGLSLShader	gOcclusionProgram; @@ -789,7 +789,7 @@ void LLViewerShaderMgr::unloadShaders()  	gTransformTexCoordProgram.unload();  	gTransformNormalProgram.unload();  	gTransformColorProgram.unload(); -	gTransformBinormalProgram.unload(); +	gTransformTangentProgram.unload();  	mVertexShaderLevel[SHADER_LIGHTING] = 0;  	mVertexShaderLevel[SHADER_OBJECT] = 0; @@ -3043,7 +3043,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  		gTransformTexCoordProgram.unload();  		gTransformNormalProgram.unload();  		gTransformColorProgram.unload(); -		gTransformBinormalProgram.unload(); +		gTransformTangentProgram.unload();  		return TRUE;  	} @@ -3106,16 +3106,16 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  	if (success)  	{ -		gTransformBinormalProgram.mName = "Binormal Transform Shader"; -		gTransformBinormalProgram.mShaderFiles.clear(); -		gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); -		gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; +		gTransformTangentProgram.mName = "Binormal Transform Shader"; +		gTransformTangentProgram.mShaderFiles.clear(); +		gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); +		gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];  		const char* varyings[] = { -			"binormal_out", +			"tangent_out",  		}; -		success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings); +		success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);  	} diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 702a92c69c..8c7de05062 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -217,7 +217,7 @@ extern LLGLSLShader			gTransformPositionProgram;  extern LLGLSLShader			gTransformTexCoordProgram;  extern LLGLSLShader			gTransformNormalProgram;  extern LLGLSLShader			gTransformColorProgram; -extern LLGLSLShader			gTransformBinormalProgram; +extern LLGLSLShader			gTransformTangentProgram; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index fe4d5b3e4d..65a906d3c0 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -229,13 +229,13 @@ LLFrameTimer	gAwayTriggerTimer;  BOOL			gShowOverlayTitle = FALSE;  LLViewerObject*  gDebugRaycastObject = NULL; -LLVector3       gDebugRaycastIntersection; -LLVector2       gDebugRaycastTexCoord; -LLVector3       gDebugRaycastNormal; -LLVector3       gDebugRaycastBinormal; -S32				gDebugRaycastFaceHit; -LLVector3		gDebugRaycastStart; -LLVector3		gDebugRaycastEnd; +LLVector4a       gDebugRaycastIntersection; +LLVector2        gDebugRaycastTexCoord; +LLVector4a       gDebugRaycastNormal; +LLVector4a       gDebugRaycastTangent; +S32				 gDebugRaycastFaceHit; +LLVector4a		 gDebugRaycastStart; +LLVector4a		 gDebugRaycastEnd;  // HUD display lines in lower right  BOOL				gDisplayWindInfo = FALSE; @@ -2841,7 +2841,7 @@ void LLViewerWindow::updateUI()  											  &gDebugRaycastIntersection,  											  &gDebugRaycastTexCoord,  											  &gDebugRaycastNormal, -											  &gDebugRaycastBinormal, +											  &gDebugRaycastTangent,  											  &gDebugRaycastStart,  											  &gDebugRaycastEnd);  	} @@ -3739,7 +3739,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_trans  }  LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, -										   LLVector3* intersection) +										   LLVector4a* intersection)  {  	S32 x = mouse_x;  	S32 y = mouse_y; @@ -3751,14 +3751,17 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep  	}  	// world coordinates of mouse +	// VECTORIZE THIS  	LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);  	LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();  	LLVector3 mouse_world_start = mouse_point_global;  	LLVector3 mouse_world_end   = mouse_point_global + mouse_direction_global * depth; -	return LLHUDIcon::lineSegmentIntersectAll(mouse_world_start, mouse_world_end, intersection); - +	LLVector4a start, end; +	start.load3(mouse_world_start.mV); +	end.load3(mouse_world_end.mV); +	return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection);  }  LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth, @@ -3766,12 +3769,12 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  												S32 this_face,  												BOOL pick_transparent,  												S32* face_hit, -												LLVector3 *intersection, +												LLVector4a *intersection,  												LLVector2 *uv, -												LLVector3 *normal, -												LLVector3 *binormal, -												LLVector3* start, -												LLVector3* end) +												LLVector4a *normal, +												LLVector4a *tangent, +												LLVector4a* start, +												LLVector4a* end)  {  	S32 x = mouse_x;  	S32 y = mouse_y; @@ -3806,17 +3809,27 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	if (!LLViewerJoystick::getInstance()->getOverrideCamera())  	{ //always set raycast intersection to mouse_world_end unless  		//flycam is on (for DoF effect) -		gDebugRaycastIntersection = mouse_world_end; +		gDebugRaycastIntersection.load3(mouse_world_end.mV);  	} +	LLVector4a mw_start; +	mw_start.load3(mouse_world_start.mV); +	LLVector4a mw_end; +	mw_end.load3(mouse_world_end.mV); + +	LLVector4a mh_start; +	mh_start.load3(mouse_hud_start.mV); +	LLVector4a mh_end; +	mh_end.load3(mouse_hud_end.mV); +  	if (start)  	{ -		*start = mouse_world_start; +		*start = mw_start;  	}  	if (end)  	{ -		*end = mouse_world_end; +		*end = mw_end;  	}  	LLViewerObject* found = NULL; @@ -3825,16 +3838,16 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	{  		if (this_object->isHUDAttachment()) // is a HUD object?  		{ -			if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent, -												  face_hit, intersection, uv, normal, binormal)) +			if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, +												  face_hit, intersection, uv, normal, tangent))  			{  				found = this_object;  			}  		}  		else // is a world object  		{ -			if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent, -												  face_hit, intersection, uv, normal, binormal)) +			if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, +												  face_hit, intersection, uv, normal, tangent))  			{  				found = this_object;  			} @@ -3842,20 +3855,20 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	}  	else // check ALL objects  	{ -		found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent, -													face_hit, intersection, uv, normal, binormal); +		found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent, +													face_hit, intersection, uv, normal, tangent);  		if (!found) // if not found in HUD, look in world:  		{ -			found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent, -														  face_hit, intersection, uv, normal, binormal); +			found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, +														  face_hit, intersection, uv, normal, tangent);  			if (found && !pick_transparent)  			{  				gDebugRaycastIntersection = *intersection;  			}  		}  	} - +		  	return found;  } @@ -5112,6 +5125,7 @@ LLPickInfo::LLPickInfo()  	  mXYCoords(-1, -1),  	  mIntersection(),  	  mNormal(), +	  mTangent(),  	  mBinormal(),  	  mHUDIcon(NULL),  	  mPickTransparent(FALSE) @@ -5133,6 +5147,7 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,  	  mSTCoords(-1.f, -1.f),  	  mXYCoords(-1, -1),  	  mNormal(), +	  mTangent(),  	  mBinormal(),  	  mHUDIcon(NULL),  	  mPickTransparent(pick_transparent) @@ -5143,19 +5158,26 @@ void LLPickInfo::fetchResults()  {  	S32 face_hit = -1; -	LLVector3 intersection, normal, binormal; +	LLVector4a intersection, normal; +	LLVector4a tangent; +  	LLVector2 uv;  	LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection); +	LLVector4a origin; +	origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);  	F32 icon_dist = 0.f;  	if (hit_icon)  	{ -		icon_dist = (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec(); +		LLVector4a delta; +		delta.setSub(intersection, origin); +		icon_dist = delta.getLength3().getF32();  	} +  	LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,  									NULL, -1, mPickTransparent, &face_hit, -									&intersection, &uv, &normal, &binormal); +									&intersection, &uv, &normal, &tangent);  	mPickPt = mMousePt; @@ -5165,9 +5187,13 @@ void LLPickInfo::fetchResults()  	LLViewerObject* objectp = hit_object; + +	LLVector4a delta; +	delta.setSub(origin, intersection); +  	if (hit_icon &&   		(!objectp ||  -		icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec())) +		icon_dist < delta.getLength3().getF32()))  	{  		// was this name referring to a hud icon?  		mHUDIcon = hit_icon; @@ -5204,11 +5230,16 @@ void LLPickInfo::fetchResults()  			{  				mPickType = PICK_OBJECT;  			} -			mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY); + +			LLVector3 v_intersection(intersection.getF32ptr()); + +			mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY);  			mObjectID = objectp->mID;  			mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; -			mPosGlobal = gAgent.getPosGlobalFromAgent(intersection); +			 + +			mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection);  			if (mWantSurfaceInfo)  			{ @@ -5252,7 +5283,16 @@ void LLPickInfo::getSurfaceInfo()  	mIntersection = LLVector3(0,0,0);  	mNormal       = LLVector3(0,0,0);  	mBinormal     = LLVector3(0,0,0); +	mTangent	  = LLVector4(0,0,0,0); +	LLVector4a tangent; +	LLVector4a intersection; +	LLVector4a normal; + +	tangent.clear(); +	normal.clear(); +	intersection.clear(); +  	LLViewerObject* objectp = getObject();  	if (objectp) @@ -5260,10 +5300,10 @@ void LLPickInfo::getSurfaceInfo()  		if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f,  										   objectp, -1, mPickTransparent,  										   &mObjectFace, -										   &mIntersection, +										   &intersection,  										   &mSTCoords, -										   &mNormal, -										   &mBinormal)) +										   &normal, +										   &tangent))  		{  			// if we succeeded with the intersect above, compute the texture coordinates: @@ -5272,10 +5312,26 @@ void LLPickInfo::getSurfaceInfo()  				LLFace* facep = objectp->mDrawable->getFace(mObjectFace);  				if (facep)  				{ -				mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); -			} +					mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal); +				}  			} +			mIntersection.set(intersection.getF32ptr()); +			mNormal.set(normal.getF32ptr()); +			mTangent.set(tangent.getF32ptr()); + +			//extrapoloate binormal from normal and tangent +			 +			LLVector4a binormal; +			binormal.setCross3(normal, tangent); +			binormal.mul(tangent.getF32ptr()[3]); + +			mBinormal.set(binormal.getF32ptr()); + +			mBinormal.normalize(); +			mNormal.normalize(); +			mTangent.normalize(); +  			// and XY coords:  			updateXYCoords(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index b33488fd78..89f6e3bc26 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -115,6 +115,7 @@ public:  	LLVector2       mSTCoords;  	LLCoordScreen	mXYCoords;  	LLVector3		mNormal; +	LLVector4		mTangent;  	LLVector3		mBinormal;  	BOOL			mPickTransparent;  	void		    getSurfaceInfo(); @@ -357,19 +358,19 @@ public:  	void			pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& pick_info), BOOL pick_transparent = FALSE);  	LLPickInfo		pickImmediate(S32 x, S32 y, BOOL pick_transparent);  	LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, -										   LLVector3* intersection); +										   LLVector4a* intersection);  	LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,  									LLViewerObject *this_object = NULL,  									S32 this_face = -1,  									BOOL pick_transparent = FALSE,  									S32* face_hit = NULL, -									LLVector3 *intersection = NULL, +									LLVector4a *intersection = NULL,  									LLVector2 *uv = NULL, -									LLVector3 *normal = NULL, -									LLVector3 *binormal = NULL, -									LLVector3* start = NULL, -									LLVector3* end = NULL); +									LLVector4a *normal = NULL, +									LLVector4a *tangent = NULL, +									LLVector4a* start = NULL, +									LLVector4a* end = NULL);  	// Returns a pointer to the last object hit @@ -499,13 +500,13 @@ extern LLFrameTimer		gAwayTimer;				// tracks time before setting the avatar awa  extern LLFrameTimer		gAwayTriggerTimer;		// how long the avatar has been away  extern LLViewerObject*  gDebugRaycastObject; -extern LLVector3        gDebugRaycastIntersection; +extern LLVector4a       gDebugRaycastIntersection;  extern LLVector2        gDebugRaycastTexCoord; -extern LLVector3        gDebugRaycastNormal; -extern LLVector3        gDebugRaycastBinormal; +extern LLVector4a       gDebugRaycastNormal; +extern LLVector4a       gDebugRaycastTangent;  extern S32				gDebugRaycastFaceHit; -extern LLVector3		gDebugRaycastStart; -extern LLVector3		gDebugRaycastEnd; +extern LLVector4a		gDebugRaycastStart; +extern LLVector4a		gDebugRaycastEnd;  extern BOOL			gDisplayCameraPos;  extern BOOL			gDisplayWindInfo; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 373a59ad6b..1a050800b4 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1388,19 +1388,20 @@ void LLVOAvatar::renderCollisionVolumes()  	if (mNameText.notNull())  	{ -		LLVector3 unused; -		mNameText->lineSegmentIntersect(LLVector3(0,0,0), LLVector3(0,0,1), unused, TRUE); +		LLVector4a unused; +	 +		mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);  	}  } -BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									  S32 face,  									  BOOL pick_transparent,  									  S32* face_hit, -									  LLVector3* intersection, +									  LLVector4a* intersection,  									  LLVector2* tex_coord, -									  LLVector3* normal, -									  LLVector3* bi_normal) +									  LLVector4a* normal, +									  LLVector4a* tangent)  {  	if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar)  	{ @@ -1417,8 +1418,8 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  			glh::matrix4f inverse = mat.inverse();  			glh::matrix4f norm_mat = inverse.transpose(); -			glh::vec3f p1(start.mV); -			glh::vec3f p2(end.mV); +			glh::vec3f p1(start.getF32ptr()); +			glh::vec3f p2(end.getF32ptr());  			inverse.mult_matrix_vec(p1);  			inverse.mult_matrix_vec(p2); @@ -1437,12 +1438,12 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				if (intersection)  				{ -					*intersection = LLVector3(res_pos.v); +					intersection->load3(res_pos.v);  				}  				if (normal)  				{ -					*normal = LLVector3(res_norm.v); +					normal->load3(res_norm.v);  				}  				return TRUE; @@ -1478,7 +1479,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e -	LLVector3 position; +	LLVector4a position;  	if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))  	{  		if (intersection) @@ -1492,14 +1493,14 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	return FALSE;  } -LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,  									  S32 face,  									  BOOL pick_transparent,  									  S32* face_hit, -									  LLVector3* intersection, +									  LLVector4a* intersection,  									  LLVector2* tex_coord, -									  LLVector3* normal, -									  LLVector3* bi_normal) +									  LLVector4a* normal, +									  LLVector4a* tangent)  {  	if (isSelf() && !gAgent.needsRenderAvatar())  	{ @@ -1510,8 +1511,8 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  	if (lineSegmentBoundingBox(start, end))  	{ -		LLVector3 local_end = end; -		LLVector3 local_intersection; +		LLVector4a local_end = end; +		LLVector4a local_intersection;  		for (attachment_map_t::iterator iter = mAttachmentPoints.begin();   			iter != mAttachmentPoints.end(); @@ -1525,7 +1526,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  			{  				LLViewerObject* attached_object = (*attachment_iter); -				if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal)) +				if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, tangent))  				{  					local_end = local_intersection;  					if (intersection) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index e7f249be69..b05eed344b 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -162,22 +162,22 @@ public:  	/*virtual*/ void   	 	 	updateRegion(LLViewerRegion *regionp);  	/*virtual*/ void   	 	 	updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);  	/*virtual*/ void   	 	 	getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); -	/*virtual*/ BOOL   	 	 	lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	/*virtual*/ BOOL   	 	 	lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES  												 BOOL pick_transparent = FALSE,  												 S32* face_hit = NULL,             // which face was hit -												 LLVector3* intersection = NULL,   // return the intersection point +												 LLVector4a* intersection = NULL,   // return the intersection point  												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point -												 LLVector3* normal = NULL,         // return the surface normal at the intersection point -												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point -	LLViewerObject*	lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +												 LLVector4a* normal = NULL,         // return the surface normal at the intersection point +												 LLVector4a* tangent = NULL);     // return the surface tangent at the intersection point +	LLViewerObject*	lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,  												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES  												 BOOL pick_transparent = FALSE,  												 S32* face_hit = NULL,             // which face was hit -												 LLVector3* intersection = NULL,   // return the intersection point +												 LLVector4a* intersection = NULL,   // return the intersection point  												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point -												 LLVector3* normal = NULL,         // return the surface normal at the intersection point -												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point +												 LLVector4a* normal = NULL,         // return the surface normal at the intersection point +												 LLVector4a* tangent = NULL);     // return the surface tangent at the intersection point  	//--------------------------------------------------------------------  	// LLCharacter interface and related diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 6a25b765cf..cab5c4bc1d 100755 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -764,8 +764,8 @@ void LLVOGrass::updateDrawable(BOOL force_damped)  }  // virtual  -BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  {  	BOOL ret = FALSE; @@ -776,7 +776,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  		return FALSE;  	} -	LLVector3 dir = end-start; +	LLVector4a dir; +	dir.setSub(end, start);  	mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); @@ -844,23 +845,31 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  		U32 idx0 = 0,idx1 = 0,idx2 = 0; -		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE)) +		LLVector4a v0a,v1a,v2a,v3a; + +		v0a.load3(v[0].mV); +		v1a.load3(v[1].mV); +		v2a.load3(v[2].mV); +		v3a.load3(v[3].mV); + +		 +		if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t))  		{  			hit = TRUE;  			idx0 = 0; idx1 = 1; idx2 = 2;  		} -		else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t))  		{  			hit = TRUE;  			idx0 = 1; idx1 = 3; idx2 = 2;  		} -		else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t))  		{  			normal1 = -normal1;  			hit = TRUE;  			idx0 = 2; idx1 = 1; idx2 = 0;  		} -		else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t))  		{  			normal1 = -normal1;  			hit = TRUE; @@ -883,7 +892,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  					closest_t = t;  					if (intersection != NULL)  					{ -						*intersection = start+dir*closest_t; +						dir.mul(closest_t); +						intersection->setAdd(start, dir);  					}  					if (tex_coord != NULL) @@ -893,7 +903,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  					if (normal != NULL)  					{ -						*normal    = normal1; +						normal->load3(normal1.mV);  					}  					ret = TRUE;  				} diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index b9835b8802..122806766d 100755 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -75,14 +75,14 @@ public:  	/*virtual*/ BOOL    isActive() const; // Whether this object needs to do an idleUpdate.  	/*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	static S32 sMaxGrassSpecies; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 65711d2339..6a7f26bdb5 100755 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -67,7 +67,7 @@ void LLVOPartGroup::restoreGL()  {  	//TODO: optimize out binormal mask here.  Specular and normal coords as well. -	sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB); +	sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB);  	U32 count = LL_MAX_PARTICLE_COUNT;  	sVB->allocateBuffer(count*4, count*6, true); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index de15f0ef43..9a5c5831ca 100755 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -97,10 +97,10 @@ public:  			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{  			glClientActiveTextureARB(GL_TEXTURE2_ARB); -			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); +			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		}  		if (data_mask & MAP_TEXCOORD0) @@ -936,8 +936,8 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,  	}  } -BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  { @@ -946,7 +946,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  		return FALSE;  	} -	LLVector3 delta = end-start; +	LLVector4a da; +	da.setSub(end, start); +	LLVector3 delta(da.getF32ptr());  	LLVector3 pdelta = delta;  	pdelta.mV[2] = 0; @@ -955,7 +957,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  	F32 tdelta = 1.f/plength; -	LLVector3 origin = start - mRegionp->getOriginAgent(); +	LLVector3 v_start(start.getF32ptr()); + +	LLVector3 origin = v_start - mRegionp->getOriginAgent();  	if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])  	{ @@ -1010,12 +1014,12 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  					{  						sample.mV[2] = mRegionp->getLandHeightRegion(sample);  					} -					*intersection = sample + mRegionp->getOriginAgent(); +					intersection->load3((sample + mRegionp->getOriginAgent()).mV);  				}  				if (normal)  				{ -					*normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample)); +					normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);  				}  				return TRUE; diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a15878368e..7b53219be8 100755 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -79,14 +79,14 @@ public:  	void dirtyPatch();  	void dirtyGeom(); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	BOOL			mDirtiedPatch; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index a1b36e3c8d..cd12cd9552 100755 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1112,8 +1112,8 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)  	mDrawable->setPositionGroup(pos);  } -BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  { @@ -1142,16 +1142,19 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end  	LLVector3 pos, norm; -	if (linesegment_tetrahedron(start, end, center, size, quat, pos, norm)) +	LLVector3 start3(start.getF32ptr()); +	LLVector3 end3(end.getF32ptr()); + +	if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm))  	{  		if (intersection)  		{ -			*intersection = pos; +			intersection->load3(pos.mV);  		}  		if (normal)  		{ -			*normal = norm; +			normal->load3(norm.mV);  		}  		return TRUE;  	} diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 2a7eb21238..2ecb0303a1 100755 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -106,14 +106,14 @@ public:  								 F32 branches,   								 F32 alpha);  -	 /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	 /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	static S32 sMaxTreeSpecies; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b107f43e4c..677d79d601 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1046,7 +1046,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  				{ //already cached  					break;  				} -				volume->genBinormals(i); +				volume->genTangents(i);  				LLFace::cacheFaceInVRAM(face);  			}  		} @@ -3612,8 +3612,8 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const  } -BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  {  	if (!mbCanSelect  @@ -3645,23 +3645,25 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	if (volume)  	{	 -		LLVector3 v_start, v_end, v_dir; -	 +		LLVector4a local_start = start; +		LLVector4a local_end = end; +		  		if (transform)  		{ -			v_start = agentPositionToVolume(start); -			v_end = agentPositionToVolume(end); -		} -		else -		{ -			v_start = start; -			v_end = end; -		} +			LLVector3 v_start(start.getF32ptr()); +			LLVector3 v_end(end.getF32ptr()); -		LLVector3 p; -		LLVector3 n; +			v_start = agentPositionToVolume(v_start); +			v_end = agentPositionToVolume(v_end); + +			local_start.load3(v_start.mV); +			local_end.load3(v_end.mV); +		} +				 +		LLVector4a p; +		LLVector4a n;  		LLVector2 tc; -		LLVector3 bn; +		LLVector4a tn;  		if (intersection != NULL)  		{ @@ -3678,9 +3680,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  			n = *normal;  		} -		if (bi_normal != NULL) +		if (tangent != NULL)  		{ -			bn = *bi_normal; +			tn = *tangent;  		}  		S32 face_hit = -1; @@ -3706,8 +3708,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				continue;  			} -			face_hit = volume->lineSegmentIntersect(v_start, v_end, i, -													&p, &tc, &n, &bn); +			face_hit = volume->lineSegmentIntersect(local_start, local_end, i, +													&p, &tc, &n, &tn);  			if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)  			{ @@ -3716,7 +3718,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				if (face &&  					(pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))  				{ -					v_end = p; +					local_end = p;  					if (face_hitp != NULL)  					{  						*face_hitp = face_hit; @@ -3726,7 +3728,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  					{  						if (transform)  						{ -							*intersection = volumePositionToAgent(p);  // must map back to agent space +							LLVector3 v_p(p.getF32ptr()); + +							intersection->load3(volumePositionToAgent(v_p).mV);  // must map back to agent space  						}  						else  						{ @@ -3738,27 +3742,37 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  					{  						if (transform)  						{ -							*normal = volumeDirectionToAgent(n); +							LLVector3 v_n(n.getF32ptr()); +							normal->load3(volumeDirectionToAgent(v_n).mV);  						}  						else  						{  							*normal = n;  						} -						(*normal).normVec(); +						(*normal).normalize3fast();  					} -					if (bi_normal != NULL) +					if (tangent != NULL)  					{  						if (transform)  						{ -							*bi_normal = volumeDirectionToAgent(bn); +							LLVector3 v_tn(tn.getF32ptr()); + +							LLVector4a trans_tangent; +							trans_tangent.load3(volumeDirectionToAgent(v_tn).mV); + +							LLVector4Logical mask; +							mask.clear(); +							mask.setElement<3>(); + +							tangent->setSelectWithMask(mask, tn, trans_tangent);  						}  						else  						{ -							*bi_normal = bn; +							*tangent = tn;  						} -						(*bi_normal).normVec(); +						(*tangent).normalize3fast();  					}  					if (tex_coord != NULL) @@ -4038,7 +4052,7 @@ static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)  {  	LLFastTimer t(FTM_REGISTER_FACE); -	if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_BINORMAL)) +	if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT))  	{  		LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;  	} @@ -4747,11 +4761,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  								if (mat->getNormalID().notNull())  								{  									if (mat->getSpecularID().notNull()) -									{ //has normal and specular maps (needs texcoord1, texcoord2, and binormal) +									{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)  										normspec_faces.push_back(facep);  									}  									else -									{ //has normal map (needs texcoord1 and binormal) +									{ //has normal map (needs texcoord1 and tangent)  										norm_faces.push_back(facep);  									}  								} @@ -4765,7 +4779,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  								}									  							}  							else if (te->getBumpmap()) -							{ //needs normal + binormal +							{ //needs normal + tangent  								bump_faces.push_back(facep);  							}  							else if (te->getShiny() || !te->getFullbright()) @@ -4781,7 +4795,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						else  						{  							if (te->getBumpmap() && LLPipeline::sRenderBump) -							{ //needs normal + binormal +							{ //needs normal + tangent  								bump_faces.push_back(facep);  							}  							else if ((te->getShiny() && LLPipeline::sRenderBump) || @@ -4822,7 +4836,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;  	U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; -	U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_BINORMAL; +	U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT;  	U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2;  	U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; @@ -4841,9 +4855,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	if (batch_textures)  	{ -		bump_mask = bump_mask | LLVertexBuffer::MAP_BINORMAL; +		bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT;  		simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; -		alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; +		alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2;  		fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;  	} diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 928ff7f66b..7503f8c5aa 100755 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -137,14 +137,14 @@ public:  	/*virtual*/ U32		getTriangleCount(S32* vcount = NULL) const;  	/*virtual*/ U32		getHighLODTriangleCount(); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  				LLVector3 agentPositionToVolume(const LLVector3& pos) const; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6dc89742ec..cbcf3165c4 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6886,20 +6886,20 @@ void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)  	sRenderHighlightTextureChannel = channel;  } -LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,  														BOOL pick_transparent,												  														S32* face_hit, -														LLVector3* intersection,         // return the intersection point +														LLVector4a* intersection,         // return the intersection point  														LLVector2* tex_coord,            // return the texture coordinates of the intersection point -														LLVector3* normal,               // return the surface normal at the intersection point -														LLVector3* bi_normal             // return the surface bi-normal at the intersection point +														LLVector4a* normal,               // return the surface normal at the intersection point +														LLVector4a* tangent             // return the surface tangent at the intersection point  	)  {  	LLDrawable* drawable = NULL; -	LLVector3 local_end = end; +	LLVector4a local_end = end; -	LLVector3 position; +	LLVector4a position;  	sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; @@ -6919,7 +6919,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  				LLSpatialPartition* part = region->getSpatialPartition(j);  				if (part && hasRenderType(part->mDrawableType))  				{ -					LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal); +					LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);  					if (hit)  					{  						drawable = hit; @@ -6934,8 +6934,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  	{  		//save hit info in case we need to restore  		//due to attachment override -		LLVector3 local_normal; -		LLVector3 local_binormal; +		LLVector4a local_normal; +		LLVector4a local_tangent;  		LLVector2 local_texcoord;  		S32 local_face_hit = -1; @@ -6947,9 +6947,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  		{  			local_texcoord = *tex_coord;  		} -		if (bi_normal) +		if (tangent)  		{ -			local_binormal = *bi_normal; +			local_tangent = *tangent;  		}  		if (normal)  		{ @@ -6968,12 +6968,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  			LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);  			if (part && hasRenderType(part->mDrawableType))  			{ -				LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal); +				LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);  				if (hit)  				{ +					LLVector4a delta; +					delta.setSub(position, local_end); +  					if (!drawable ||   						!drawable->getVObj()->isAttachment() || -						(position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST) +						delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)  					{ //avatar overrides if previously hit drawable is not an attachment or   					  //attachment is far enough away from detected intersection  						drawable = hit; @@ -6991,9 +6994,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  						{  							*tex_coord = local_texcoord;  						} -						if (bi_normal) +						if (tangent)  						{ -							*bi_normal = local_binormal; +							*tangent = local_tangent;  						}  						if (normal)  						{ @@ -7027,13 +7030,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  	return drawable ? drawable->getVObj().get() : NULL;  } -LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,  													  BOOL pick_transparent,													  													  S32* face_hit, -													  LLVector3* intersection,         // return the intersection point +													  LLVector4a* intersection,         // return the intersection point  													  LLVector2* tex_coord,            // return the texture coordinates of the intersection point -													  LLVector3* normal,               // return the surface normal at the intersection point -													  LLVector3* bi_normal             // return the surface bi-normal at the intersection point +													  LLVector4a* normal,               // return the surface normal at the intersection point +													  LLVector4a* tangent				// return the surface tangent at the intersection point  	)  {  	LLDrawable* drawable = NULL; @@ -7053,7 +7056,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co  		LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);  		if (part)  		{ -			LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal); +			LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);  			if (hit)  			{  				drawable = hit; @@ -7513,13 +7516,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  			{  				if (LLViewerJoystick::getInstance()->getOverrideCamera())  				{ //focus on point under cursor -					focus_point = gDebugRaycastIntersection; +					focus_point.set(gDebugRaycastIntersection.getF32ptr());  				}  				else if (gAgentCamera.cameraMouselook())  				{ //focus on point under mouselook crosshairs +					LLVector4a result; +					result.clear(); +  					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,  													NULL, -													&focus_point); +													&result); + +					focus_point.set(result.getF32ptr());  				}  				else  				{ diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a8362953b4..2c023a6f70 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -188,21 +188,21 @@ public:  	void		markMeshDirty(LLSpatialGroup* group);  	//get the object between start and end that's closest to start. -	LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +	LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,  												BOOL pick_transparent,  												S32* face_hit,                          // return the face hit -												LLVector3* intersection = NULL,         // return the intersection point +												LLVector4a* intersection = NULL,         // return the intersection point  												LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -												LLVector3* normal = NULL,               // return the surface normal at the intersection point -												LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point   +												LLVector4a* normal = NULL,               // return the surface normal at the intersection point +												LLVector4a* tangent = NULL             // return the surface tangent at the intersection point    		); -	LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +	LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,  											  BOOL pick_transparent,  											  S32* face_hit,                          // return the face hit -											  LLVector3* intersection = NULL,         // return the intersection point +											  LLVector4a* intersection = NULL,         // return the intersection point  											  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -											  LLVector3* normal = NULL,               // return the surface normal at the intersection point -											  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +											  LLVector4a* normal = NULL,               // return the surface normal at the intersection point +											  LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		);  	// Something about these textures has changed.  Dirty them. | 
