diff options
| author | Karl Steifvater <qarl@lindenlab.com> | 2008-07-23 21:20:19 +0000 | 
|---|---|---|
| committer | Karl Steifvater <qarl@lindenlab.com> | 2008-07-23 21:20:19 +0000 | 
| commit | 52562e2e664c70dcd476291820ac02b893e489b8 (patch) | |
| tree | 5137f49f194a6a28f290385c38f689d77656b2e0 | |
| parent | bc39ad916e8f23ffae12184eee675aa7c1be2ca9 (diff) | |
svn merge -r92720:92721 svn+ssh://svn.lindenlab.com/svn/linden/branches/uv-picking-merge
QAR-698 / DEV-9985 add touch "position" information to touch-events in LSL
72 files changed, 2001 insertions, 1334 deletions
| diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h index 17fa981c7c..21ca4189ff 100644 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -183,10 +183,11 @@ public:  	LLRectBase& setCenterAndSize(Type x, Type y, Type width, Type height)  	{ +		// width and height could be odd, so favor top, right with extra pixel  		mLeft = x - width/2; -		mTop = y + height/2; -		mRight = x + width/2;  		mBottom = y - height/2; +		mTop = mBottom + height; +		mRight = mLeft + width;  		return *this;  	} diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3b01140e3a..242b0809eb 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -104,46 +104,128 @@ BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLV  	}  }  -// intersect test between triangle pt1,pt2,pt3 and line from linept to linept+vect -//returns TRUE if intersecting and moves linept to the point of intersection -BOOL LLTriangleLineSegmentIntersect( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, LLVector3& linept, const LLVector3& vect) +BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size)  { -	LLVector3 V1 = pt2-pt1; -	LLVector3 V2 = pt3-pt2; +	float fAWdU[3]; +	LLVector3 dir; +	LLVector3 diff; + +	for (U32 i = 0; i < 3; i++) +	{ +		dir.mV[i] = 0.5f * (end.mV[i] - start.mV[i]); +		diff.mV[i] = (0.5f * (end.mV[i] + start.mV[i])) - center.mV[i]; +		fAWdU[i] = fabsf(dir.mV[i]); +		if(fabsf(diff.mV[i])>size.mV[i] + fAWdU[i]) return false; +	} + +	float f; +	f = dir.mV[1] * diff.mV[2] - dir.mV[2] * diff.mV[1];    if(fabsf(f)>size.mV[1]*fAWdU[2] + size.mV[2]*fAWdU[1])  return false; +	f = dir.mV[2] * diff.mV[0] - dir.mV[0] * diff.mV[2];    if(fabsf(f)>size.mV[0]*fAWdU[2] + size.mV[2]*fAWdU[0])  return false; +	f = dir.mV[0] * diff.mV[1] - dir.mV[1] * diff.mV[0];    if(fabsf(f)>size.mV[0]*fAWdU[1] + size.mV[1]*fAWdU[0])  return false; -	LLVector3 norm = V1 % V2; +	return true; +} + + +// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. +// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, +// and returns the intersection point along dir in intersection_t. + +// Moller-Trumbore algorithm +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) +{ +	F32 u, v, t; +	 +	/* find vectors for two edges sharing vert0 */ +	LLVector3 edge1 = vert1 - vert0; +	 +	LLVector3 edge2 = vert2 - vert0;; + +	/* begin calculating determinant - also used to calculate U parameter */ +	LLVector3 pvec = dir % edge2; -	F32 dotprod = norm * vect; +	/* if determinant is near zero, ray lies in plane of triangle */ +	F32 det = edge1 * pvec; -	if(dotprod < 0) +	if (!two_sided)  	{ -		//Find point of intersect to triangle plane. -		//find t to intersect point -		F32 t = -(norm * (linept-pt1))/dotprod; +		if (det < F_APPROXIMATELY_ZERO) +		{ +			return FALSE; +		} + +		/* calculate distance from vert0 to ray origin */ +		LLVector3 tvec = orig - vert0; -		// if ds is neg line started past triangle so can't hit triangle. -		if (t > 0)  +		/* calculate U parameter and test bounds */ +		u = tvec * pvec;	 + +		if (u < 0.f || u > det)  		{  			return FALSE;  		} -		LLVector3 pt_int = linept + (vect*t); +		/* prepare to test V parameter */ +		LLVector3 qvec = tvec % edge1; -		if(check_same_clock_dir(pt1, pt2, pt_int, norm)) +		/* calculate V parameter and test bounds */ +		v = dir * qvec; +		if (v < 0.f || u + v > det)  		{ -			if(check_same_clock_dir(pt2, pt3, pt_int, norm)) +			return FALSE; +		} + +		/* calculate t, scale parameters, ray intersects triangle */ +		t = edge2 * qvec; +		F32 inv_det = 1.0 / det; +		t *= inv_det; +		u *= inv_det; +		v *= inv_det; +	} +	 +	else // two sided  			{ -				if(check_same_clock_dir(pt3, pt1, pt_int, norm)) +		if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO)  				{ -					// answer in pt_int is insde triangle -					linept.setVec(pt_int); -					return TRUE; +			return FALSE;  				} +		F32 inv_det = 1.0 / det; + +		/* calculate distance from vert0 to ray origin */ +		LLVector3 tvec = orig - vert0; +		 +		/* calculate U parameter and test bounds */ +		u = (tvec * pvec) * inv_det; +		if (u < 0.f || u > 1.f) +		{ +			return FALSE;  			} + +		/* prepare to test V parameter */ +		LLVector3 qvec = tvec - edge1; +		 +		/* calculate V parameter and test bounds */ +		v = (dir * qvec) * inv_det; +		 +		if (v < 0.f || u + v > 1.f) +		{ +			return FALSE;  		} + +		/* calculate t, ray intersects triangle */ +		t = (edge2 * qvec) * inv_det;  	} -	return FALSE; +	if (intersection_a != NULL) +		*intersection_a = u; +	if (intersection_b != NULL) +		*intersection_b = v; +	if (intersection_t != NULL) +		*intersection_t = t; +	 +	 +	return TRUE;  }  @@ -3405,47 +3487,99 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,  	}  } -S32 LLVolume::lineSegmentIntersect(const LLVector3& start, LLVector3& end) const +S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +								   S32 face, +								   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)  { -	S32 ret = -1; +	S32 hit_face = -1; +	 +	S32 start_face; +	S32 end_face; -	LLVector3 vec = end - start; +	if (face == -1) // ALL_SIDES +	{ +		start_face = 0; +		end_face = getNumFaces() - 1; +	} +	else +	{ +		start_face = face; +		end_face = face; +	} + +	LLVector3 dir = end - start; + +	F32 closest_t = 2.f; // must be larger than 1 -	for (S32 i = 0; i < getNumFaces(); i++) +	for (S32 i = start_face; i <= end_face; i++)  	{ -		const LLVolumeFace& face = getVolumeFace(i); +		LLVolumeFace face = getVolumeFace((U32)i); + +		LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f; +		LLVector3 box_size   = face.mExtents[1] - face.mExtents[0]; + +        if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) +		{ +			if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them +			{ +				genBinormals(i); +			} +			 +			for (U32 tri = 0; tri < face.mIndices.size()/3; tri++)  +			{ +				S32 index1 = face.mIndices[tri*3+0]; +				S32 index2 = face.mIndices[tri*3+1]; +				S32 index3 = face.mIndices[tri*3+2]; -		for (U32 j = 0; j < face.mIndices.size()/3; j++)  +				F32 a, b, t; +			 +				if (LLTriangleRayIntersect(face.mVertices[index1].mPosition, +										   face.mVertices[index2].mPosition, +										   face.mVertices[index3].mPosition, +										   start, dir, &a, &b, &t, FALSE)) +				{ +					if ((t >= 0.f) &&      // if hit is after start +						(t <= 1.f) &&      // and before end +						(t < closest_t))   // and this hit is closer  		{ -			//approximate normal -			S32 v1 = face.mIndices[j*3+0]; -			S32 v2 = face.mIndices[j*3+1]; -			S32 v3 = face.mIndices[j*3+2]; +						closest_t = t; +						hit_face = i; -			LLVector3 norm = (face.mVertices[v2].mPosition - face.mVertices[v1].mPosition) %  -				(face.mVertices[v3].mPosition - face.mVertices[v2].mPosition); +						if (intersection != NULL) +						{ +							*intersection = start + dir * closest_t; +						} -			if (norm.magVecSquared() >= 0.00000001f)  +						if (tex_coord != NULL)  			{ -				//get view vector -				//LLVector3 view = (start-face.mVertices[v1].mPosition); -				//if (view * norm < 0.0f) +							*tex_coord = ((1.f - a - b)  * face.mVertices[index1].mTexCoord + +										  a              * face.mVertices[index2].mTexCoord + +										  b              * face.mVertices[index3].mTexCoord); + +						} + +						if (normal != NULL)  				{ -					if (LLTriangleLineSegmentIntersect( face.mVertices[v1].mPosition, -														face.mVertices[v2].mPosition, -														face.mVertices[v3].mPosition, -														end, -														vec)) +							*normal    = ((1.f - a - b)  * face.mVertices[index1].mNormal +  +										  a              * face.mVertices[index2].mNormal + +										  b              * face.mVertices[index3].mNormal); +						} + +						if (bi_normal != NULL)  					{ -						vec = end-start; -						ret = (S32) i; +							*bi_normal = ((1.f - a - b)  * face.mVertices[index1].mBinormal +  +										  a              * face.mVertices[index2].mBinormal + +										  b              * face.mVertices[index3].mBinormal); +						} +  					}  				}  			}  		}		  	} -	return ret; +	 +	return hit_face;  }  class LLVertexIndexPair diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c395ed7378..0444a02825 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -906,7 +906,13 @@ 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, LLVector3& end) const; +	S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +							 S32 face = -1,                          // which face to check, -1 = ALL_SIDES +							 LLVector3* 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 +		);  	// The following cleans up vertices and triangles,  	// getting rid of degenerate triangles and duplicate vertices, @@ -967,4 +973,10 @@ LLVector3 calc_binormal_from_triangle(  		const LLVector3& pos2,  		const LLVector2& tex2); +BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); +BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, +							F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided); +	 +	 +  #endif diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp index 7033048575..f9e62cbd53 100644 --- a/indra/llmath/v2math.cpp +++ b/indra/llmath/v2math.cpp @@ -33,6 +33,7 @@  //#include "vmath.h"  #include "v2math.h" +#include "v3math.h"  #include "v4math.h"  #include "m4math.h"  #include "m3math.h" diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h index 5f46655a07..c896b80977 100644 --- a/indra/llmath/v2math.h +++ b/indra/llmath/v2math.h @@ -33,6 +33,7 @@  #define LL_V2MATH_H  #include "llmath.h" +#include "v3math.h"  class LLVector4;  class LLMatrix3; @@ -49,9 +50,10 @@ class LLVector2  		static LLVector2 zero; -		LLVector2();							// Initializes LLVector2 to (0, 0) -		LLVector2(F32 x, F32 y);			    // Initializes LLVector2 to (x. y) -		LLVector2(const F32 *vec);				// Initializes LLVector2 to (vec[0]. vec[1]) +		LLVector2();							  // Initializes LLVector2 to (0, 0) +		LLVector2(F32 x, F32 y);			      // Initializes LLVector2 to (x. y) +		LLVector2(const F32 *vec);				  // Initializes LLVector2 to (vec[0]. vec[1]) +        explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1])  		// Clears LLVector2 to (0, 0).  DEPRECATED - prefer zeroVec.  		void	clear(); @@ -137,6 +139,12 @@ inline LLVector2::LLVector2(const F32 *vec)  	mV[VY] = vec[VY];  } +inline LLVector2::LLVector2(const LLVector3 &vec) +{ +	mV[VX] = vec.mV[VX]; +	mV[VY] = vec.mV[VY]; +} +  // Clear and Assignment Functions diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index 166761e550..12916b6253 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -34,6 +34,7 @@  #include "v3math.h"  //#include "vmath.h" +#include "v2math.h"  #include "v4math.h"  #include "m4math.h"  #include "m3math.h" @@ -270,6 +271,13 @@ const LLVector3&	LLVector3::setVec(const LLVector4 &vec)  	return (*this);  } +LLVector3::LLVector3(const LLVector2 &vec) +{ +	mV[VX] = (F32)vec.mV[VX]; +	mV[VY] = (F32)vec.mV[VY]; +	mV[VZ] = 0; +} +  LLVector3::LLVector3(const LLVector3d &vec)  {  	mV[VX] = (F32)vec.mdV[VX]; diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 051d5376b7..42ca1f88b2 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -36,6 +36,7 @@  #include "llmath.h"  #include "llsd.h" +class LLVector2;  class LLVector4;  class LLMatrix3;  class LLVector3d; @@ -62,6 +63,7 @@ class LLVector3  		inline LLVector3();							// Initializes LLVector3 to (0, 0, 0)  		inline LLVector3(const F32 x, const F32 y, const F32 z);			// Initializes LLVector3 to (x. y, z)  		inline explicit LLVector3(const F32 *vec);				// Initializes LLVector3 to (vec[0]. vec[1], vec[2]) +		explicit LLVector3(const LLVector2 &vec);				// Initializes LLVector3 to (vec[0]. vec[1], 0)  		explicit LLVector3(const LLVector3d &vec);				// Initializes LLVector3 to (vec[0]. vec[1], vec[2])  		explicit LLVector3(const LLVector4 &vec);				// Initializes LLVector4 to (vec[0]. vec[1], vec[2])  		LLVector3(const LLSD& sd); diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index b1395b0b70..b5186ad539 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -574,7 +574,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender  			// repeat number is a single byte  			if (decode_pos >= mReceiveSize)  			{ -				logRanOffEndOfPacket(sender, decode_pos, 1); +				// commented out - hetgrid says that missing variable blocks +				// at end of message are legal +				// logRanOffEndOfPacket(sender, decode_pos, 1);  				// default to 0 repeats  				repeat_number = 0; diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 0d537e0575..dd034904d3 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -1371,4 +1371,7 @@ char* _PREHASH_OwnerMask = LLMessageStringTable::getInstance()->getString("Owner  char* _PREHASH_TransferInventoryAck = LLMessageStringTable::getInstance()->getString("TransferInventoryAck");  char* _PREHASH_RegionDenyAgeUnverified = LLMessageStringTable::getInstance()->getString("RegionDenyAgeUnverified");  char* _PREHASH_AgeVerificationBlock = LLMessageStringTable::getInstance()->getString("AgeVerificationBlock"); +char* _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord"); +char* _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord"); +char* _PREHASH_FaceIndex = LLMessageStringTable::getInstance()->getString("FaceIndex"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 287296d1eb..9dfb3992ca 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -1371,6 +1371,8 @@ extern char * _PREHASH_OwnerMask;  extern char * _PREHASH_TransferInventoryAck;  extern char * _PREHASH_RegionDenyAgeUnverified;  extern char * _PREHASH_AgeVerificationBlock; - +extern char * _PREHASH_UCoord; +extern char * _PREHASH_VCoord; +extern char * _PREHASH_FaceIndex;  #endif diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index c20bfe6ac0..c1da6c93fe 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -63,7 +63,6 @@ BOOL	LLView::sDebugKeys = FALSE;  S32		LLView::sDepth = 0;  BOOL	LLView::sDebugMouseHandling = FALSE;  std::string LLView::sMouseHandlerMessage; -S32	LLView::sSelectID = GL_NAME_UI_RESERVED;  BOOL	LLView::sEditingUI = FALSE;  BOOL	LLView::sForceReshape = FALSE;  LLView*	LLView::sEditingUIView = NULL; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 65f0a2b7e2..df3fb2e240 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1411,6 +1411,11 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)  	// Under certain circumstances, this will trigger us to decouple the cursor.  	adjustCursorDecouple(true); +	// trigger mouse move callback +	LLCoordGL gl_pos; +	convertCoords(position, &gl_pos); +	mCallbacks->handleMouseMove(this, gl_pos, (MASK)0); +  	return result;  } diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 4a81ddd1fd..526a6769a0 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1387,6 +1387,10 @@ BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position)  		return FALSE;  	} +	LLCoordGL gl_pos; +	convertCoords(position, &gl_pos); +	mCallbacks->handleMouseMove(this, gl_pos, (MASK)0); +	  	return SetCursorPos(screen_pos.mX, screen_pos.mY);  } diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp index 0b357c9182..b99bd64f2a 100644 --- a/indra/lscript/lscript_library/lscript_library.cpp +++ b/indra/lscript/lscript_library/lscript_library.cpp @@ -442,6 +442,14 @@ void LLScriptLibrary::init()  	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionAgentCount", "i", NULL, "int llGetRegionAgentCount()\nreturns the number of agents in a region"));  	addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llTextBox", NULL, "ksi", "llTextBox(key avatar, string message, integer chat_channel\nShows a dialog box on the avatar's screen with the message.\nA text box asks for input, and if entered the text is chatted on chat_channel."));  	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAgentLanguage", "s", "k", "string llGetAgentLanguage(key id)\nGets the agents preferred language..")); +	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchUV", "v", "i", "vector llDetectedTouchUV(integer number)\nreturns the u and v coordinates in the first two components of a vector, for a triggered touch event")); +	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchFace", "i", "i", "integer llDetectedTouchFace(integer number)\nreturns the index of the face on the object for a triggered touch event")); +	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchPos", "v", "i", "vector llDetectedTouchPos(integer number)\nreturns the position touched for a triggered touch event")); +	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchNormal", "v", "i", "vector llDetectedTouchNormal(integer number)\nreturns the surface normal for a triggered touch event")); +	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchBinormal", "v", "i", "vector llDetectedTouchBinormal(integer number)\nreturns the surface binormal for a triggered touch event")); +	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchST", "v", "i", "vector llDetectedTouchST(integer number)\nreturns the s and t coordinates in the first two components of a vector, for a triggered touch event")); + +  	// energy, sleep, dummy_func, name, return type, parameters, help text, gods-only diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8ca74f6d0f..4c47cb45b2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5201,6 +5201,28 @@        <key>Value</key>        <string />      </map> +    <key>PerFrameHoverPick</key> +    <map> +      <key>Comment</key> +      <string>Detect the object under the mouse continually</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <real>1</real> +    </map> +    <key>PerFrameHoverPickCount</key> +    <map> +      <key>Comment</key> +      <string>Detect the object under the mouse every n frames</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>PermissionsCautionEnabled</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7fb9e57507..cffd4410c3 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -133,7 +133,6 @@  // end Ventrella  extern LLMenuBarGL* gMenuBarView; -extern U8 gLastPickAlpha;  //drone wandering constants  const F32 MAX_WANDER_TIME = 20.f;						// seconds @@ -330,6 +329,8 @@ LLAgent::LLAgent()  	mCameraZoomFraction(1.f),			// deprecated  	mThirdPersonHeadOffset(0.f, 0.f, 1.f),  	mSitCameraEnabled(FALSE), +	mHUDTargetZoom(1.f), +	mHUDCurZoom(1.f),  	mFocusOnAvatar(TRUE),  	mFocusGlobal(),  	mFocusTargetGlobal(), @@ -530,10 +531,7 @@ void LLAgent::resetView(BOOL reset_camera)  		setFocusOnAvatar(TRUE, ANIMATE);  	} -	if (mAvatarObject.notNull()) -	{ -		mAvatarObject->mHUDTargetZoom = 1.f; -	} +	mHUDTargetZoom = 1.f;  }  // Handle any actions that need to be performed when the main app gains focus @@ -1298,7 +1296,7 @@ LLQuaternion LLAgent::getQuat() const  //-----------------------------------------------------------------------------  // calcFocusOffset()  //----------------------------------------------------------------------------- -LLVector3d LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y) +LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y)  {  	// calculate offset based on view direction  	BOOL is_avatar = object->isAvatar(); @@ -1457,10 +1455,10 @@ LLVector3d LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y)  		obj_rel = lerp(focus_delta, obj_rel, bias); -		return LLVector3d(obj_rel); +		return LLVector3(obj_rel);  	} -	return LLVector3d(focus_delta.mV[VX], focus_delta.mV[VY], focus_delta.mV[VZ]); +	return LLVector3(focus_delta.mV[VX], focus_delta.mV[VY], focus_delta.mV[VZ]);  }  //----------------------------------------------------------------------------- @@ -1650,7 +1648,7 @@ F32 LLAgent::getCameraZoomFraction()  	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)  	{  		// already [0,1] -		return mAvatarObject->mHUDTargetZoom; +		return mHUDTargetZoom;  	}  	else if (mFocusOnAvatar && cameraThirdPerson())  	{ @@ -1698,7 +1696,7 @@ void LLAgent::setCameraZoomFraction(F32 fraction)  	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)  	{ -		mAvatarObject->mHUDTargetZoom = fraction; +		mHUDTargetZoom = fraction;  	}  	else if (mFocusOnAvatar && cameraThirdPerson())  	{ @@ -1808,7 +1806,7 @@ void LLAgent::cameraZoomIn(const F32 fraction)  	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)  	{  		// just update hud zoom level -		mAvatarObject->mHUDTargetZoom /= fraction; +		mHUDTargetZoom /= fraction;  		return;  	} @@ -3757,7 +3755,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)  					lag_interp *= u; -					if (gViewerWindow->getLeftMouseDown() && gLastHitObjectID == mAvatarObject->getID()) +					if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == mAvatarObject->getID())  					{  						// disable camera lag when using mouse-directed steering  						target_lag.clearVec(); @@ -4285,6 +4283,12 @@ void LLAgent::setFocusObject(LLViewerObject* object)  //-----------------------------------------------------------------------------  // setFocusGlobal()  //----------------------------------------------------------------------------- +void LLAgent::setFocusGlobal(const LLPickInfo& pick) +{ +	setFocusGlobal(pick.mPosGlobal, pick.mObjectID); +} + +  void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)  {  	setFocusObject(gObjectList.findObject(object_id)); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 45006fef8d..ea9138fdd1 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -95,6 +95,7 @@ class LLMessageSystem;  class LLPermissions;  class LLHost;  class LLFriendObserver; +class LLPickInfo;  struct LLGroupData  { @@ -191,6 +192,7 @@ public:  	void			changeCameraToFollow(BOOL animate = TRUE);  	//end Ventrella +	void			setFocusGlobal(const LLPickInfo& pick);  	void			setFocusGlobal(const LLVector3d &focus, const LLUUID &object_id = LLUUID::null);  	void			setFocusOnAvatar(BOOL focus, BOOL animate);  	void			setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id); @@ -374,7 +376,7 @@ public:  	void			sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request);  	void			sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request); -	LLVector3d		calcFocusOffset(LLViewerObject *object, S32 x, S32 y); +	LLVector3		calcFocusOffset(LLViewerObject *object, S32 x, S32 y);  	BOOL			calcCameraMinDistance(F32 &obj_min_distance);  	void			startCameraAnimation(); @@ -711,6 +713,9 @@ public:  	LLDynamicArray<LLGroupData> mGroups; +	F32				mHUDTargetZoom;	// target zoom level for HUD objects (used when editing) +	F32				mHUDCurZoom;	// current animated zoom level for HUD objects +  	BOOL			mInitialized;  	static BOOL		sDebugDisplayTarget; @@ -786,6 +791,7 @@ private:  	LLVector3		mSitCameraFocus;				// root relative camera target when sitting  	LLVector3d      mCameraSmoothingLastPositionGlobal;      	LLVector3d      mCameraSmoothingLastPositionAgent;     +  	//Ventrella  	LLVector3		mCameraUpVector;				// camera's up direction in world coordinates (determines the 'roll' of the view) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 422c0dc9a8..6d81edd7ca 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -53,8 +53,6 @@ static U32 sBufferUsage = GL_STREAM_DRAW_ARB;  static U32 sShaderLevel = 0;  static LLGLSLShader* sVertexProgram = NULL; -extern BOOL gUseGLPick; -  F32 CLOTHING_GRAVITY_EFFECT = 0.7f;  F32 CLOTHING_ACCEL_FORCE_FACTOR = 0.2f;  const S32 NUM_TEST_AVATARS = 30; @@ -566,11 +564,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  //-----------------------------------------------------------------------------  void LLDrawPoolAvatar::renderForSelect()  { -	if (gUseGLPick) -	{ -		return; -	} -	  	if (!gRenderAvatar)  	{  		return; @@ -618,7 +611,7 @@ void LLDrawPoolAvatar::renderForSelect()  	glColor4ubv(color.mV); -	if ((sShaderLevel > 0) && !gUseGLPick)  // for hardware blending +	if (sShaderLevel > 0)  // for hardware blending  	{  		sRenderingSkinned = TRUE;  		sVertexProgram->bind(); @@ -628,7 +621,7 @@ void LLDrawPoolAvatar::renderForSelect()  	avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);  	// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done -	if ((sShaderLevel > 0) && !gUseGLPick) +	if (sShaderLevel > 0)  	{  		sRenderingSkinned = FALSE;  		sVertexProgram->unbind(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b2f5caa57d..16668f81e2 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -54,8 +54,6 @@  #define LL_MAX_INDICES_COUNT 1000000 -extern BOOL gPickFaces; -  BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE  #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]) @@ -73,14 +71,15 @@ The resulting texture coordinate <u,v> is:  	u = 2(B dot P)  	v = 2(T dot P)  */ -void planarProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec) +void planarProjection(LLVector2 &tc, const LLVector3& normal, +					  const LLVector3 &mCenter, const LLVector3& vec)  {	//DONE!  	LLVector3 binormal; -	float d = vd.mNormal * LLVector3(1,0,0); +	float d = normal * LLVector3(1,0,0);  	if (d >= 0.5f || d <= -0.5f)  	{  		binormal = LLVector3(0,1,0); -		if (vd.mNormal.mV[0] < 0) +		if (normal.mV[0] < 0)  		{  			binormal = -binormal;  		} @@ -88,18 +87,19 @@ void planarProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const L  	else  	{          binormal = LLVector3(1,0,0); -		if (vd.mNormal.mV[1] > 0) +		if (normal.mV[1] > 0)  		{  			binormal = -binormal;  		}  	} -	LLVector3 tangent = binormal % vd.mNormal; +	LLVector3 tangent = binormal % normal;  	tc.mV[1] = -((tangent*vec)*2 - 0.5f);  	tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f);  } -void sphericalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec) +void sphericalProjection(LLVector2 &tc, const LLVector3& normal, +						 const LLVector3 &mCenter, const LLVector3& vec)  {	//BROKEN  	/*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; @@ -110,7 +110,7 @@ void sphericalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, cons  	}*/  } -void cylindricalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, const LLVector3 &mCenter, const LLVector3& vec) +void cylindricalProjection(LLVector2 &tc, const LLVector3& normal, const LLVector3 &mCenter, const LLVector3& vec)  {	//BROKEN  	/*LLVector3 binormal;  	float d = vd.mNormal * LLVector3(1,0,0); @@ -374,7 +374,7 @@ void LLFace::renderForSelect(U32 data_mask)  #if !LL_RELEASE_FOR_DOWNLOAD  		LLGLState::checkClientArrays(data_mask);  #endif -		if (gPickFaces && mTEOffset != -1) +		if (mTEOffset != -1)  		{  			// mask off high 4 bits (16 total possible faces)  			color.mV[0] &= 0x0f; @@ -419,12 +419,11 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color)  	if (mGeomCount > 0 && mIndicesCount > 0)  	{ -		LLGLSPipelineAlpha gls_pipeline_alpha; -		glColor4fv(color.mV); +		gGL.color4fv(color.mV);  		LLViewerImage::bindTexture(imagep); -		glPushMatrix(); +		gGL.pushMatrix();  		if (mDrawablep->isActive())  		{  			glMultMatrixf((GLfloat*)mDrawablep->getRenderMatrix().mMatrix); @@ -434,137 +433,49 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color)  			glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix);  		} -		mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD); +		mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD);  #if !LL_RELEASE_FOR_DOWNLOAD -		LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD); +		LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD);  #endif  		mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, mIndicesCount, mIndicesIndex); -		glPopMatrix(); +		gGL.popMatrix();  	}  } -void LLFace::renderSelectedUV(const S32 offset, const S32 count) + +/* removed in lieu of raycast uv detection +void LLFace::renderSelectedUV()  { -#if 0  	LLViewerImage* red_blue_imagep = gImageList.getImageFromFile("uv_test1.j2c", TRUE, TRUE);  	LLViewerImage* green_imagep = gImageList.getImageFromFile("uv_test2.tga", TRUE, TRUE); -	LLGLSObjectSelect object_select; -	LLGLEnable blend(GL_BLEND); -	 -	if (!mDrawPoolp || !getIndicesCount() || getIndicesStart() < 0) -	{ -		return; -	} -	for (S32 pass = 0; pass < 2; pass++) -	{ -		static F32 bias = 0.f; -		static F32 factor = -10.f; -		if (mGeomCount > 0) -		{ -			gGL.color4fv(LLColor4::white.mV); - -			if (pass == 0) -			{ -				LLViewerImage::bindTexture(red_blue_imagep); -				red_blue_imagep->setMipFilterNearest (TRUE, TRUE); -			} -			else // pass == 1 -			{ -				gGL.blendFunc(GL_ONE, GL_ONE); -				LLViewerImage::bindTexture(green_imagep); -				glMatrixMode(GL_TEXTURE); -				glPushMatrix(); -				glScalef(256.f, 256.f, 1.f); -				green_imagep->setMipFilterNearest (TRUE, TRUE); -			} - - -			if (!isState(GLOBAL)) -			{ -				// Apply the proper transform for non-global objects. -				glMatrixMode(GL_MODELVIEW); -				glPushMatrix(); -				glMultMatrixf((float*)getRenderMatrix().mMatrix); -			} - -			glEnable(GL_POLYGON_OFFSET_FILL); -			glPolygonOffset(factor, bias); -			if (sSafeRenderSelect) -			{ -				gGL.begin(LLVertexBuffer::TRIANGLES); -				if (count) -				{ -					for (S32 i = offset; i < offset + count; i++) -					{ -						LLVector2 tc = mDrawPoolp->getTexCoord(mDrawPoolp->getIndex(getIndicesStart() + i), 0); -						gGL.texCoord2fv(tc.mV); -						LLVector3 vertex = mDrawPoolp->getVertex(mDrawPoolp->getIndex(getIndicesStart() + i)); -						gGL.vertex3fv(vertex.mV); -					} -				} -				else -				{ -					for (U32 i = 0; i < getIndicesCount(); i++) -					{ -						LLVector2 tc = mDrawPoolp->getTexCoord(mDrawPoolp->getIndex(getIndicesStart() + i), 0); -						gGL.texCoord2fv(tc.mV); -						LLVector3 vertex = mDrawPoolp->getVertex(mDrawPoolp->getIndex(getIndicesStart() + i)); -						gGL.vertex3fv(vertex.mV); -					} -				} -				gGL.end(); -			} -			else -			{ -				llassert(mGeomIndex >= 0); -				if (count) -				{ -					if (mIndicesCount > 0) -					{ -						glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, getRawIndices() + offset);  -					} -					else -					{ -						llerrs << "Rendering non-indexed volume face!" << llendl; -						glDrawArrays(mPrimType, mGeomIndex, mGeomCount);  -					} -				} -				else -				{ -					if (mIndicesCount > 0) -					{ -						glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_SHORT, getRawIndices());  -					} -					else -					{ -						glDrawArrays(GL_TRIANGLES, mGeomIndex, mGeomCount);  -					} -				} -			} +	LLGLSUVSelect object_select; -			glDisable(GL_POLYGON_OFFSET_FILL); -			if (!isState(GLOBAL)) -			{ -				// Restore the tranform for non-global objects -				glPopMatrix(); -			} -			if (pass == 1) -			{ -				glMatrixMode(GL_TEXTURE); -				glPopMatrix(); -				glMatrixMode(GL_MODELVIEW); -				gGL.blendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); -			} -		} -	} +	// use red/blue gradient to get coarse UV coordinates +	renderSelected(red_blue_imagep, LLColor4::white); -	//restore blend func -	gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -#endif +	static F32 bias = 0.f; +	static F32 factor = -10.f; +	glPolygonOffset(factor, bias); + +	// add green dither pattern on top of red/blue gradient +	gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ONE); +	glMatrixMode(GL_TEXTURE); +	glPushMatrix(); +	// make green pattern repeat once per texel in red/blue texture +	glScalef(256.f, 256.f, 1.f); +	glMatrixMode(GL_MODELVIEW); + +	renderSelected(green_imagep, LLColor4::white); + +	glMatrixMode(GL_TEXTURE); +	glPopMatrix(); +	glMatrixMode(GL_MODELVIEW); +	gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);  } +*/  void LLFace::printDebugInfo() const  { @@ -760,6 +671,69 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  	return TRUE;  } + + +// convert surface coordinates to texture coordinates, based on +// the values in the texture entry.  probably should be +// 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 tc = surface_coord; +	 +	const LLTextureEntry *tep = getTextureEntry(); + +	if (tep == NULL) +	{ +		// can't do much without the texture entry +		return surface_coord; +	} + +	// see if we have a non-default mapping +    U8 texgen = getTextureEntry()->getTexGen(); +	if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) +	{ +		LLVector3 center = mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter; +		 +		LLVector3 scale = (mDrawablep->getVOVolume()->isVolumeGlobal()) ? LLVector3(1,1,1) : mVObjp->getScale(); +		LLVector3 vec = position; +		vec.scaleVec(scale); + +		switch (texgen) +		{ +		case LLTextureEntry::TEX_GEN_PLANAR: +			planarProjection(tc, normal, center, vec); +			break; +		case LLTextureEntry::TEX_GEN_SPHERICAL: +			sphericalProjection(tc, normal, center, vec); +			break; +		case LLTextureEntry::TEX_GEN_CYLINDRICAL: +			cylindricalProjection(tc, normal, center, vec); +			break; +		default: +			break; +		}		 +	} + +	if (mTextureMatrix)	// if we have a texture matrix, use it +	{ +		LLVector3 tc3(tc); +		tc3 = tc3 * *mTextureMatrix; +		tc = LLVector2(tc3); +	} +	 +	else // otherwise use the texture entry parameters +	{ +		xform(tc, cos(tep->getRotation()), sin(tep->getRotation()), +			  tep->mOffsetS, tep->mOffsetT, tep->mScaleS, tep->mScaleT); +	} + +	 +	return tc; +} + +  BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							   const S32 &f,  								const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, @@ -1039,13 +1013,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				switch (texgen)  				{  					case LLTextureEntry::TEX_GEN_PLANAR: -						planarProjection(tc, vf.mVertices[i], vf.mCenter, vec); +						planarProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);  						break;  					case LLTextureEntry::TEX_GEN_SPHERICAL: -						sphericalProjection(tc, vf.mVertices[i], vf.mCenter, vec); +						sphericalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);  						break;  					case LLTextureEntry::TEX_GEN_CYLINDRICAL: -						cylindricalProjection(tc, vf.mVertices[i], vf.mCenter, vec); +						cylindricalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);  						break;  					default:  						break; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 0391cda66f..9e7a33eb7b 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -91,6 +91,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);  	U32				getState()			const	{ return mState; }  	void			setState(U32 state)			{ mState |= state; } @@ -165,7 +166,7 @@ public:  	void		update();  	void		updateCenterAgent(); // Update center when xform has changed. -	void		renderSelectedUV(const S32 offset = 0, const S32 count = 0); +	void		renderSelectedUV();  	void		renderForSelect(U32 data_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD);  	void		renderSelected(LLImageGL *image, const LLColor4 &color); diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h index 11d9f43fcc..12b2eced9b 100644 --- a/indra/newview/llhudobject.h +++ b/indra/newview/llhudobject.h @@ -67,6 +67,8 @@ public:  	U8 getType() const { return mType; } +	LLVector3d getPositionGlobal() const { return mPositionGlobal; } +  	static LLHUDObject *addHUDObject(const U8 type);  	static LLHUDEffect *addHUDEffect(const U8 type);  	static void updateAll(); diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 5e09e69e2b..891dd69f84 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -96,7 +96,8 @@ LLManip::LLManip( const std::string& name, LLToolComposite* composite )  	:  	LLTool( name, composite ),  	mInSnapRegime(FALSE), -	mHighlightedPart(LL_NO_PART) +	mHighlightedPart(LL_NO_PART), +	mManipPart(LL_NO_PART)  {  } @@ -177,7 +178,7 @@ F32 LLManip::getSubdivisionLevel(const LLVector3 &reference_point, const LLVecto  	LLVector3 cam_to_reference;  	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{ -		cam_to_reference = LLVector3(1.f / gAgent.getAvatarObject()->mHUDCurZoom, 0.f, 0.f); +		cam_to_reference = LLVector3(1.f / gAgent.mHUDCurZoom, 0.f, 0.f);  	}  	else  	{ @@ -199,6 +200,8 @@ void LLManip::handleSelect()  void LLManip::handleDeselect()  { +	mHighlightedPart = LL_NO_PART; +	mManipPart = LL_NO_PART;  	mObjectSelection = NULL;  } @@ -260,8 +263,8 @@ BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVect  	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{  		BOOL result = FALSE; -		F32 mouse_x = ((F32)x / gViewerWindow->getWindowWidth() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.getAvatarObject()->mHUDCurZoom; -		F32 mouse_y = ((F32)y / gViewerWindow->getWindowHeight() - 0.5f) / gAgent.getAvatarObject()->mHUDCurZoom; +		F32 mouse_x = ((F32)x / gViewerWindow->getWindowWidth() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.mHUDCurZoom; +		F32 mouse_y = ((F32)y / gViewerWindow->getWindowHeight() - 0.5f) / gAgent.mHUDCurZoom;  		LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin);  		LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y); @@ -299,8 +302,8 @@ BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, co  	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{ -		F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.getAvatarObject()->mHUDCurZoom; -		F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.getAvatarObject()->mHUDCurZoom; +		F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.mHUDCurZoom; +		F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.mHUDCurZoom;  		a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y);  		a2 = a1 + LLVector3(1.f, 0.f, 0.f);  	} @@ -484,7 +487,7 @@ void LLManip::renderTickText(const LLVector3& pos, const std::string& text, cons  	LLVector3 render_pos = pos;  	if (hud_selection)  	{ -		F32 zoom_amt = gAgent.getAvatarObject()->mHUDCurZoom; +		F32 zoom_amt = gAgent.mHUDCurZoom;  		F32 inv_zoom_amt = 1.f / zoom_amt;  		// scale text back up to counter-act zoom level  		render_pos = pos * zoom_amt; @@ -542,7 +545,7 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string  	LLVector3 render_pos = pos;  	if (hud_selection)  	{ -		F32 zoom_amt = gAgent.getAvatarObject()->mHUDCurZoom; +		F32 zoom_amt = gAgent.mHUDCurZoom;  		F32 inv_zoom_amt = 1.f / zoom_amt;  		// scale text back up to counter-act zoom level  		render_pos = pos * zoom_amt; diff --git a/indra/newview/llmanip.h b/indra/newview/llmanip.h index 1313f77c5b..43d6eaadc8 100644 --- a/indra/newview/llmanip.h +++ b/indra/newview/llmanip.h @@ -155,6 +155,7 @@ protected:  	BOOL				mInSnapRegime;  	LLSafeHandle<LLObjectSelection> mObjectSelection;  	EManipPart			mHighlightedPart; +	EManipPart			mManipPart;  	static F32			sHelpTextVisibleTime;  	static F32			sHelpTextFadeTime; diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index e98ded2a87..ca0812c8a0 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -98,7 +98,6 @@ LLManipRotate::LLManipRotate( LLToolComposite* composite )  	mCenterToCamMag(0.f),  	mCenterToProfilePlane(),  	mCenterToProfilePlaneMag(0.f), -	mManipPart( LL_NO_PART ),  	mSendUpdateOnMouseUp( FALSE ),  	mSmoothRotate( FALSE ),  	mCamEdgeOn(FALSE), @@ -113,13 +112,6 @@ void LLManipRotate::handleSelect()  	LLManip::handleSelect();  } -void LLManipRotate::handleDeselect() -{ -	mHighlightedPart = LL_NO_PART; -	mManipPart = LL_NO_PART; -	LLManip::handleDeselect(); -} -  void LLManipRotate::render()  {  	LLGLSUIDefault gls_ui; @@ -144,7 +136,7 @@ void LLManipRotate::render()  	glPushMatrix();  	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{ -		F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom; +		F32 zoom = gAgent.mHUDCurZoom;  		glScalef(zoom, zoom, zoom);  	} @@ -363,8 +355,7 @@ BOOL LLManipRotate::handleMouseDown(S32 x, S32 y, MASK mask)  	LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE);  	if( first_object )  	{ -		LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); -		if( hit_obj && mHighlightedPart != LL_NO_PART ) +		if( mHighlightedPart != LL_NO_PART )  		{  			handled = handleMouseDownOnPart( x, y, mask );  		} @@ -1126,18 +1117,18 @@ BOOL LLManipRotate::updateVisiblity()  	LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );  	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{ -		mCenterToCam = LLVector3(-1.f / gAgent.getAvatarObject()->mHUDCurZoom, 0.f, 0.f); +		mCenterToCam = LLVector3(-1.f / gAgent.mHUDCurZoom, 0.f, 0.f);  		mCenterToCamNorm = mCenterToCam;  		mCenterToCamMag = mCenterToCamNorm.normVec();  		mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); -		mRadiusMeters /= gAgent.getAvatarObject()->mHUDCurZoom; +		mRadiusMeters /= gAgent.mHUDCurZoom;  		mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag;  		mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm; -		mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgent.getAvatarObject()->mHUDCurZoom * gViewerWindow->getWindowWidth()), -							(S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgent.getAvatarObject()->mHUDCurZoom * gViewerWindow->getWindowHeight())); +		mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWindowWidth()), +							(S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWindowHeight()));  		visible = TRUE;  	}  	else @@ -1653,8 +1644,8 @@ void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_  {  	if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD)  	{ -		F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) / gAgent.getAvatarObject()->mHUDCurZoom; -		F32 mouse_y = ((((F32)y) / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.getAvatarObject()->mHUDCurZoom; +		F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) / gAgent.mHUDCurZoom; +		F32 mouse_y = ((((F32)y) / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.mHUDCurZoom;  		*ray_pt = LLVector3(-1.f, -mouse_x, mouse_y);  		*ray_dir = LLVector3(1.f, 0.f, 0.f); diff --git a/indra/newview/llmaniprotate.h b/indra/newview/llmaniprotate.h index 460bd3fcba..f5c815d537 100644 --- a/indra/newview/llmaniprotate.h +++ b/indra/newview/llmaniprotate.h @@ -64,7 +64,6 @@ public:  	virtual void	render();  	virtual void	handleSelect(); -	virtual void	handleDeselect();  	virtual BOOL	handleMouseDownOnPart(S32 x, S32 y, MASK mask);  	virtual void	highlightManipulators(S32 x, S32 y); @@ -109,8 +108,6 @@ private:  	LLVector3			mCenterToProfilePlane;  	F32					mCenterToProfilePlaneMag; -	EManipPart			mManipPart; -  	BOOL				mSendUpdateOnMouseUp;  	BOOL				mSmoothRotate; diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 57c901e9bc..5859d4c75f 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -166,19 +166,11 @@ void LLManipScale::handleSelect()  	LLManip::handleSelect();  } -void LLManipScale::handleDeselect() -{ -	mHighlightedPart = LL_NO_PART; -	mManipPart = LL_NO_PART; -	LLManip::handleDeselect(); -} -  LLManipScale::LLManipScale( LLToolComposite* composite )  	:   	LLManip( std::string("Scale"), composite ),  	mBoxHandleSize( 1.f ),  	mScaledBoxHandleSize( 1.f ), -	mManipPart( LL_NO_PART ),  	mLastMouseX( -1 ),  	mLastMouseY( -1 ),  	mSendUpdateOnMouseUp( FALSE ), @@ -216,7 +208,7 @@ void LLManipScale::render()  		glPushMatrix();  		if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  		{ -			F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom; +			F32 zoom = gAgent.mHUDCurZoom;  			glScalef(zoom, zoom, zoom);  		} @@ -233,7 +225,7 @@ void LLManipScale::render()  		if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  		{  			mBoxHandleSize = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); -			mBoxHandleSize /= gAgent.getAvatarObject()->mHUDCurZoom; +			mBoxHandleSize /= gAgent.mHUDCurZoom;  		}  		else  		{ @@ -316,9 +308,7 @@ BOOL LLManipScale::handleMouseDown(S32 x, S32 y, MASK mask)  {  	BOOL	handled = FALSE; -	LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); -	if( hit_obj ||   -		(mHighlightedPart != LL_NO_PART) ) +	if(mHighlightedPart != LL_NO_PART)  	{  		handled = handleMouseDownOnPart( x, y, mask );  	} @@ -446,7 +436,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)  			LLMatrix4 cfr(OGL_TO_CFR_ROTATION);  			transform *= cfr;  			LLMatrix4 window_scale; -			F32 zoom_level = 2.f * gAgent.getAvatarObject()->mHUDCurZoom; +			F32 zoom_level = 2.f * gAgent.mHUDCurZoom;  			window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f),  				LLQuaternion::DEFAULT,  				LLVector3::zero); @@ -1367,7 +1357,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)  	if(mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{ -		mSnapRegimeOffset = SNAP_GUIDE_SCREEN_OFFSET / gAgent.getAvatarObject()->mHUDCurZoom; +		mSnapRegimeOffset = SNAP_GUIDE_SCREEN_OFFSET / gAgent.mHUDCurZoom;  	}  	else @@ -1380,7 +1370,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)  	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{  		cam_at_axis.setVec(1.f, 0.f, 0.f); -		snap_guide_length = SNAP_GUIDE_SCREEN_LENGTH / gAgent.getAvatarObject()->mHUDCurZoom; +		snap_guide_length = SNAP_GUIDE_SCREEN_LENGTH / gAgent.mHUDCurZoom;  	}  	else  	{ diff --git a/indra/newview/llmanipscale.h b/indra/newview/llmanipscale.h index c02845e358..432be2cd3e 100644 --- a/indra/newview/llmanipscale.h +++ b/indra/newview/llmanipscale.h @@ -76,7 +76,6 @@ public:  	virtual BOOL	handleHover( S32 x, S32 y, MASK mask );  	virtual void	render();  	virtual void	handleSelect(); -	virtual void	handleDeselect();  	virtual BOOL	handleMouseDownOnPart(S32 x, S32 y, MASK mask);  	virtual void	highlightManipulators(S32 x, S32 y);	// decided which manipulator, if any, should be highlighted by mouse hover @@ -140,7 +139,6 @@ private:  	F32				mBoxHandleSize;		// The size of the handles at the corners of the bounding box  	F32				mScaledBoxHandleSize; // handle size after scaling for selection feedback -	EManipPart		mManipPart;  	LLVector3d		mDragStartPointGlobal;  	LLVector3d		mDragStartCenterGlobal;	// The center of the bounding box of all selected objects at time of drag start  	LLVector3d		mDragPointGlobal; diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index f4f3a535de..7785b5a078 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -113,7 +113,6 @@ LLManipTranslate::LLManipTranslate( LLToolComposite* composite )  	mConeSize(0),  	mArrowLengthMeters(0.f),  	mPlaneManipOffsetMeters(0.f), -	mManipPart(LL_NO_PART),  	mUpdateTimer(),  	mSnapOffsetMeters(0.f),  	mArrowScales(1.f, 1.f, 1.f), @@ -257,21 +256,12 @@ void LLManipTranslate::handleSelect()  	LLManip::handleSelect();  } -void LLManipTranslate::handleDeselect() -{ -	mHighlightedPart = LL_NO_PART; -	mManipPart = LL_NO_PART; -	LLManip::handleDeselect(); -} -  BOOL LLManipTranslate::handleMouseDown(S32 x, S32 y, MASK mask)  {  	BOOL	handled = FALSE;  	// didn't click in any UI object, so must have clicked in the world -	LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); -	if( hit_obj &&  -		(mHighlightedPart == LL_X_ARROW || +	if( (mHighlightedPart == LL_X_ARROW ||  		 mHighlightedPart == LL_Y_ARROW ||  		 mHighlightedPart == LL_Z_ARROW ||  		 mHighlightedPart == LL_YZ_PLANE || @@ -818,7 +808,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y)  		LLMatrix4 cfr(OGL_TO_CFR_ROTATION);  		transform *= cfr;  		LLMatrix4 window_scale; -		F32 zoom_level = 2.f * gAgent.getAvatarObject()->mHUDCurZoom; +		F32 zoom_level = 2.f * gAgent.mHUDCurZoom;  		window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f),  			LLQuaternion::DEFAULT,  			LLVector3::zero); @@ -1056,7 +1046,7 @@ void LLManipTranslate::render()  	gGL.pushMatrix();  	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{ -		F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom; +		F32 zoom = gAgent.mHUDCurZoom;  		glScalef(zoom, zoom, zoom);  	}  	{ @@ -1220,7 +1210,7 @@ void LLManipTranslate::renderSnapGuides()  		if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  		{ -			guide_size_meters = 1.f / gAgent.getAvatarObject()->mHUDCurZoom; +			guide_size_meters = 1.f / gAgent.mHUDCurZoom;  			mSnapOffsetMeters = mArrowLengthMeters * 1.5f;  		}  		else @@ -1803,7 +1793,7 @@ void LLManipTranslate::renderTranslationHandles()  	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)  	{  		mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWindowHeight(); -		mArrowLengthMeters /= gAgent.getAvatarObject()->mHUDCurZoom; +		mArrowLengthMeters /= gAgent.mHUDCurZoom;  	}  	else  	{ diff --git a/indra/newview/llmaniptranslate.h b/indra/newview/llmaniptranslate.h index c9f98e9c7d..8c17dd3d51 100644 --- a/indra/newview/llmaniptranslate.h +++ b/indra/newview/llmaniptranslate.h @@ -61,7 +61,6 @@ public:  	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);  	virtual void	render();  	virtual void	handleSelect(); -	virtual void	handleDeselect();  	virtual void	highlightManipulators(S32 x, S32 y);  	virtual BOOL	handleMouseDownOnPart(S32 x, S32 y, MASK mask); @@ -110,7 +109,6 @@ private:  	F32			mArrowLengthMeters;		// meters  	F32			mGridSizeMeters;  	F32			mPlaneManipOffsetMeters; -	EManipPart	mManipPart;  	LLVector3	mManipNormal;  	LLVector3d	mDragCursorStartGlobal;  	LLVector3d	mDragSelectionStartGlobal; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 8ebaeb6758..2f11dad010 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -96,9 +96,6 @@ const S32 MAX_ACTION_QUEUE_SIZE = 20;  const S32 MAX_SILS_PER_FRAME = 50;  const S32 MAX_OBJECTS_PER_PACKET = 254; -extern LLUUID			gLastHitObjectID; -extern LLVector3d		gLastHitObjectOffset; -  //  // Globals  // @@ -4833,7 +4830,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)  	{  		LLBBox hud_bbox = avatar->getHUDBBox(); -		F32 cur_zoom = avatar->mHUDCurZoom; +		F32 cur_zoom = gAgent.mHUDCurZoom;  		// set up transform to encompass bounding box of HUD  		glMatrixMode(GL_PROJECTION); @@ -5280,7 +5277,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)  		F32 silhouette_thickness;  		if (is_hud_object && gAgent.getAvatarObject())  		{ -			silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgent.getAvatarObject()->mHUDCurZoom; +			silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgent.mHUDCurZoom;  		}  		else  		{ @@ -5479,8 +5476,8 @@ void LLSelectMgr::updateSelectionCenter()  		if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && gAgent.getAvatarObject())  		{  			// reset hud ZOOM -			gAgent.getAvatarObject()->mHUDTargetZoom = 1.f; -			gAgent.getAvatarObject()->mHUDCurZoom = 1.f; +			gAgent.mHUDTargetZoom = 1.f; +			gAgent.mHUDCurZoom = 1.f;  		}  		mShowSelection = FALSE; @@ -5564,11 +5561,12 @@ void LLSelectMgr::updatePointAt()  		if (mSelectedObjects->getObjectCount())  		{					  			LLVector3 select_offset; -			LLViewerObject *click_object = gObjectList.findObject(gLastHitObjectID); +			const LLPickInfo& pick = gViewerWindow->getLastPick(); +			LLViewerObject *click_object = pick.getObject();  			if (click_object && click_object->isSelected())  			{  				// clicked on another object in our selection group, use that as target -				select_offset.setVec(gLastHitObjectOffset); +				select_offset.setVec(pick.mObjectOffset);  				select_offset.rotVec(~click_object->getRenderRotation());  				gAgent.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset); @@ -5766,29 +5764,20 @@ BOOL LLSelectMgr::setForceSelection(BOOL force)  void LLSelectMgr::resetAgentHUDZoom()  { -	if (gAgent.getAvatarObject()) -	{ -		gAgent.getAvatarObject()->mHUDTargetZoom = 1.f; -		gAgent.getAvatarObject()->mHUDCurZoom = 1.f; -	} +	gAgent.mHUDTargetZoom = 1.f; +	gAgent.mHUDCurZoom = 1.f;  }  void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const  { -	if (gAgent.getAvatarObject()) -	{ -		target_zoom = gAgent.getAvatarObject()->mHUDTargetZoom; -		current_zoom = gAgent.getAvatarObject()->mHUDCurZoom; -	} +	target_zoom = gAgent.mHUDTargetZoom; +	current_zoom = gAgent.mHUDCurZoom;  }  void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)  { -	if (gAgent.getAvatarObject()) -	{ -		gAgent.getAvatarObject()->mHUDTargetZoom = target_zoom; -		gAgent.getAvatarObject()->mHUDCurZoom = current_zoom; -	} +	gAgent.mHUDTargetZoom = target_zoom; +	gAgent.mHUDCurZoom = current_zoom;  }  LLObjectSelection::LLObjectSelection() :  diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index a62b1ac56a..e9b09599e2 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -36,6 +36,7 @@  #include "llviewerwindow.h"  #include "llviewerobjectlist.h"  #include "llvovolume.h" +#include "llvolume.h"  #include "llviewercamera.h"  #include "llface.h"  #include "llviewercontrol.h" @@ -243,28 +244,6 @@ void LLSpatialGroup::buildOcclusion()  BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); -BOOL LLLineSegmentAABB(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size) -{ -	float fAWdU[3]; -	LLVector3 dir; -	LLVector3 diff; -	 -	for (U32 i = 0; i < 3; i++) -	{ -		dir.mV[i] = 0.5f * (end.mV[i] - start.mV[i]); -		diff.mV[i] = (0.5f * (end.mV[i] + start.mV[i])) - center.mV[i]; -		fAWdU[i] = fabsf(dir.mV[i]); -		if(fabsf(diff.mV[i])>size.mV[i] + fAWdU[i])	return false; -	} - -	float f; -	f = dir.mV[1] * diff.mV[2] - dir.mV[2] * diff.mV[1];	if(fabsf(f)>size.mV[1]*fAWdU[2] + size.mV[2]*fAWdU[1])	return false; -	f = dir.mV[2] * diff.mV[0] - dir.mV[0] * diff.mV[2];	if(fabsf(f)>size.mV[0]*fAWdU[2] + size.mV[2]*fAWdU[0])	return false; -	f = dir.mV[0] * diff.mV[1] - dir.mV[1] * diff.mV[0];	if(fabsf(f)>size.mV[0]*fAWdU[1] + size.mV[1]*fAWdU[0])	return false; - -	return true; -} -  //returns:  //	0 if sphere and AABB are not intersecting   //	1 if they are @@ -2305,6 +2284,56 @@ void renderLights(LLDrawable* drawablep)  	}  } + +void renderRaycast(LLDrawable* drawablep) +{ +	if (drawablep->getVObj() != gDebugRaycastObject) +	{ +		return; +	} +	 +	if (drawablep->getNumFaces()) +	{ +		LLGLEnable blend(GL_BLEND); +		gGL.color4f(0,1,1,0.5f); + +		for (S32 i = 0; i < drawablep->getNumFaces(); i++) +		{ +			pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); +		} + +		// draw intersection point +		glPushMatrix(); +		glLoadMatrixd(gGLModelView); +		LLVector3 translate = gDebugRaycastIntersection; +		glTranslatef(translate.mV[0], translate.mV[1], translate.mV[2]); +		LLCoordFrame orient; +		orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal); +		LLMatrix4 rotation; +		orient.getRotMatrixToParent(rotation); +		glMultMatrixf((float*)rotation.mMatrix); +		 +		gGL.color4f(1,0,0,0.5f); +		drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f)); +		gGL.color4f(0,1,0,0.5f); +		drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f)); +		gGL.color4f(0,0,1,0.5f); +		drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f)); +		glPopMatrix(); + +		// draw bounding box of prim +		const LLVector3* ext = drawablep->getSpatialExtents(); + +		LLVector3 pos = (ext[0] + ext[1]) * 0.5f; +		LLVector3 size = (ext[1] - ext[0]) * 0.5f; + +		LLGLDepthTest depth(GL_FALSE, GL_TRUE); +		gGL.color4f(0,0.5f,0.5f,1); +		drawBoxOutline(pos, size); + +	} +} +  class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>  {  public: @@ -2381,6 +2410,11 @@ public:  			{  				renderLights(drawable);  			} + +			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) +			{ +				renderRaycast(drawable); +			}  		}  		for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -2411,7 +2445,8 @@ void LLSpatialPartition::renderDebug()  									  LLPipeline::RENDER_DEBUG_BBOXES |  									  LLPipeline::RENDER_DEBUG_POINTS |  									  LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | -									  LLPipeline::RENDER_DEBUG_TEXTURE_ANIM)) +									  LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | +									  LLPipeline::RENDER_DEBUG_RAYCAST))  	{  		return;  	} @@ -2457,17 +2492,37 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)  	return TRUE;  } -class LLOctreePick : public LLSpatialGroup::OctreeTraveler +class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler  {  public:  	LLVector3 mStart;  	LLVector3 mEnd; -	LLDrawable* mRet; +	S32       *mFaceHit; +	LLVector3 *mIntersection; +	LLVector2 *mTexCoord; +	LLVector3 *mNormal; +	LLVector3 *mBinormal; +	LLDrawable* mHit; -	LLOctreePick(LLVector3 start, LLVector3 end) -	: mStart(start), mEnd(end) +	LLOctreeIntersect(LLVector3 start, LLVector3 end, +					  S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal) +		: mStart(start), +		  mEnd(end), +		  mFaceHit(face_hit), +		  mIntersection(intersection), +		  mTexCoord(tex_coord), +		  mNormal(normal), +		  mBinormal(binormal), +		  mHit(NULL)  	{ -		mRet = NULL; +	} +	 +	virtual void visit(const LLSpatialGroup::OctreeNode* branch)  +	{	 +		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) +	{ +			check(*i); +		}  	}  	virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node) @@ -2487,41 +2542,73 @@ public:  			size = group->mBounds[1];  			center = group->mBounds[0]; -			if (LLLineSegmentAABB(mStart, mEnd, center, size)) +			LLVector3 local_start = mStart; +			LLVector3 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; +			} + +			if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))  			{  				check(child);  			}  		}	 -		return mRet; +		return mHit;  	} -	virtual void visit(const LLSpatialGroup::OctreeNode* branch)  +	virtual bool check(LLDrawable* drawable)  	{	 -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) +		if (drawable->isSpatialBridge())  		{ -			check(*i); -		} +			LLSpatialPartition *part = drawable->asPartition(); + +			check(part->mOctree);  	} -	virtual bool check(LLDrawable* drawable) +		else  	{  		LLViewerObject* vobj = drawable->getVObj(); -		if (vobj->lineSegmentIntersect(mStart, mEnd)) + +			if (vobj) +			{ +				LLVector3 intersection; +				if (vobj->lineSegmentIntersect(mStart, mEnd, -1, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) +				{ +					mEnd = intersection;  // shorten ray so we only find CLOSER hits +					if (mIntersection)  		{ -			mRet = vobj->mDrawable; +						*mIntersection = intersection; +					} +					 +					mHit = vobj->mDrawable; +				} +			}  		}  		return false;  	}  }; -LLDrawable*	LLSpatialPartition::pickDrawable(const LLVector3& start, const LLVector3& end, LLVector3& collision) +LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +													 S32* face_hit,                   // return the face hit +													 LLVector3* 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 +	) +  { -	LLOctreePick pick(start, end); -	LLDrawable* ret = pick.check(mOctree); -	collision.setVec(pick.mEnd); -	return ret; +	LLOctreeIntersect intersect(start, end, face_hit, intersection, tex_coord, normal, bi_normal); +	LLDrawable* drawable = intersect.check(mOctree); + +	return drawable;  }  LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,  diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 7e872915b9..d9a81d8b9e 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -300,7 +300,14 @@ public:  	LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);  	BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp); -	LLDrawable*	pickDrawable(const LLVector3& start, const LLVector3& end, LLVector3& collision); +	LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +									 S32* face_hit,                          // return the face hit +									 LLVector3* 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 +		); +	  	// If the drawable moves, move it here.  	virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index c522bd0697..83b5cdbb66 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1452,13 +1452,15 @@ LLToolTexEyedropper::~LLToolTexEyedropper()  BOOL LLToolTexEyedropper::handleMouseDown(S32 x, S32 y, MASK mask)  { -	LLViewerObject* hit_obj	= gViewerWindow->lastObjectHit(); +	// this will affect framerate on mouse down +	const LLPickInfo& pick = gViewerWindow->pickImmediate(x, y, FALSE); +	LLViewerObject* hit_obj	= pick.getObject();  	if (hit_obj &&   		!hit_obj->isAvatar())  	{ -		if( (0 <= gLastHitObjectFace) && (gLastHitObjectFace < hit_obj->getNumTEs()) ) +		if( (0 <= pick.mObjectFace) && (pick.mObjectFace < hit_obj->getNumTEs()) )  		{ -			LLViewerImage* image = hit_obj->getTEImage( gLastHitObjectFace ); +			LLViewerImage* image = hit_obj->getTEImage( pick.mObjectFace );  			if( image )  			{  				if( mCallback ) diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 4efc6f74d4..9fd8044cca 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -145,18 +145,18 @@ LLToolCompInspect::~LLToolCompInspect()  BOOL LLToolCompInspect::handleMouseDown(S32 x, S32 y, MASK mask)  {  	mMouseDown = TRUE; -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +	gViewerWindow->pickAsync(x, y, mask, pickCallback);  	return TRUE;  } -void LLToolCompInspect::pickCallback(S32 x, S32 y, MASK mask) +void LLToolCompInspect::pickCallback(const LLPickInfo& pick_info)  { -	LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); +	LLViewerObject* hit_obj = pick_info.getObject();  	if (!LLToolCompInspect::getInstance()->mMouseDown)  	{  		// fast click on object, but mouse is already up...just do select -		LLToolCompInspect::getInstance()->mSelectRect->handleObjectSelection(hit_obj, mask, gSavedSettings.getBOOL("EditLinkedParts"), FALSE); +		LLToolCompInspect::getInstance()->mSelectRect->handleObjectSelection(pick_info, gSavedSettings.getBOOL("EditLinkedParts"), FALSE);  		return;  	} @@ -167,13 +167,13 @@ void LLToolCompInspect::pickCallback(S32 x, S32 y, MASK mask)  			LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance();  		}  		LLToolCompInspect::getInstance()->setCurrentTool( LLToolCompInspect::getInstance()->mSelectRect ); -		LLToolCompInspect::getInstance()->mSelectRect->handleMouseDown( x, y, mask ); +		LLToolCompInspect::getInstance()->mSelectRect->handlePick( pick_info );  	}  	else  	{  		LLToolCompInspect::getInstance()->setCurrentTool( LLToolCompInspect::getInstance()->mSelectRect ); -		LLToolCompInspect::getInstance()->mSelectRect->handleMouseDown( x, y, mask); +		LLToolCompInspect::getInstance()->mSelectRect->handlePick( pick_info );  	}  } @@ -218,19 +218,19 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask)  {  	mMouseDown = TRUE; -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback, TRUE); +	gViewerWindow->pickAsync(x, y, mask, pickCallback, TRUE);  	return TRUE;  } -void LLToolCompTranslate::pickCallback(S32 x, S32 y, MASK mask) +void LLToolCompTranslate::pickCallback(const LLPickInfo& pick_info)  { -	LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); +	LLViewerObject* hit_obj = pick_info.getObject(); -	LLToolCompTranslate::getInstance()->mManip->highlightManipulators(x, y); +	LLToolCompTranslate::getInstance()->mManip->highlightManipulators(pick_info.mMousePt.mX, pick_info.mMousePt.mY);  	if (!LLToolCompTranslate::getInstance()->mMouseDown)  	{  		// fast click on object, but mouse is already up...just do select -		LLToolCompTranslate::getInstance()->mSelectRect->handleObjectSelection(hit_obj, mask, gSavedSettings.getBOOL("EditLinkedParts"), FALSE); +		LLToolCompTranslate::getInstance()->mSelectRect->handleObjectSelection(pick_info, gSavedSettings.getBOOL("EditLinkedParts"), FALSE);  		return;  	} @@ -246,12 +246,12 @@ void LLToolCompTranslate::pickCallback(S32 x, S32 y, MASK mask)  		if(	LLManip::LL_NO_PART != LLToolCompTranslate::getInstance()->mManip->getHighlightedPart() && can_move)  		{  			LLToolCompTranslate::getInstance()->setCurrentTool( LLToolCompTranslate::getInstance()->mManip ); -			LLToolCompTranslate::getInstance()->mManip->handleMouseDownOnPart( x, y, mask ); +			LLToolCompTranslate::getInstance()->mManip->handleMouseDownOnPart( pick_info.mMousePt.mX, pick_info.mMousePt.mY, pick_info.mKeyMask );  		}  		else  		{  			LLToolCompTranslate::getInstance()->setCurrentTool( LLToolCompTranslate::getInstance()->mSelectRect ); -			LLToolCompTranslate::getInstance()->mSelectRect->handleMouseDown( x, y, mask ); +			LLToolCompTranslate::getInstance()->mSelectRect->handlePick( pick_info );  			// *TODO: add toggle to trigger old click-drag functionality  			// LLToolCompTranslate::getInstance()->mManip->handleMouseDownOnPart( XY_part, x, y, mask); @@ -260,7 +260,7 @@ void LLToolCompTranslate::pickCallback(S32 x, S32 y, MASK mask)  	else  	{  		LLToolCompTranslate::getInstance()->setCurrentTool( LLToolCompTranslate::getInstance()->mSelectRect ); -		LLToolCompTranslate::getInstance()->mSelectRect->handleMouseDown( x, y, mask); +		LLToolCompTranslate::getInstance()->mSelectRect->handlePick( pick_info );  	}  } @@ -342,19 +342,19 @@ BOOL LLToolCompScale::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolCompScale::handleMouseDown(S32 x, S32 y, MASK mask)  {  	mMouseDown = TRUE; -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +	gViewerWindow->pickAsync(x, y, mask, pickCallback);  	return TRUE;  } -void LLToolCompScale::pickCallback(S32 x, S32 y, MASK mask) +void LLToolCompScale::pickCallback(const LLPickInfo& pick_info)  { -	LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); +	LLViewerObject* hit_obj = pick_info.getObject(); -	LLToolCompScale::getInstance()->mManip->highlightManipulators(x, y); +	LLToolCompScale::getInstance()->mManip->highlightManipulators(pick_info.mMousePt.mX, pick_info.mMousePt.mY);  	if (!LLToolCompScale::getInstance()->mMouseDown)  	{  		// fast click on object, but mouse is already up...just do select -		LLToolCompScale::getInstance()->mSelectRect->handleObjectSelection(hit_obj, mask, gSavedSettings.getBOOL("EditLinkedParts"), FALSE); +		LLToolCompScale::getInstance()->mSelectRect->handleObjectSelection(pick_info, gSavedSettings.getBOOL("EditLinkedParts"), FALSE);  		return;  	} @@ -368,18 +368,18 @@ void LLToolCompScale::pickCallback(S32 x, S32 y, MASK mask)  		if(	LLManip::LL_NO_PART != LLToolCompScale::getInstance()->mManip->getHighlightedPart() )  		{  			LLToolCompScale::getInstance()->setCurrentTool( LLToolCompScale::getInstance()->mManip ); -			LLToolCompScale::getInstance()->mManip->handleMouseDownOnPart( x, y, mask ); +			LLToolCompScale::getInstance()->mManip->handleMouseDownOnPart( pick_info.mMousePt.mX, pick_info.mMousePt.mY, pick_info.mKeyMask );  		}  		else  		{  			LLToolCompScale::getInstance()->setCurrentTool( LLToolCompScale::getInstance()->mSelectRect ); -			LLToolCompScale::getInstance()->mSelectRect->handleMouseDown( x, y, mask ); +			LLToolCompScale::getInstance()->mSelectRect->handlePick( pick_info );  		}  	}  	else  	{  		LLToolCompScale::getInstance()->setCurrentTool( LLToolCompScale::getInstance()->mSelectRect ); -		LLToolCompScale::getInstance()->mCur->handleMouseDown( x, y, mask ); +		LLToolCompScale::getInstance()->mSelectRect->handlePick( pick_info );  	}  } @@ -457,15 +457,15 @@ BOOL LLToolCompCreate::handleMouseDown(S32 x, S32 y, MASK mask)  	BOOL handled = FALSE;  	mMouseDown = TRUE; -	if ( !(mask == MASK_SHIFT) && !(mask == MASK_CONTROL) ) +	if ( (mask == MASK_SHIFT) || (mask == MASK_CONTROL) )  	{ -		setCurrentTool( mPlacer ); -		handled = mPlacer->placeObject( x, y, mask ); +		gViewerWindow->pickAsync(x, y, mask, pickCallback); +		handled = TRUE;  	}  	else  	{ -		gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); -		handled = TRUE; +		setCurrentTool( mPlacer ); +		handled = mPlacer->placeObject( x, y, mask );  	}  	mObjectPlacedOnMouseDown = TRUE; @@ -473,15 +473,15 @@ BOOL LLToolCompCreate::handleMouseDown(S32 x, S32 y, MASK mask)  	return TRUE;  } -void LLToolCompCreate::pickCallback(S32 x, S32 y, MASK mask) +void LLToolCompCreate::pickCallback(const LLPickInfo& pick_info)  {  	// *NOTE: We mask off shift and control, so you cannot  	// multi-select multiple objects with the create tool. -	mask = (mask & ~MASK_SHIFT); +	MASK mask = (pick_info.mKeyMask & ~MASK_SHIFT);  	mask = (mask & ~MASK_CONTROL);  	LLToolCompCreate::getInstance()->setCurrentTool( LLToolCompCreate::getInstance()->mSelectRect ); -	LLToolCompCreate::getInstance()->mSelectRect->handleMouseDown( x, y, mask); +	LLToolCompCreate::getInstance()->mSelectRect->handlePick( pick_info );  }  BOOL LLToolCompCreate::handleDoubleClick(S32 x, S32 y, MASK mask) @@ -543,19 +543,19 @@ BOOL LLToolCompRotate::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolCompRotate::handleMouseDown(S32 x, S32 y, MASK mask)  {  	mMouseDown = TRUE; -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +	gViewerWindow->pickAsync(x, y, mask, pickCallback);  	return TRUE;  } -void LLToolCompRotate::pickCallback(S32 x, S32 y, MASK mask) +void LLToolCompRotate::pickCallback(const LLPickInfo& pick_info)  { -	LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); +	LLViewerObject* hit_obj = pick_info.getObject(); -	LLToolCompRotate::getInstance()->mManip->highlightManipulators(x, y); +	LLToolCompRotate::getInstance()->mManip->highlightManipulators(pick_info.mMousePt.mX, pick_info.mMousePt.mY);  	if (!LLToolCompRotate::getInstance()->mMouseDown)  	{  		// fast click on object, but mouse is already up...just do select -		LLToolCompRotate::getInstance()->mSelectRect->handleObjectSelection(hit_obj, mask, gSavedSettings.getBOOL("EditLinkedParts"), FALSE); +		LLToolCompRotate::getInstance()->mSelectRect->handleObjectSelection(pick_info, gSavedSettings.getBOOL("EditLinkedParts"), FALSE);  		return;  	} @@ -568,18 +568,18 @@ void LLToolCompRotate::pickCallback(S32 x, S32 y, MASK mask)  		if(	LLManip::LL_NO_PART != LLToolCompRotate::getInstance()->mManip->getHighlightedPart() )  		{  			LLToolCompRotate::getInstance()->setCurrentTool( LLToolCompRotate::getInstance()->mManip ); -			LLToolCompRotate::getInstance()->mManip->handleMouseDownOnPart( x, y, mask ); +			LLToolCompRotate::getInstance()->mManip->handleMouseDownOnPart( pick_info.mMousePt.mX, pick_info.mMousePt.mY, pick_info.mKeyMask );  		}  		else  		{  			LLToolCompRotate::getInstance()->setCurrentTool( LLToolCompRotate::getInstance()->mSelectRect ); -			LLToolCompRotate::getInstance()->mSelectRect->handleMouseDown( x, y, mask ); +			LLToolCompRotate::getInstance()->mSelectRect->handlePick( pick_info );  		}  	}  	else  	{  		LLToolCompRotate::getInstance()->setCurrentTool( LLToolCompRotate::getInstance()->mSelectRect ); -		LLToolCompRotate::getInstance()->mCur->handleMouseDown( x, y, mask ); +		LLToolCompRotate::getInstance()->mSelectRect->handlePick( pick_info );  	}  } diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h index 8926cd34d2..5547a6d15b 100644 --- a/indra/newview/lltoolcomp.h +++ b/indra/newview/lltoolcomp.h @@ -37,6 +37,7 @@  class LLManip;  class LLToolSelectRect;  class LLToolPlacer; +class LLPickInfo;  class LLView;  class LLTextBox; @@ -114,7 +115,7 @@ public:      virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);      virtual BOOL		handleDoubleClick(S32 x, S32 y, MASK mask); -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  };  //----------------------------------------------------------------------- @@ -135,7 +136,7 @@ public:  	virtual LLTool*		getOverrideTool(MASK mask); -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  };  //----------------------------------------------------------------------- @@ -156,7 +157,7 @@ public:  	virtual LLTool*		getOverrideTool(MASK mask); -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  }; @@ -178,7 +179,7 @@ public:  	virtual LLTool*		getOverrideTool(MASK mask); -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  protected:  }; @@ -197,7 +198,7 @@ public:      virtual BOOL		handleDoubleClick(S32 x, S32 y, MASK mask);  	virtual BOOL		handleMouseUp(S32 x, S32 y, MASK mask); -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  protected:  	LLToolPlacer*		mPlacer;  	BOOL				mObjectPlacedOnMouseDown; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 940f5ba62d..109a11755b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -988,32 +988,37 @@ void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAccep  	mDrop = drop;  	if (mDrop)  	{ -		gPickFaces = TRUE;  		// don't allow drag and drop onto transparent objects -		gViewerWindow->hitObjectOrLandGlobalImmediate(x, y, pickCallback, FALSE); +		pickCallback(gViewerWindow->pickImmediate(x, y, FALSE));  	}  	else  	{ -		// Don't pick faces during hover.  Nothing currently requires per-face -		// data.  		// don't allow drag and drop onto transparent objects -		gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback, FALSE); +		gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE);  	}  	*acceptance = mLastAccept;  } -void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask) +void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info)  {  	EDropTarget target = DT_NONE;  	S32	hit_face = -1; -	LLViewerObject* hit_obj = gViewerWindow->lastNonFloraObjectHit(); +	LLViewerObject* hit_obj = pick_info.getObject();  	LLSelectMgr::getInstance()->unhighlightAll();  	// Treat attachments as part of the avatar they are attached to.  	if (hit_obj)  	{ +		// don't allow drag and drop on grass, trees, etc. +		if(pick_info.mPickType == LLPickInfo::PICK_FLORA) +		{ +			LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NO; +			gViewerWindow->getWindow()->setCursor( LLToolDragAndDrop::getInstance()->mCursor ); +			return; +		} +  		if(hit_obj->isAttachment() && !hit_obj->isHUDAttachment())  		{  			LLVOAvatar* avatar = LLVOAvatar::findAvatarFromAttachment( hit_obj ); @@ -1044,12 +1049,12 @@ void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)  		else  		{  			target = DT_OBJECT; -			hit_face = gLastHitNonFloraObjectFace; +			hit_face = pick_info.mObjectFace;  			// if any item being dragged will be applied to the object under our cursor  			// highlight that object  			for (S32 i = 0; i < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size(); i++)  			{ -				if (LLToolDragAndDrop::getInstance()->mCargoTypes[i] != DAD_OBJECT || (mask & MASK_CONTROL)) +				if (LLToolDragAndDrop::getInstance()->mCargoTypes[i] != DAD_OBJECT || (pick_info.mKeyMask & MASK_CONTROL))  				{  					LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj);  					break; @@ -1057,7 +1062,7 @@ void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)  			}  		}  	} -	else if(gLastHitLand) +	else if(pick_info.mPickType == LLPickInfo::PICK_LAND)  	{  		target = DT_LAND;  		hit_face = -1; @@ -1073,7 +1078,7 @@ void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)  			(U32)LLToolDragAndDrop::getInstance()->mLastAccept,  			(U32)callMemberFunction((*LLToolDragAndDrop::getInstance()),   				LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target]) -				(hit_obj, hit_face, mask, FALSE)); +				(hit_obj, hit_face, pick_info.mKeyMask, FALSE));  	}  	if (LLToolDragAndDrop::getInstance()->mDrop && (U32)LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_SINGLE) @@ -1095,7 +1100,7 @@ void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)  			// Call the right implementation function  			(U32)callMemberFunction((*LLToolDragAndDrop::getInstance()),   				LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target]) -				(hit_obj, hit_face, mask, TRUE); +				(hit_obj, hit_face, pick_info.mKeyMask, TRUE);  		}  	} @@ -1142,7 +1147,7 @@ void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)  		llassert( FALSE );  	} -	LLToolDragAndDrop::getInstance()->mLastHitPos = gLastHitPosGlobal + gLastHitObjectOffset; +	LLToolDragAndDrop::getInstance()->mLastHitPos = pick_info.mPosGlobal;  	LLToolDragAndDrop::getInstance()->mLastCameraPos = gAgent.getCameraPositionGlobal();  	gViewerWindow->getWindow()->setCursor( LLToolDragAndDrop::getInstance()->mCursor ); diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 8f6d1713fa..8e2788a173 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -45,6 +45,7 @@  class LLToolDragAndDrop;  class LLViewerRegion;  class LLVOAvatar; +class LLPickInfo;  class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>  { @@ -106,7 +107,7 @@ protected:  					EAcceptance* acceptance);  	void dragOrDrop3D(S32 x, S32 y, MASK mask, BOOL drop,  					  EAcceptance* acceptance); -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  protected: diff --git a/indra/newview/lltoolface.cpp b/indra/newview/lltoolface.cpp index 3248913182..138fc99606 100644 --- a/indra/newview/lltoolface.cpp +++ b/indra/newview/lltoolface.cpp @@ -82,17 +82,16 @@ BOOL LLToolFace::handleDoubleClick(S32 x, S32 y, MASK mask)  BOOL LLToolFace::handleMouseDown(S32 x, S32 y, MASK mask)  { -	gPickFaces = TRUE; -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +	gViewerWindow->pickAsync(x, y, mask, pickCallback);  	return TRUE;  } -void LLToolFace::pickCallback(S32 x, S32 y, MASK mask) +void LLToolFace::pickCallback(const LLPickInfo& pick_info)  { -	LLViewerObject* hit_obj	= gViewerWindow->lastObjectHit(); +	LLViewerObject* hit_obj	= pick_info.getObject();  	if (hit_obj)  	{ -		S32 hit_face = gLastHitObjectFace; +		S32 hit_face = pick_info.mObjectFace;  		if (hit_obj->isAvatar())  		{ @@ -102,7 +101,7 @@ void LLToolFace::pickCallback(S32 x, S32 y, MASK mask)  		// ...clicked on a world object, try to pick the appropriate face -		if (mask & MASK_SHIFT) +		if (pick_info.mKeyMask & MASK_SHIFT)  		{  			// If object not selected, need to inform sim  			if ( !hit_obj->isSelected() ) @@ -133,7 +132,7 @@ void LLToolFace::pickCallback(S32 x, S32 y, MASK mask)  	}  	else  	{ -		if (!(mask == MASK_SHIFT)) +		if (!(pick_info.mKeyMask == MASK_SHIFT))  		{  			LLSelectMgr::getInstance()->deselectAll();  		} diff --git a/indra/newview/lltoolface.h b/indra/newview/lltoolface.h index f573bfa9c5..113dcc9fbd 100644 --- a/indra/newview/lltoolface.h +++ b/indra/newview/lltoolface.h @@ -35,6 +35,7 @@  #include "lltool.h"  class LLViewerObject; +class LLPickInfo;  class LLToolFace  :	public LLTool, public LLSingleton<LLToolFace> @@ -49,7 +50,7 @@ public:  	virtual void	handleDeselect();  	virtual void	render();			// draw face highlights -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  };  #endif diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index b46d25583a..3fdf24bbc3 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -126,28 +126,28 @@ BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)  	gViewerWindow->hideCursor(); -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +	gViewerWindow->pickAsync(x, y, mask, pickCallback);  	// don't steal focus from UI  	return FALSE;  } -void LLToolCamera::pickCallback(S32 x, S32 y, MASK mask) +void LLToolCamera::pickCallback(const LLPickInfo& pick_info)  {  	if (!LLToolCamera::getInstance()->hasMouseCapture())  	{  		return;  	} -	LLToolCamera::getInstance()->mMouseDownX = x; -	LLToolCamera::getInstance()->mMouseDownY = y; +	LLToolCamera::getInstance()->mMouseDownX = pick_info.mMousePt.mX; +	LLToolCamera::getInstance()->mMouseDownY = pick_info.mMousePt.mY;  	gViewerWindow->moveCursorToCenter();  	// Potentially recenter if click outside rectangle -	LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); +	LLViewerObject* hit_obj = pick_info.getObject();  	// Check for hit the sky, or some other invalid point -	if (!hit_obj && gLastHitPosGlobal.isExactlyZero()) +	if (!hit_obj && pick_info.mPosGlobal.isExactlyZero())  	{  		LLToolCamera::getInstance()->mValidClickPoint = FALSE;  		return; @@ -195,29 +195,27 @@ void LLToolCamera::pickCallback(S32 x, S32 y, MASK mask)  		}  	}  	//RN: check to see if this is mouse-driving as opposed to ALT-zoom or Focus tool -	else if (mask & MASK_ALT ||  +	else if (pick_info.mKeyMask & MASK_ALT ||   			(LLToolMgr::getInstance()->getCurrentTool()->getName() == "Camera"))   	{ -		LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); +		LLViewerObject* hit_obj = pick_info.getObject();  		if (hit_obj)  		{  			// ...clicked on a world object, so focus at its position -			// Use "gLastHitPosGlobal" because it's correct for avatar heads, -			// not pelvis.  			if (!hit_obj->isHUDAttachment())  			{  				gAgent.setFocusOnAvatar(FALSE, ANIMATE); -				gAgent.setFocusGlobal( gLastHitObjectOffset + gLastHitPosGlobal, gLastHitObjectID); +				gAgent.setFocusGlobal(pick_info);  			}  		} -		else if (!gLastHitPosGlobal.isExactlyZero()) +		else if (!pick_info.mPosGlobal.isExactlyZero())  		{  			// Hit the ground  			gAgent.setFocusOnAvatar(FALSE, ANIMATE); -			gAgent.setFocusGlobal( gLastHitPosGlobal, gLastHitObjectID); +			gAgent.setFocusGlobal(pick_info);  		} -		if (!(mask & MASK_ALT) && +		if (!(pick_info.mKeyMask & MASK_ALT) &&  			gAgent.cameraThirdPerson() &&  			gViewerWindow->getLeftMouseDown() &&   			!gSavedSettings.getBOOL("FreezeTime") && @@ -238,7 +236,7 @@ void LLToolCamera::pickCallback(S32 x, S32 y, MASK mask)  		LLVector3d cam_pos = gAgent.getCameraPositionGlobal();  		cam_pos -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * gAgent.calcCustomizeAvatarUIOffset( cam_pos )); -		gAgent.setCameraPosAndFocusGlobal( cam_pos, gLastHitObjectOffset + gLastHitPosGlobal, gLastHitObjectID); +		gAgent.setCameraPosAndFocusGlobal( cam_pos, pick_info.mPosGlobal, pick_info.mObjectID);  	}  } diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h index 2ed456b188..c8c748a1b0 100644 --- a/indra/newview/lltoolfocus.h +++ b/indra/newview/lltoolfocus.h @@ -34,6 +34,8 @@  #include "lltool.h" +class LLPickInfo; +  class LLToolCamera  :	public LLTool, public LLSingleton<LLToolCamera>  { @@ -52,7 +54,7 @@ public:  	virtual LLTool*	getOverrideTool(MASK mask) { return NULL; } -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  	BOOL mouseSteerMode() { return mMouseSteering; }  protected: diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index a41e9381f6..13037c6a20 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -78,16 +78,6 @@ LLToolGrab::LLToolGrab( LLToolComposite* composite )  :	LLTool( std::string("Grab"), composite ),  	mMode( GRAB_INACTIVE ),  	mVerticalDragging( FALSE ), -	mHitLand(FALSE), -	mHitObjectID(), -	mGrabObject( NULL ), -	mLastMouseX(0), -	mLastMouseY(0), -	mMouseDownX( -1 ), -	mMouseDownY( -1 ), -	mMouseMask(0), -	mAccumDeltaX(0), -	mAccumDeltaY(0),  	mHasMoved( FALSE ),  	mOutsideSlop(FALSE),  	mDeselectedThisClick(FALSE), @@ -138,24 +128,23 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask)  		llinfos << "LLToolGrab handleMouseDown" << llendl;  	} -	mHitLand = FALSE; -  	// call the base class to propogate info to sim  	LLTool::handleMouseDown(x, y, mask);  	if (!gAgent.leftButtonGrabbed())  	{  		// can grab transparent objects (how touch event propagates, scripters rely on this) -		gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback, TRUE); +		gViewerWindow->pickAsync(x, y, mask, pickCallback, TRUE);  	}  	return TRUE;  } -void LLToolGrab::pickCallback(S32 x, S32 y, MASK mask) +void LLToolGrab::pickCallback(const LLPickInfo& pick_info)  { -	LLViewerObject	*objectp = gObjectList.findObject( gLastHitObjectID ); +	LLToolGrab::getInstance()->mGrabPick = pick_info; +	LLViewerObject	*objectp = pick_info.getObject(); -	BOOL extend_select = (mask & MASK_SHIFT); +	BOOL extend_select = (pick_info.mKeyMask & MASK_SHIFT);  	if (!extend_select && !LLSelectMgr::getInstance()->getSelection()->isEmpty())  	{ @@ -172,23 +161,22 @@ void LLToolGrab::pickCallback(S32 x, S32 y, MASK mask)  	{  		LLToolGrab::getInstance()->setMouseCapture(TRUE);  		LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT; -		LLToolGrab::getInstance()->mHitObjectID.setNull(); +		LLToolGrab::getInstance()->mGrabPick.mObjectID.setNull();  	}  	else  	{ -		LLToolGrab::getInstance()->handleObjectHit(objectp, x, y, mask); +		LLToolGrab::getInstance()->handleObjectHit(LLToolGrab::getInstance()->mGrabPick);  	}  } -BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mask) +BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)  { -	mMouseDownX = x; -	mMouseDownY = y; -	mMouseMask = mask; +	mGrabPick = info; +	LLViewerObject* objectp = mGrabPick.getObject();  	if (gDebugClicks)  	{ -		llinfos << "LLToolGrab handleObjectHit " << mMouseDownX << "," << mMouseDownY << llendl; +		llinfos << "LLToolGrab handleObjectHit " << info.mMousePt.mX << "," << info.mMousePt.mY << llendl;  	}  	if (NULL == objectp) // unexpected @@ -209,8 +197,6 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas  	setMouseCapture( TRUE ); -	mHitObjectID = objectp->getID(); -  	// Grabs always start from the root  	// objectp = (LLViewerObject *)objectp->getRoot(); @@ -230,13 +216,13 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas  		if (gAgent.cameraMouselook() && !script_touch)  		{  			mMode = GRAB_LOCKED; +			gViewerWindow->hideCursor(); +			gViewerWindow->moveCursorToCenter();  		}  		else  		{  			mMode = GRAB_NONPHYSICAL;  		} -		gViewerWindow->hideCursor(); -		gViewerWindow->moveCursorToCenter();  		// Don't bail out here, go on and grab so buttons can get  		// their "touched" event.  	} @@ -261,20 +247,18 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas  	// Always send "touched" message +	mLastMouseX = gViewerWindow->getCurrentMouseX(); +	mLastMouseY = gViewerWindow->getCurrentMouseY();  	mAccumDeltaX = 0;  	mAccumDeltaY = 0;  	mHasMoved = FALSE;  	mOutsideSlop = FALSE; -	mGrabObject = objectp; +	mVerticalDragging = (info.mKeyMask == MASK_VERTICAL) || gGrabBtnVertical; -	mGrabOffset.clearVec(); +	startGrab(); -	mVerticalDragging = (mask == MASK_VERTICAL) || gGrabBtnVertical; - -	startGrab(x, y); - -	if ((mask == MASK_SPIN) || gGrabBtnSpin) +	if ((info.mKeyMask == MASK_SPIN) || gGrabBtnSpin)  	{  		startSpin();  	} @@ -282,10 +266,10 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas  	LLSelectMgr::getInstance()->updateSelectionCenter();		// update selection beam  	// update point at -	LLViewerObject *edit_object = gObjectList.findObject(mHitObjectID); -	if (edit_object) +	LLViewerObject *edit_object = info.getObject(); +	if (edit_object && info.mPickType != LLPickInfo::PICK_FLORA)  	{ -		LLVector3 local_edit_point = gAgent.getPosAgentFromGlobal(gLastHitNonFloraPosGlobal); +		LLVector3 local_edit_point = gAgent.getPosAgentFromGlobal(info.mPosGlobal);  		local_edit_point -= edit_object->getPositionAgent();  		local_edit_point = local_edit_point * ~edit_object->getRenderRotation();  		gAgent.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point ); @@ -307,10 +291,15 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas  void LLToolGrab::startSpin()  { +	LLViewerObject* objectp = mGrabPick.getObject(); +	if (!objectp) +	{ +		return; +	}  	mSpinGrabbing = TRUE;  	// Was saveSelectedObjectTransform() -	LLViewerObject *root = (LLViewerObject *)mGrabObject->getRoot(); +	LLViewerObject *root = (LLViewerObject *)objectp->getRoot();  	mSpinRotation = root->getRotation();  	LLMessageSystem *msg = gMessageSystem; @@ -319,8 +308,8 @@ void LLToolGrab::startSpin()  	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );  	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  	msg->nextBlockFast(_PREHASH_ObjectData); -	msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() ); -	msg->sendMessage( mGrabObject->getRegion()->getHost() ); +	msg->addUUIDFast(_PREHASH_ObjectID, mGrabPick.mObjectID ); +	msg->sendMessage( objectp->getRegion()->getHost() );  } @@ -328,6 +317,12 @@ void LLToolGrab::stopSpin()  {  	mSpinGrabbing = FALSE; +	LLViewerObject* objectp = mGrabPick.getObject(); +	if (!objectp) +	{ +		return; +	} +  	LLMessageSystem *msg = gMessageSystem;  	switch(mMode)  	{ @@ -339,8 +334,8 @@ void LLToolGrab::stopSpin()  		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );  		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  		msg->nextBlockFast(_PREHASH_ObjectData); -		msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() ); -		msg->sendMessage( mGrabObject->getRegion()->getHost() ); +		msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() ); +		msg->sendMessage( objectp->getRegion()->getHost() );  		break;  	case GRAB_NOOBJECT: @@ -352,11 +347,17 @@ void LLToolGrab::stopSpin()  } -void LLToolGrab::startGrab(S32 x, S32 y) +void LLToolGrab::startGrab()  {  	// Compute grab_offset in the OBJECT's root's coordinate frame  	// (sometimes root == object) -	LLViewerObject *root = (LLViewerObject *)mGrabObject->getRoot(); +	LLViewerObject* objectp = mGrabPick.getObject(); +	if (!objectp) +	{ +		return; +	} + +	LLViewerObject *root = (LLViewerObject *)objectp->getRoot();  	// drag from center  	LLVector3d grab_start_global = root->getPositionGlobal(); @@ -365,7 +366,7 @@ void LLToolGrab::startGrab(S32 x, S32 y)  	// JC - This code looks wonky, but I believe it does the right thing.  	// Otherwise, when you grab a linked object set, it "pops" on the start  	// of the drag. -	LLVector3d grab_offsetd = root->getPositionGlobal() - mGrabObject->getPositionGlobal(); +	LLVector3d grab_offsetd = root->getPositionGlobal() - objectp->getPositionGlobal();  	LLVector3 grab_offset;  	grab_offset.setVec(grab_offsetd); @@ -384,9 +385,16 @@ void LLToolGrab::startGrab(S32 x, S32 y)  	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());  	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  	msg->nextBlockFast(_PREHASH_ObjectData); -	msg->addU32Fast(_PREHASH_LocalID, mGrabObject->mLocalID); +	msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID);  	msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset ); -	msg->sendMessage( mGrabObject->getRegion()->getHost()); +	msg->nextBlock("SurfaceInfo"); +	msg->addVector3("UVCoord", LLVector3(mGrabPick.mUVCoords)); +	msg->addVector3("STCoord", LLVector3(mGrabPick.mSTCoords)); +	msg->addS32Fast(_PREHASH_FaceIndex, mGrabPick.mObjectFace); +	msg->addVector3("Position", mGrabPick.mIntersection); +	msg->addVector3("Normal", mGrabPick.mNormal); +	msg->addVector3("Binormal", mGrabPick.mBinormal); +	msg->sendMessage( objectp->getRegion()->getHost());  	mGrabOffsetFromCenterInitial = grab_offset;  	mGrabHiddenOffsetFromCamera = mDragStartFromCamera; @@ -397,9 +405,6 @@ void LLToolGrab::startGrab(S32 x, S32 y)  BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)  { -	mLastMouseX = x; -	mLastMouseY = y; -  	if (!gViewerWindow->getLeftMouseDown())  	{  		gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB); @@ -411,9 +416,12 @@ BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)  	switch( mMode )  	{  	case GRAB_ACTIVE_CENTER: -	case GRAB_NONPHYSICAL:  		handleHoverActive( x, y, mask );	// cursor hidden  		break; +		 +	case GRAB_NONPHYSICAL: +		handleHoverNonPhysical(x, y, mask); +		break;  	case GRAB_INACTIVE:  		handleHoverInactive( x, y, mask );  // cursor set here @@ -426,18 +434,24 @@ BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)  	} +	mLastMouseX = x; +	mLastMouseY = y; +	  	return TRUE;  } +const F32 GRAB_SENSITIVITY_X = 0.0075f; +const F32 GRAB_SENSITIVITY_Y = 0.0075f; +  // Dragging.  void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  { -	llassert( hasMouseCapture() ); -	llassert( mGrabObject ); -	if (mGrabObject->isDead()) +	LLViewerObject* objectp = mGrabPick.getObject(); +	if (!objectp || !hasMouseCapture() ) return; +	if (objectp->isDead())  	{  		// Bail out of drag because object has been killed  		setMouseCapture(FALSE); @@ -466,7 +480,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  		// ...switch to horizontal dragging  		mVerticalDragging = FALSE; -		mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, mGrabObject); +		mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, objectp);  		mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();  	}  	else if (!mVerticalDragging && (mask == MASK_VERTICAL) ) @@ -474,16 +488,13 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  		// ...switch to vertical dragging  		mVerticalDragging = TRUE; -		mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, mGrabObject); +		mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, objectp);  		mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();  	}  	const F32 RADIANS_PER_PIXEL_X = 0.01f;  	const F32 RADIANS_PER_PIXEL_Y = 0.01f; -	const F32 SENSITIVITY_X = 0.0075f; -	const F32 SENSITIVITY_Y = 0.0075f; -  	S32 dx = x - (gViewerWindow->getWindowWidth() / 2);  	S32 dy = y - (gViewerWindow->getWindowHeight() / 2); @@ -525,9 +536,9 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );  			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  			msg->nextBlockFast(_PREHASH_ObjectData); -			msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() ); +			msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() );  			msg->addQuatFast(_PREHASH_Rotation, mSpinRotation ); -			msg->sendMessage( mGrabObject->getRegion()->getHost() ); +			msg->sendMessage( objectp->getRegion()->getHost() );  		}  		else  		{ @@ -555,8 +566,8 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  			}  			mGrabHiddenOffsetFromCamera = mGrabHiddenOffsetFromCamera  -				+ (x_part * (-dx * SENSITIVITY_X))  -				+ (y_part * ( dy * SENSITIVITY_Y)); +				+ (x_part * (-dx * GRAB_SENSITIVITY_X))  +				+ (y_part * ( dy * GRAB_SENSITIVITY_Y));  			// Send the message to the viewer. @@ -640,7 +651,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  				&& (grab_center_gl.mY > 24))  			{  				// Transmit update to simulator -				LLVector3 grab_pos_region = mGrabObject->getRegion()->getPosRegionFromGlobal( grab_point_global ); +				LLVector3 grab_pos_region = objectp->getRegion()->getPosRegionFromGlobal( grab_point_global );  				LLMessageSystem *msg = gMessageSystem;  				msg->newMessageFast(_PREHASH_ObjectGrabUpdate); @@ -648,11 +659,19 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());  				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  				msg->nextBlockFast(_PREHASH_ObjectData); -				msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() ); +				msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() );  				msg->addVector3Fast(_PREHASH_GrabOffsetInitial, mGrabOffsetFromCenterInitial );  				msg->addVector3Fast(_PREHASH_GrabPosition, grab_pos_region );  				msg->addU32Fast(_PREHASH_TimeSinceLast, dt_milliseconds ); -				msg->sendMessage( mGrabObject->getRegion()->getHost() ); +				msg->nextBlock("SurfaceInfo"); +				msg->addVector3("UVCoord", LLVector3(mGrabPick.mUVCoords)); +				msg->addVector3("STCoord", LLVector3(mGrabPick.mSTCoords)); +				msg->addS32Fast(_PREHASH_FaceIndex, mGrabPick.mObjectFace); +				msg->addVector3("Position", mGrabPick.mIntersection); +				msg->addVector3("Normal", mGrabPick.mNormal); +				msg->addVector3("Binormal", mGrabPick.mBinormal); + +				msg->sendMessage( objectp->getRegion()->getHost() );  			}  		} @@ -666,8 +685,8 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  	if (mHasMoved)  	{  		if (!gAgent.cameraMouselook() &&  -			!mGrabObject->isHUDAttachment() &&  -			mGrabObject->getRoot() == gAgent.getAvatarObject()->getRoot()) +			!objectp->isHUDAttachment() &&  +			objectp->getRoot() == gAgent.getAvatarObject()->getRoot())  		{  			// force focus to point in space where we were looking previously  			gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null); @@ -686,6 +705,134 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)  } +void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask) +{ +	LLViewerObject* objectp = mGrabPick.getObject(); +	if (!objectp || !hasMouseCapture() ) return; +	if (objectp->isDead()) +	{ +		// Bail out of drag because object has been killed +		setMouseCapture(FALSE); +		return; +	} + +	LLPickInfo pick = mGrabPick; +	pick.mMousePt = LLCoordGL(x, y); +	pick.getSurfaceInfo(); + +	// compute elapsed time +	F32 dt = mGrabTimer.getElapsedTimeAndResetF32(); +	U32 dt_milliseconds = (U32) (1000.f * dt); + +	// i'm not a big fan of the following code - it's been culled from the physical grab case. +	// ideally these two would be nicely integrated - but the code in that method is a serious +	// mess of spaghetti.  so here we go: + +	LLVector3 grab_pos_region(0,0,0); +	 +	const BOOL SUPPORT_LLDETECTED_GRAB = TRUE; +	if (SUPPORT_LLDETECTED_GRAB) +	{ +		//-------------------------------------------------- +		// Toggle vertical dragging +		//-------------------------------------------------- +		if (mVerticalDragging && !(mask == MASK_VERTICAL) && !gGrabBtnVertical) +		{ +			mVerticalDragging = FALSE; +		} +	 +		else if (!mVerticalDragging && (mask == MASK_VERTICAL) ) +		{ +			mVerticalDragging = TRUE; +		} +	 +		S32 dx = x - mLastMouseX; +		S32 dy = y - mLastMouseY; + +		if (dx != 0 || dy != 0) +		{ +			mAccumDeltaX += dx; +			mAccumDeltaY += dy; +		 +			S32 dist_sq = mAccumDeltaX * mAccumDeltaX + mAccumDeltaY * mAccumDeltaY; +			if (dist_sq > SLOP_DIST_SQ) +			{ +				mOutsideSlop = TRUE; +			} + +			// mouse has moved  +			mHasMoved = TRUE; + +			//------------------------------------------------------ +			// Handle grabbing +			//------------------------------------------------------ + +			LLVector3d x_part; +			x_part.setVec(LLViewerCamera::getInstance()->getLeftAxis()); +			x_part.mdV[VZ] = 0.0; +			x_part.normVec(); + +			LLVector3d y_part; +			if( mVerticalDragging ) +			{ +				y_part.setVec(LLViewerCamera::getInstance()->getUpAxis()); +				// y_part.setVec(0.f, 0.f, 1.f); +			} +			else +			{ +				// drag toward camera +				y_part = x_part % LLVector3d::z_axis; +				y_part.mdV[VZ] = 0.0; +				y_part.normVec(); +			} + +			mGrabHiddenOffsetFromCamera = mGrabHiddenOffsetFromCamera  +				+ (x_part * (-dx * GRAB_SENSITIVITY_X))  +				+ (y_part * ( dy * GRAB_SENSITIVITY_Y)); + +		} +		 +		// need to return offset from mGrabStartPoint +		LLVector3d grab_point_global = gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera; +		grab_pos_region = objectp->getRegion()->getPosRegionFromGlobal( grab_point_global ); +	} + +	LLMessageSystem *msg = gMessageSystem; +	msg->newMessageFast(_PREHASH_ObjectGrabUpdate); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	msg->nextBlockFast(_PREHASH_ObjectData); +	msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() ); +	msg->addVector3Fast(_PREHASH_GrabOffsetInitial, mGrabOffsetFromCenterInitial ); +	msg->addVector3Fast(_PREHASH_GrabPosition, grab_pos_region ); +	msg->addU32Fast(_PREHASH_TimeSinceLast, dt_milliseconds ); +	msg->nextBlock("SurfaceInfo"); +	msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); +	msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); +	msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); +	msg->addVector3("Position", pick.mIntersection); +	msg->addVector3("Normal", pick.mNormal); +	msg->addVector3("Binormal", pick.mBinormal); + +	msg->sendMessage( objectp->getRegion()->getHost() ); + +	// update point-at / look-at +	if (pick.mObjectFace != -1) // if the intersection was on the surface of the obejct +	{ +		LLVector3 local_edit_point = pick.mIntersection; +		local_edit_point -= objectp->getPositionAgent(); +		local_edit_point = local_edit_point * ~objectp->getRenderRotation(); +		gAgent.setPointAt(POINTAT_TARGET_GRAB, objectp, local_edit_point ); +		gAgent.setLookAt(LOOKAT_TARGET_SELECT, objectp, local_edit_point ); +	} +	 +	 +	 +	gViewerWindow->setCursor(UI_CURSOR_HAND);   +} +  +  // Not dragging.  Just showing affordances  void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)  { @@ -726,7 +873,7 @@ void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask)  	}  	else  	{ -		S32 dist_sq = (x-mMouseDownX) * (x-mMouseDownX) + (y-mMouseDownY) * (y-mMouseDownY); +		S32 dist_sq = (x-mGrabPick.mMousePt.mX) * (x-mGrabPick.mMousePt.mX) + (y-mGrabPick.mMousePt.mY) * (y-mGrabPick.mMousePt.mY);  		if( mOutsideSlop || dist_sq > SLOP_DIST_SQ )  		{  			mOutsideSlop = TRUE; @@ -791,23 +938,27 @@ void LLToolGrab::stopEditing()  void LLToolGrab::onMouseCaptureLost()  { +	LLViewerObject* objectp = mGrabPick.getObject(); +	if (!objectp) +	{ +		gViewerWindow->showCursor(); +		return; +	}  	// First, fix cursor placement  	if( !gAgent.cameraMouselook()  -		&& (GRAB_ACTIVE_CENTER == mMode || GRAB_NONPHYSICAL == mMode)) +		&& (GRAB_ACTIVE_CENTER == mMode))  	{ -		llassert( mGrabObject );  - -		if (mGrabObject->isHUDAttachment()) +		if (objectp->isHUDAttachment())  		{  			// ...move cursor "naturally", as if it had moved when hidden -			S32 x = mMouseDownX + mAccumDeltaX; -			S32 y = mMouseDownY + mAccumDeltaY; +			S32 x = mGrabPick.mMousePt.mX + mAccumDeltaX; +			S32 y = mGrabPick.mMousePt.mY + mAccumDeltaY;  			LLUI::setCursorPositionScreen(x, y);  		}  		else if (mHasMoved)  		{  			// ...move cursor back to the center of the object -			LLVector3 grab_point_agent = mGrabObject->getRenderPosition(); +			LLVector3 grab_point_agent = objectp->getRenderPosition();  			LLCoordGL gl_point;  			if (LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_point_agent, gl_point)) @@ -818,19 +969,21 @@ void LLToolGrab::onMouseCaptureLost()  		else  		{  			// ...move cursor back to click position -			LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY); +			LLUI::setCursorPositionScreen(mGrabPick.mMousePt.mX, mGrabPick.mMousePt.mY);  		}  		gViewerWindow->showCursor();  	}  	stopGrab(); +	if (mSpinGrabbing)  	stopSpin(); +	  	mMode = GRAB_INACTIVE;  	mHideBuildHighlight = FALSE; -	mGrabObject = NULL; +	mGrabPick.mObjectID.setNull();  	LLSelectMgr::getInstance()->updateSelectionCenter();  	gAgent.setPointAt(POINTAT_TARGET_CLEAR); @@ -842,6 +995,24 @@ void LLToolGrab::onMouseCaptureLost()  void LLToolGrab::stopGrab()  { +	LLViewerObject* objectp = mGrabPick.getObject(); +	if (!objectp) +	{ +		return; +	} + +	LLPickInfo pick = mGrabPick; + +	if (mMode == GRAB_NONPHYSICAL) +	{ +		// for non-physical (touch) grabs, +		// gather surface info for this degrab (mouse-up) +		S32 x = gViewerWindow->getCurrentMouseX(); +		S32 y = gViewerWindow->getCurrentMouseY(); +		pick.mMousePt = LLCoordGL(x, y); +		pick.getSurfaceInfo(); +	} +  	// Next, send messages to simulator  	LLMessageSystem *msg = gMessageSystem;  	switch(mMode) @@ -854,11 +1025,18 @@ void LLToolGrab::stopGrab()  		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());  		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  		msg->nextBlockFast(_PREHASH_ObjectData); -		msg->addU32Fast(_PREHASH_LocalID, mGrabObject->mLocalID); -		msg->sendMessage(mGrabObject->getRegion()->getHost()); +		msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID); +		msg->nextBlock("SurfaceInfo"); +		msg->addVector3("UVCoord", LLVector3(mGrabPick.mUVCoords)); +		msg->addVector3("STCoord", LLVector3(mGrabPick.mSTCoords)); +		msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); +		msg->addVector3("Position", pick.mIntersection); +		msg->addVector3("Normal", pick.mNormal); +		msg->addVector3("Binormal", pick.mBinormal); + +		msg->sendMessage(objectp->getRegion()->getHost());  		mVerticalDragging = FALSE; -		mGrabOffset.clearVec();  		break;  	case GRAB_NOOBJECT: @@ -880,14 +1058,12 @@ void LLToolGrab::render()  BOOL LLToolGrab::isEditing()  { -	// Can't just compare to null directly due to "smart" pointer. -	LLViewerObject *obj = mGrabObject; -	return (obj != NULL); +	return (mGrabPick.getObject().notNull());  }  LLViewerObject* LLToolGrab::getEditingObject()  { -	return mGrabObject; +	return mGrabPick.getObject();  } diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index d744c495a5..696ce0742a 100644 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -37,10 +37,12 @@  #include "llquaternion.h"  #include "llmemory.h"  #include "lluuid.h" +#include "llviewerwindow.h" // for LLPickInfo  class LLView;  class LLTextBox;  class LLViewerObject; +class LLPickInfo;  class LLToolGrab : public LLTool, public LLSingleton<LLToolGrab>  { @@ -69,15 +71,15 @@ public:  	LLVector3		getGrabOffset(S32 x, S32 y);		// HACK  	// Capture the mouse and start grabbing. -	BOOL			handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mask); +	BOOL			handleObjectHit(const LLPickInfo& info);  	// Certain grabs should not highlight the "Build" toolbar button  	BOOL getHideBuildHighlight() { return mHideBuildHighlight; } -	static void		pickCallback(S32 x, S32 y, MASK mask); +	static void		pickCallback(const LLPickInfo& pick_info);  private:  	LLVector3d		getGrabPointGlobal(); -	void			startGrab(S32 x, S32 y); +	void			startGrab();  	void			stopGrab();  	void			startSpin(); @@ -85,6 +87,7 @@ private:  	void			handleHoverSpin(S32 x, S32 y, MASK mask);  	void			handleHoverActive(S32 x, S32 y, MASK mask); +	void			handleHoverNonPhysical(S32 x, S32 y, MASK mask);  	void			handleHoverInactive(S32 x, S32 y, MASK mask);  	void			handleHoverFailed(S32 x, S32 y, MASK mask); @@ -96,29 +99,26 @@ private:  	BOOL			mVerticalDragging;  	BOOL			mHitLand; -	LLUUID			mHitObjectID;				// if hit something, its ID -	LLPointer<LLViewerObject>	mGrabObject;					// the object currently being grabbed  	LLTimer			mGrabTimer;						// send simulator time between hover movements  	LLVector3		mGrabOffsetFromCenterInitial;	// meters from CG of object -	LLVector3		mGrabOffset;					// how far cursor currently is from grab start point, meters  	LLVector3d		mGrabHiddenOffsetFromCamera;	// in cursor hidden drag, how far is grab offset from camera  	LLVector3d		mDragStartPointGlobal;				// projected into world  	LLVector3d		mDragStartFromCamera;			// drag start relative to camera +	LLPickInfo		mGrabPick; +  	S32				mLastMouseX;  	S32				mLastMouseY; -	S32				mMouseDownX; -	S32				mMouseDownY; -	MASK			mMouseMask;  	S32				mAccumDeltaX;	// since cursor hidden, how far have you moved?  	S32				mAccumDeltaY;  	BOOL			mHasMoved;		// has mouse moved off center at all?  	BOOL			mOutsideSlop;	// has mouse moved outside center 5 pixels?  	BOOL			mDeselectedThisClick; +  	BOOL			mSpinGrabbing;  	LLQuaternion	mSpinRotation; @@ -131,3 +131,4 @@ extern LLTool* gGrabTransientTool;  #endif  // LL_TOOLGRAB_H + diff --git a/indra/newview/lltoolindividual.cpp b/indra/newview/lltoolindividual.cpp index 3fa96cd84a..0e0524daa6 100644 --- a/indra/newview/lltoolindividual.cpp +++ b/indra/newview/lltoolindividual.cpp @@ -72,13 +72,13 @@ LLToolIndividual::~LLToolIndividual()  BOOL LLToolIndividual::handleMouseDown(S32 x, S32 y, MASK mask)  { -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +	gViewerWindow->pickAsync(x, y, mask, pickCallback);  	return TRUE;  } -void LLToolIndividual::pickCallback(S32 x, S32 y, MASK mask) +void LLToolIndividual::pickCallback(const LLPickInfo& pick_info)  { -	LLViewerObject* obj = gViewerWindow->lastObjectHit(); +	LLViewerObject* obj = pick_info.getObject();  	LLSelectMgr::getInstance()->deselectAll();  	if(obj)  	{ diff --git a/indra/newview/lltoolindividual.h b/indra/newview/lltoolindividual.h index 48a2365363..913e4ff2b8 100644 --- a/indra/newview/lltoolindividual.h +++ b/indra/newview/lltoolindividual.h @@ -34,6 +34,8 @@  #include "lltool.h" +class LLPickInfo; +  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class lltoolindividual  // @@ -52,7 +54,7 @@ public:  	//virtual void handleDeselect();  	//virtual void render(); -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  protected: diff --git a/indra/newview/lltoolobjpicker.cpp b/indra/newview/lltoolobjpicker.cpp index 67e0db962f..ee9c24f269 100644 --- a/indra/newview/lltoolobjpicker.cpp +++ b/indra/newview/lltoolobjpicker.cpp @@ -69,7 +69,7 @@ BOOL LLToolObjPicker::handleMouseDown(S32 x, S32 y, MASK mask)  	if (! handled)  	{  		// didn't click in any UI object, so must have clicked in the world -		gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +		gViewerWindow->pickAsync(x, y, mask, pickCallback);  		handled = TRUE;  	}  	else @@ -90,16 +90,10 @@ BOOL LLToolObjPicker::handleMouseDown(S32 x, S32 y, MASK mask)  	return handled;  } -void LLToolObjPicker::pickCallback(S32 x, S32 y, MASK mask) +void LLToolObjPicker::pickCallback(const LLPickInfo& pick_info)  { -	// You must hit the body for this tool to think you hit the object. -	LLViewerObject*	objectp = NULL; -	objectp = gObjectList.findObject( gLastHitObjectID ); -	if (objectp) -	{ -		LLToolObjPicker::getInstance()->mHitObjectID = objectp->mID; -		LLToolObjPicker::getInstance()->mPicked = TRUE; -	} +	LLToolObjPicker::getInstance()->mHitObjectID = pick_info.mObjectID; +	LLToolObjPicker::getInstance()->mPicked = pick_info.mObjectID.notNull();  } @@ -181,3 +175,4 @@ void LLToolObjPicker::handleDeselect()  } + diff --git a/indra/newview/lltoolobjpicker.h b/indra/newview/lltoolobjpicker.h index 794d035a83..8d0c87c8ae 100644 --- a/indra/newview/lltoolobjpicker.h +++ b/indra/newview/lltoolobjpicker.h @@ -36,6 +36,8 @@  #include "v3math.h"  #include "lluuid.h" +class LLPickInfo; +  class LLToolObjPicker : public LLTool, public LLSingleton<LLToolObjPicker>  {  public: @@ -54,7 +56,7 @@ public:  	LLUUID				getObjectID() const { return mHitObjectID; } -	static void			pickCallback(S32 x, S32 y, MASK mask); +	static void			pickCallback(const LLPickInfo& pick_info);  protected:  	BOOL				mPicked; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index b6bcf9544d..b444cb8ce6 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -84,50 +84,48 @@ LLToolPie::LLToolPie()  :	LLTool(std::string("Select")),  	mPieMouseButtonDown( FALSE ),  	mGrabMouseButtonDown( FALSE ), -	mHitLand( FALSE ), -	mHitObjectID(),  	mMouseOutsideSlop( FALSE )  { }  BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)  { -	gPickFaces = TRUE;  	//left mouse down always picks transparent -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, leftMouseCallback,  -											  TRUE, TRUE); +	gViewerWindow->pickAsync(x, y, mask, leftMouseCallback, TRUE, TRUE);  	mGrabMouseButtonDown = TRUE;  	return TRUE;  }  // static -void LLToolPie::leftMouseCallback(S32 x, S32 y, MASK mask) +void LLToolPie::leftMouseCallback(const LLPickInfo& pick_info)  { -	LLToolPie::getInstance()->pickAndShowMenu(x, y, mask, FALSE); +	LLToolPie::getInstance()->mPick = pick_info; +	LLToolPie::getInstance()->pickAndShowMenu(FALSE);  }  BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)  { -	// Pick faces in case they select "Copy Texture" and need that info. -	gPickFaces = TRUE;  	// don't pick transparent so users can't "pay" transparent objects -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, rightMouseCallback, -											  FALSE, TRUE); +	gViewerWindow->pickAsync(x, y, mask, rightMouseCallback, FALSE);  	mPieMouseButtonDown = TRUE;   	// don't steal focus from UI  	return FALSE;  }  // static -void LLToolPie::rightMouseCallback(S32 x, S32 y, MASK mask) +void LLToolPie::rightMouseCallback(const LLPickInfo& pick_info)  { -	LLToolPie::getInstance()->pickAndShowMenu(x, y, mask, TRUE); +	LLToolPie::getInstance()->mPick = pick_info; +	LLToolPie::getInstance()->pickAndShowMenu(TRUE);  }  // True if you selected an object. -BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show) +BOOL LLToolPie::pickAndShowMenu(BOOL always_show)  { -	if (!always_show && gLastHitParcelWall) +	S32 x = mPick.mMousePt.mX; +	S32 y = mPick.mMousePt.mY; +	MASK mask = mPick.mKeyMask; +	if (!always_show && mPick.mPickType == LLPickInfo::PICK_PARCEL_WALL)  	{  		LLParcel* parcel = LLViewerParcelMgr::getInstance()->getCollisionParcel();  		if (parcel) @@ -151,25 +149,18 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show)  	}  	// didn't click in any UI object, so must have clicked in the world -	LLViewerObject *object = gViewerWindow->lastObjectHit(); +	LLViewerObject *object = mPick.getObject();  	LLViewerObject *parent = NULL; -	mHitLand = !object && !gLastHitPosGlobal.isExactlyZero(); -	if (!mHitLand) +	if (mPick.mPickType != LLPickInfo::PICK_LAND)  	{  		LLViewerParcelMgr::getInstance()->deselectLand();  	}  	if (object)  	{ -		mHitObjectID = object->mID; -  		parent = object->getRootEdit();  	} -	else -	{ -		mHitObjectID.setNull(); -	}  	BOOL touchable = (object && object->flagHandleTouch())   					 || (parent && parent->flagHandleTouch()); @@ -206,19 +197,19 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show)  			{  				// pay event goes to object actually clicked on  				sClickActionObject = object; -				sLeftClickSelection = LLToolSelect::handleObjectSelection(object, MASK_NONE, FALSE, TRUE); +				sLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);  				return TRUE;  			}  			break;  		case CLICK_ACTION_BUY:  			sClickActionObject = parent; -			sLeftClickSelection = LLToolSelect::handleObjectSelection(parent, MASK_NONE, FALSE, TRUE); +			sLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE);  			return TRUE;  		case CLICK_ACTION_OPEN:  			if (parent && parent->allowOpen())  			{  				sClickActionObject = parent; -				sLeftClickSelection = LLToolSelect::handleObjectSelection(parent, MASK_NONE, FALSE, TRUE); +				sLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE);  			}  			return TRUE;  		case CLICK_ACTION_PLAY: @@ -239,12 +230,13 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show)  	{  		gGrabTransientTool = this;  		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() ); -		return LLToolGrab::getInstance()->handleObjectHit( object, x, y, mask); +		return LLToolGrab::getInstance()->handleObjectHit( mPick );  	} -	if (!object && gLastHitHUDIcon && gLastHitHUDIcon->getSourceObject()) +	LLHUDIcon* last_hit_hud_icon = mPick.mHUDIcon; +	if (!object && last_hit_hud_icon && last_hit_hud_icon->getSourceObject())  	{ -		LLFloaterScriptDebug::show(gLastHitHUDIcon->getSourceObject()->getID()); +		LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID());  	}  	// If left-click never selects or spawns a menu @@ -273,7 +265,7 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show)  			LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance());  			gViewerWindow->hideCursor();  			LLToolCamera::getInstance()->setMouseCapture(TRUE); -			LLToolCamera::getInstance()->pickCallback(gViewerWindow->getCurrentMouseX(), gViewerWindow->getCurrentMouseY(), mask); +			LLToolCamera::getInstance()->pickCallback(mPick);  			gAgent.setFocusOnAvatar(TRUE, TRUE);  			return TRUE; @@ -292,22 +284,22 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show)  	}  	// Can't ignore children here. -	LLToolSelect::handleObjectSelection(object, mask, FALSE, TRUE); +	LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);  	// Spawn pie menu -	if (mHitLand) +	if (mPick.mPickType == LLPickInfo::PICK_LAND)  	{ -		LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( gLastHitPosGlobal ); +		LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( mPick.mPosGlobal );  		gMenuHolder->setParcelSelection(selection);  		gPieLand->show(x, y, mPieMouseButtonDown);  		// VEFFECT: ShowPie  		LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE); -		effectp->setPositionGlobal(gLastHitPosGlobal); +		effectp->setPositionGlobal(mPick.mPosGlobal);  		effectp->setColor(LLColor4U(gAgent.getEffectColor()));  		effectp->setDuration(0.25f);  	} -	else if (mHitObjectID == gAgent.getID() ) +	else if (mPick.mObjectID == gAgent.getID() )  	{  		if(!gPieSelf)   		{ @@ -377,7 +369,7 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show)  			// Don't show when you click on someone else, it freaks them  			// out.  			LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE); -			effectp->setPositionGlobal(gLastHitPosGlobal); +			effectp->setPositionGlobal(mPick.mPosGlobal);  			effectp->setColor(LLColor4U(gAgent.getEffectColor()));  			effectp->setDuration(0.25f);  		} @@ -544,7 +536,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  	LLViewerObject *parent = NULL;  	if (gHoverView)  	{ -		object = gHoverView->getLastHoverObject(); +		object = gViewerWindow->getHoverPick().getObject();  	}  	if (object) @@ -581,7 +573,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)  { -	LLViewerObject* obj = gViewerWindow->lastObjectHit(); +	LLViewerObject* obj = mPick.getObject();  	U8 click_action = final_click_action(obj);  	if (click_action != CLICK_ACTION_NONE)  	{ @@ -626,18 +618,18 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)  	if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))  	{ -		if (gLastHitLand -			&& !gLastHitPosGlobal.isExactlyZero()) +		if (mPick.mPickType == LLPickInfo::PICK_LAND +			&& !mPick.mPosGlobal.isExactlyZero())  		{  			handle_go_to();  			return TRUE;  		} -		else if (gLastHitObjectID.notNull() -				 && !gLastHitPosGlobal.isExactlyZero()) +		else if (mPick.mObjectID.notNull() +				 && !mPick.mPosGlobal.isExactlyZero())  		{  			// Hit an object  			// HACK: Call the last hit position the point we hit on the object -			gLastHitPosGlobal += gLastHitObjectOffset; +			//gLastHitPosGlobal += gLastHitObjectOffset;  			handle_go_to();  			return TRUE;  		} @@ -649,7 +641,7 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)  	objects gets you into trouble.  	// If double-click on object or land, go there. -	LLViewerObject *object = gViewerWindow->lastObjectHit(); +	LLViewerObject *object = gViewerWindow->getLastPick().getObject();  	if (object)  	{  		if (object->isAvatar()) @@ -756,10 +748,11 @@ static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp)  	if (objectp.isNull()) return;  	// did we hit a valid face on the object? -	if( gLastHitObjectFace < 0 || gLastHitObjectFace >= objectp->getNumTEs() ) return; +	S32 face = LLToolPie::getInstance()->getPick().mObjectFace; +	if( face < 0 || face >= objectp->getNumTEs() ) return;  	// is media playing on this face? -	if (!LLViewerMedia::isActiveMediaTexture(objectp->getTE(gLastHitObjectFace)->getID())) +	if (!LLViewerMedia::isActiveMediaTexture(objectp->getTE(face)->getID()))  	{  		handle_click_action_play();  		return; diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 4963940840..a8103f23a0 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -34,6 +34,7 @@  #include "lltool.h"  #include "lluuid.h" +#include "llviewerwindow.h" // for LLPickInfo  class LLViewerObject;  class LLObjectSelection; @@ -58,23 +59,25 @@ public:  	virtual void		handleDeselect();  	virtual LLTool*		getOverrideTool(MASK mask); -	static void			leftMouseCallback(S32 x, S32 y, MASK mask); -	static void			rightMouseCallback(S32 x, S32 y, MASK mask); +	LLPickInfo&			getPick() { return mPick; } + +	static void			leftMouseCallback(const LLPickInfo& pick_info); +	static void			rightMouseCallback(const LLPickInfo& pick_info);  	static void			selectionPropertiesReceived(); +  protected:  	BOOL outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y); -	BOOL pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL edit_menu); +	BOOL pickAndShowMenu(BOOL edit_menu);  	BOOL useClickAction(BOOL always_show, MASK mask, LLViewerObject* object,  						LLViewerObject* parent);  protected:  	BOOL				mPieMouseButtonDown;  	BOOL				mGrabMouseButtonDown; -	BOOL				mHitLand; -	LLUUID				mHitObjectID;  	BOOL				mMouseOutsideSlop;				// for this drag, has mouse moved outside slop region +	LLPickInfo			mPick;  	static LLPointer<LLViewerObject> sClickActionObject;  	static U8				sClickAction;  	static LLSafeHandle<LLObjectSelection> sLeftClickSelection; diff --git a/indra/newview/lltoolpipette.cpp b/indra/newview/lltoolpipette.cpp index a565e4361b..9456cd4472 100644 --- a/indra/newview/lltoolpipette.cpp +++ b/indra/newview/lltoolpipette.cpp @@ -67,9 +67,8 @@ BOOL LLToolPipette::handleMouseDown(S32 x, S32 y, MASK mask)  {  	mSuccess = TRUE;  	mTooltipMsg.clear(); -	gPickFaces = TRUE;  	setMouseCapture(TRUE); -	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +	gViewerWindow->pickAsync(x, y, mask, pickCallback);  	return TRUE;  } @@ -88,8 +87,7 @@ BOOL LLToolPipette::handleHover(S32 x, S32 y, MASK mask)  	gViewerWindow->setCursor(mSuccess ? UI_CURSOR_PIPETTE : UI_CURSOR_NO);  	if (hasMouseCapture()) // mouse button is down  	{ -		gPickFaces = TRUE; -		gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); +		gViewerWindow->pickAsync(x, y, mask, pickCallback);  		return TRUE;  	}  	return FALSE; @@ -107,19 +105,19 @@ BOOL LLToolPipette::handleToolTip(S32 x, S32 y, std::string& msg, LLRect *sticky  	return TRUE;  } -void LLToolPipette::pickCallback(S32 x, S32 y, MASK mask) +void LLToolPipette::pickCallback(const LLPickInfo& pick_info)  { -	LLViewerObject* hit_obj	= gViewerWindow->lastObjectHit(); +	LLViewerObject* hit_obj	= pick_info.getObject();  	LLSelectMgr::getInstance()->unhighlightAll();  	// if we clicked on a face of a valid prim, save off texture entry data  	if (hit_obj &&   		hit_obj->getPCode() == LL_PCODE_VOLUME && -		gLastHitObjectFace != -1) +		pick_info.mObjectFace != -1)  	{  		//TODO: this should highlight the selected face only  		LLSelectMgr::getInstance()->highlightObjectOnly(hit_obj); -		LLToolPipette::getInstance()->mTextureEntry = *hit_obj->getTE(gLastHitObjectFace); +		LLToolPipette::getInstance()->mTextureEntry = *hit_obj->getTE(pick_info.mObjectFace);  		if (LLToolPipette::getInstance()->mSelectCallback)  		{  			LLToolPipette::getInstance()->mSelectCallback(LLToolPipette::getInstance()->mTextureEntry, LLToolPipette::getInstance()->mUserData); diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h index b88a6eebc8..5d5b27f964 100644 --- a/indra/newview/lltoolpipette.h +++ b/indra/newview/lltoolpipette.h @@ -41,6 +41,7 @@  #include "lltextureentry.h"  class LLViewerObject; +class LLPickInfo;  class LLToolPipette  :	public LLTool, public LLSingleton<LLToolPipette> @@ -58,7 +59,7 @@ public:  	void setSelectCallback(select_callback callback, void* user_data);  	void setResult(BOOL success, const std::string& msg); -	static void pickCallback(S32 x, S32 y, MASK mask); +	static void pickCallback(const LLPickInfo& pick_info);  protected:  	LLTextureEntry	mTextureEntry; diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 7d4d0397cc..8806d1465a 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -81,14 +81,22 @@ BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj,  	// Viewer-side pick to find the right sim to create the object on.    	// First find the surface the object will be created on. -	gViewerWindow->hitObjectOrLandGlobalImmediate(x, y, NULL, FALSE); +	LLPickInfo pick = gViewerWindow->pickImmediate(x, y, FALSE);  	// Note: use the frontmost non-flora version because (a) plants usually have lots of alpha and (b) pants' Havok  	// representations (if any) are NOT the same as their viewer representation. -	*hit_obj = gObjectList.findObject( gLastHitNonFloraObjectID ); -	*hit_face = gLastHitNonFloraObjectFace; -	*b_hit_land = !(*hit_obj) && !gLastHitNonFloraPosGlobal.isExactlyZero(); -	LLVector3d land_pos_global = gLastHitNonFloraPosGlobal; +	if (pick.mPickType == LLPickInfo::PICK_FLORA) +	{ +		*hit_obj = NULL; +		*hit_face = -1; +	} +	else +	{ +		*hit_obj = pick.getObject(); +		*hit_face = pick.mObjectFace; +	} +	*b_hit_land = !(*hit_obj) && !pick.mPosGlobal.isExactlyZero(); +	LLVector3d land_pos_global = pick.mPosGlobal;  	// Make sure there's a surface to place the new object on.  	BOOL bypass_sim_raycast = FALSE; diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 8f84013a26..e74cd58924 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -64,39 +64,24 @@ LLToolSelect::LLToolSelect( LLToolComposite* composite )  // True if you selected an object.  BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)  { -	BOOL handled = FALSE; - -	// didn't click in any UI object, so must have clicked in the world -	LLViewerObject*	object = NULL; - -	// You must hit the body for this tool to think you hit the object. -	object = gObjectList.findObject( gLastHitObjectID ); - -	if (object) -	{ -		mSelectObjectID = object->getID(); -		handled = TRUE; -	} -	else -	{ -		mSelectObjectID.setNull(); -	} +	// do immediate pick query +	mPick = gViewerWindow->pickImmediate(x, y, TRUE);  	// Pass mousedown to agent  	LLTool::handleMouseDown(x, y, mask); -	return handled; +	return mPick.getObject().notNull();  } -BOOL LLToolSelect::handleDoubleClick(S32 x, S32 y, MASK mask) -{ -	//RN: double click to toggle individual/linked picking??? -	return LLTool::handleDoubleClick(x, y, mask); -}  // static -LLSafeHandle<LLObjectSelection> LLToolSelect::handleObjectSelection(LLViewerObject *object, MASK mask, BOOL ignore_group, BOOL temp_select) +LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, BOOL ignore_group, BOOL temp_select, BOOL select_root)  { +	LLViewerObject* object = pick.getObject(); +	if (select_root) +	{ +		object = object->getRootEdit(); +	}  	BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly");  	BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); @@ -108,14 +93,16 @@ LLSafeHandle<LLObjectSelection> LLToolSelect::handleObjectSelection(LLViewerObje  		LLSelectMgr::getInstance()->setForceSelection(TRUE);  	} -	BOOL extend_select = (mask == MASK_SHIFT) || (mask == MASK_CONTROL); +	BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL);  	// If no object, check for icon, then just deselect  	if (!object)  	{ -		if (gLastHitHUDIcon && gLastHitHUDIcon->getSourceObject()) +		LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon; + +		if (last_hit_hud_icon && last_hit_hud_icon->getSourceObject())  		{ -			LLFloaterScriptDebug::show(gLastHitHUDIcon->getSourceObject()->getID()); +			LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID());  		}  		else if (!extend_select)  		{ @@ -240,8 +227,7 @@ BOOL LLToolSelect::handleMouseUp(S32 x, S32 y, MASK mask)  {  	mIgnoreGroup = gSavedSettings.getBOOL("EditLinkedParts"); -	LLViewerObject* object = gObjectList.findObject(mSelectObjectID); -	LLToolSelect::handleObjectSelection(object, mask, mIgnoreGroup, FALSE); +	handleObjectSelection(mPick, mIgnoreGroup, FALSE);  	return LLTool::handleMouseUp(x, y, mask);  } @@ -275,3 +261,4 @@ void LLToolSelect::onMouseCaptureLost() + diff --git a/indra/newview/lltoolselect.h b/indra/newview/lltoolselect.h index c3d10424b1..f6359863a8 100644 --- a/indra/newview/lltoolselect.h +++ b/indra/newview/lltoolselect.h @@ -35,6 +35,7 @@  #include "lltool.h"  #include "v3math.h"  #include "lluuid.h" +#include "llviewerwindow.h" // for LLPickInfo  class LLObjectSelection; @@ -45,11 +46,10 @@ public:  	virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);  	virtual BOOL		handleMouseUp(S32 x, S32 y, MASK mask); -	virtual BOOL		handleDoubleClick(S32 x, S32 y, MASK mask);  	virtual void		stopEditing(); -	static LLSafeHandle<LLObjectSelection>	handleObjectSelection(LLViewerObject *object, MASK mask, BOOL ignore_group, BOOL temp_select); +	static LLSafeHandle<LLObjectSelection>	handleObjectSelection(const LLPickInfo& pick, BOOL ignore_group, BOOL temp_select, BOOL select_root = FALSE);  	virtual void		onMouseCaptureLost();  	virtual void		handleDeselect(); @@ -57,6 +57,7 @@ public:  protected:  	BOOL				mIgnoreGroup;  	LLUUID				mSelectObjectID; +	LLPickInfo			mPick;  }; diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp index 67d9e2da65..0d403bbb28 100644 --- a/indra/newview/lltoolselectrect.cpp +++ b/indra/newview/lltoolselectrect.cpp @@ -78,18 +78,26 @@ void dialog_refresh_all(void);  BOOL LLToolSelectRect::handleMouseDown(S32 x, S32 y, MASK mask)  { +	handlePick(gViewerWindow->pickImmediate(x, y, TRUE)); + +	LLTool::handleMouseDown(x, y, mask); + +	return mPick.getObject().notNull(); +} + +void LLToolSelectRect::handlePick(const LLPickInfo& pick) +{ +	mPick = pick; +  	// start dragging rectangle  	setMouseCapture( TRUE ); -	mDragStartX = x; -	mDragStartY = y; -	mDragEndX = x; -	mDragEndY = y; +	mDragStartX = pick.mMousePt.mX; +	mDragStartY = pick.mMousePt.mY; +	mDragEndX = pick.mMousePt.mX; +	mDragEndY = pick.mMousePt.mY;  	mMouseOutsideSlop = FALSE; - -	LLToolSelect::handleMouseDown(x, y, mask); -	return TRUE;  } diff --git a/indra/newview/lltoolselectrect.h b/indra/newview/lltoolselectrect.h index d45f0a433c..63b8d26e24 100644 --- a/indra/newview/lltoolselectrect.h +++ b/indra/newview/lltoolselectrect.h @@ -46,6 +46,8 @@ public:  	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);  	virtual void	draw();							// draw the select rectangle +	void handlePick(const LLPickInfo& pick); +  protected:  	void			handleRectangleSelection(S32 x, S32 y, MASK mask);	// true if you selected one  	BOOL			outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index b2cf873a21..0e83ba1123 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -798,7 +798,12 @@ void render_hud_attachments()  	glh::matrix4f current_proj = glh_get_current_projection();  	glh::matrix4f current_mod = glh_get_current_modelview(); -	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE)) +	// clamp target zoom level to reasonable values +	gAgent.mHUDTargetZoom = llclamp(gAgent.mHUDTargetZoom, 0.1f, 1.f); +	// smoothly interpolate current zoom level +	gAgent.mHUDCurZoom = lerp(gAgent.mHUDCurZoom, gAgent.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f)); + +	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())  	{  		LLCamera hud_cam = *LLViewerCamera::getInstance();  		LLVector3 origin = hud_cam.getOrigin(); @@ -856,52 +861,53 @@ void render_hud_attachments()  	glh_set_current_modelview(current_mod);  } -BOOL setup_hud_matrices(BOOL for_select) +BOOL setup_hud_matrices() +{ +	LLRect whole_screen = gViewerWindow->getVirtualWindowRect(); + +	// apply camera zoom transform (for high res screenshots) +	F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); +	S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); +	if (zoom_factor > 1.f) +	{ +		S32 num_horizontal_tiles = llceil(zoom_factor); +		S32 tile_width = llround((F32)gViewerWindow->getWindowWidth() / zoom_factor); +		S32 tile_height = llround((F32)gViewerWindow->getWindowHeight() / zoom_factor); +		int tile_y = sub_region / num_horizontal_tiles; +		int tile_x = sub_region - (tile_y * num_horizontal_tiles); +		glh::matrix4f mat; + +		whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWindowHeight() - (tile_y * tile_height), tile_width, tile_height); +	} + +	return setup_hud_matrices(whole_screen); +} + +BOOL setup_hud_matrices(const LLRect& screen_region)  {  	LLVOAvatar* my_avatarp = gAgent.getAvatarObject();  	if (my_avatarp && my_avatarp->hasHUDAttachment())  	{ -		if (!for_select) -		{ -			// clamp target zoom level to reasonable values -			my_avatarp->mHUDTargetZoom = llclamp(my_avatarp->mHUDTargetZoom, 0.1f, 1.f); -			// smoothly interpolate current zoom level -			my_avatarp->mHUDCurZoom = lerp(my_avatarp->mHUDCurZoom, my_avatarp->mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f)); -		} - -		F32 zoom_level = my_avatarp->mHUDCurZoom; -		// clear z buffer and set up transform for hud -		if (!for_select) -		{ -			//glClear(GL_DEPTH_BUFFER_BIT); -		} +		F32 zoom_level = gAgent.mHUDCurZoom;  		LLBBox hud_bbox = my_avatarp->getHUDBBox(); -		 -		// set up transform to encompass bounding box of HUD +		// set up transform to keep HUD objects in front of camera  		glMatrixMode(GL_PROJECTION);  		F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); -		if (for_select) -		{ -			//RN: reset viewport to window extents so ortho screen is calculated with proper reference frame -			gViewerWindow->setupViewport(); -		}  		glh::matrix4f proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth);  		proj.element(2,2) = -0.01f; -		// apply camera zoom transform (for high res screenshots) -		F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); -		S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); -		if (zoom_factor > 1.f) -		{ -			float offset = zoom_factor - 1.f; -			int pos_y = sub_region / llceil(zoom_factor); -			int pos_x = sub_region - (pos_y*llceil(zoom_factor)); -			glh::matrix4f mat; -			mat.set_scale(glh::vec3f(zoom_factor, zoom_factor, 1.f)); -			mat.set_translate(glh::vec3f(LLViewerCamera::getInstance()->getAspect() * 0.5f * (offset - (F32)pos_x * 2.f), 0.5f * (offset - (F32)pos_y * 2.f), 0.f)); -			proj *= mat; -		} +		F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect(); + +		glh::matrix4f mat; +		F32 scale_x = (F32)gViewerWindow->getWindowWidth() / (F32)screen_region.getWidth(); +		F32 scale_y = (F32)gViewerWindow->getWindowHeight() / (F32)screen_region.getHeight(); +		mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f)); +		mat.set_translate( +			glh::vec3f(clamp_rescale((F32)screen_region.getCenterX(), 0.f, (F32)gViewerWindow->getWindowWidth(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), +						clamp_rescale((F32)screen_region.getCenterY(), 0.f, (F32)gViewerWindow->getWindowHeight(), 0.5f * scale_y, -0.5f * scale_y), +						0.f)); +		proj *= mat;  		glLoadMatrixf(proj.m);  		glh_set_current_projection(proj); @@ -909,9 +915,8 @@ BOOL setup_hud_matrices(BOOL for_select)  		glMatrixMode(GL_MODELVIEW);  		glh::matrix4f model((GLfloat*) OGL_TO_CFR_ROTATION); -		glh::matrix4f mat; -		mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f));  		mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level)); +		mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f));  		model *= mat;  		glLoadMatrixf(model.m); @@ -1127,14 +1132,14 @@ void render_ui_2d()  	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  	// render outline for HUD -	if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mHUDCurZoom < 0.98f) +	if (gAgent.getAvatarObject() && gAgent.mHUDCurZoom < 0.98f)  	{  		glPushMatrix();  		S32 half_width = (gViewerWindow->getWindowWidth() / 2);  		S32 half_height = (gViewerWindow->getWindowHeight() / 2);  		glScalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);  		glTranslatef((F32)half_width, (F32)half_height, 0.f); -		F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom; +		F32 zoom = gAgent.mHUDCurZoom;  		glScalef(zoom,zoom,1.f);  		gGL.color4fv(LLColor4::white.mV);  		gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 1586f8dc75..3f57b26fec 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -694,5 +694,3 @@ void LLViewerMedia::setMimeType(std::string mime_type)  {  	sViewerMediaImpl.mMimeType = mime_type;  } - - diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 347ddac797..a095c9e159 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1359,6 +1359,9 @@ void init_debug_rendering_menu(LLMenuGL* menu)  	sub_menu->append(new LLMenuItemCheckGL("Glow",&LLPipeline::toggleRenderDebug, NULL,  													&LLPipeline::toggleRenderDebugControl,  													(void*)LLPipeline::RENDER_DEBUG_GLOW)); +	sub_menu->append(new LLMenuItemCheckGL("Raycasting",	&LLPipeline::toggleRenderDebug, NULL, +													&LLPipeline::toggleRenderDebugControl, +													(void*)LLPipeline::RENDER_DEBUG_RAYCAST));  	sub_menu->append(new LLMenuItemCheckGL("Show Depth Buffer",  										   &menu_toggle_control, @@ -1628,7 +1631,11 @@ class LLObjectReportAbuse : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLFloaterReporter::showFromObject(gLastHitObjectID); +		LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); +		if (objectp) +		{ +			LLFloaterReporter::showFromObject(objectp->getID()); +		}  		return true;  	}  }; @@ -1638,7 +1645,7 @@ class LLObjectEnableReportAbuse : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		bool new_value = !gLastHitObjectID.isNull(); +		bool new_value = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0;  		gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);  		return true;  	} @@ -1648,7 +1655,7 @@ class LLObjectTouch : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLViewerObject* object = gObjectList.findObject(gLastHitObjectID); +		LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		if (!object) return true;  		LLMessageSystem	*msg = gMessageSystem; @@ -1683,7 +1690,7 @@ class LLObjectEnableTouch : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID); +		LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		bool new_value = obj && obj->flagHandleTouch();  		gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); @@ -1717,7 +1724,7 @@ void label_touch(std::string& label, void*)  bool handle_object_open()  { -	LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID); +	LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  	if(!obj) return true;  	LLFloaterOpenObject::show(); @@ -1738,7 +1745,7 @@ class LLObjectEnableOpen : public view_listener_t  	{  		// Look for contents in root object, which is all the LLFloaterOpenObject  		// understands. -		LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID); +		LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		bool new_value = (obj != NULL);  		if (new_value)  		{ @@ -1838,14 +1845,14 @@ class LLObjectBuild : public view_listener_t  		{  			// zoom in if we're looking at the avatar  			gAgent.setFocusOnAvatar(FALSE, ANIMATE); -			gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  			gAgent.cameraZoomIn(0.666f);  			gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );  			gViewerWindow->moveCursorToCenter();  		}  		else if ( gSavedSettings.getBOOL("EditCameraMovement") )  		{ -			gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  			gViewerWindow->moveCursorToCenter();  		} @@ -1878,13 +1885,17 @@ class LLObjectEdit : public view_listener_t  			else  			{  				gAgent.setFocusOnAvatar(FALSE, ANIMATE); +				LLViewerObject* selected_objectp = selection->getFirstRootObject(); +				if (selected_objectp) +				{  				// zoom in on object center instead of where we clicked, as we need to see the manipulator handles -				gAgent.setFocusGlobal(gLastHitPosGlobal /*+ gLastHitObjectOffset*/, gLastHitObjectID); +					gAgent.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());  				gAgent.cameraZoomIn(0.666f);  				gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );  				gViewerWindow->moveCursorToCenter();  			}  		} +		}  		gFloaterTools->open();		/* Flawfinder: ignore */ @@ -1923,7 +1934,7 @@ class LLLandBuild : public view_listener_t  		{  			// zoom in if we're looking at the avatar  			gAgent.setFocusOnAvatar(FALSE, ANIMATE); -			gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  			gAgent.cameraZoomIn(0.666f);  			gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );  			gViewerWindow->moveCursorToCenter(); @@ -1931,7 +1942,7 @@ class LLLandBuild : public view_listener_t  		else if ( gSavedSettings.getBOOL("EditCameraMovement")  )  		{  			// otherwise just move focus -			gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  			gViewerWindow->moveCursorToCenter();  		} @@ -2049,15 +2060,19 @@ BOOL enable_has_attachments(void*)  //---------------------------------------------------------------------------  void handle_follow(void *userdata)  { -	// follow a given avatar, ID in gLastHitObjectID -	gAgent.startFollowPilot(gLastHitObjectID); +	// follow a given avatar by ID +	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); +	if (objectp) +	{ +		gAgent.startFollowPilot(objectp->getID()); +	}  }  class LLObjectEnableMute : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLViewerObject* object = gViewerWindow->lastObjectHit(); +		LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		bool new_value = (object != NULL);  		if (new_value)  		{ @@ -2080,7 +2095,7 @@ class LLObjectMute : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLViewerObject* object = gViewerWindow->lastObjectHit(); +		LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		if (!object) return true;  		LLUUID id; @@ -2136,11 +2151,12 @@ bool handle_go_to()  	// JAMESDEBUG try simulator autopilot  	std::vector<std::string> strings;  	std::string val; -	val = llformat("%g", gLastHitPosGlobal.mdV[VX]); +	LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal; +	val = llformat("%g", pos.mdV[VX]);  	strings.push_back(val); -	val = llformat("%g", gLastHitPosGlobal.mdV[VY]); +	val = llformat("%g", pos.mdV[VY]);  	strings.push_back(val); -	val = llformat("%g", gLastHitPosGlobal.mdV[VZ]); +	val = llformat("%g", pos.mdV[VZ]);  	strings.push_back(val);  	send_generic_message("autopilot", strings); @@ -2209,7 +2225,7 @@ class LLAvatarFreeze : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); +		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getFirstObject() );  		if( avatar )  		{  			LLUUID* avatar_id = new LLUUID( avatar->getID() ); @@ -2259,7 +2275,7 @@ class LLAvatarDebug : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); +		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getFirstObject() );  		if( avatar )  		{  			avatar->dumpLocalTextures(); @@ -2311,7 +2327,7 @@ class LLAvatarEject : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); +		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getFirstObject() );  		if( avatar )  		{  			LLUUID* avatar_id = new LLUUID( avatar->getID() ); @@ -2341,7 +2357,7 @@ class LLAvatarEnableFreezeEject : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); +		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getFirstObject() );  		bool new_value = (avatar != NULL);  		if (new_value) @@ -2366,7 +2382,7 @@ class LLAvatarGiveCard : public view_listener_t  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{  		llinfos << "handle_give_card()" << llendl; -		LLViewerObject* dest = gViewerWindow->lastObjectHit(); +		LLViewerObject* dest = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		if(dest && dest->isAvatar())  		{  			bool found_name = false; @@ -2605,9 +2621,9 @@ void handle_dump_region_object_cache(void*)  void handle_dump_focus(void *)  { -	LLView *view = gFocusMgr.getKeyboardFocus(); -	std::string name = view ? view->getName() : "(none)"; -	llinfos << "Keyboard focus " << name << llendl; +	LLUICtrl *ctrl = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); + +	llinfos << "Keyboard focus " << (ctrl ? ctrl->getName() : "(none)") << llendl;  }  class LLSelfStandUp : public view_listener_t @@ -2823,7 +2839,7 @@ class LLAvatarEnableAddFriend : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object(gViewerWindow->lastObjectHit()); +		LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getFirstObject());  		bool new_value = avatar && !is_agent_friend(avatar->getID());  		gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);  		return true; @@ -2870,10 +2886,12 @@ class LLEditEnableCustomizeAvatar : public view_listener_t  	}  }; +// only works on pie menu  bool handle_sit_or_stand()  { -	LLViewerObject *object = gObjectList.findObject(gLastHitNonFloraObjectID);	 -	if (!object) +	LLPickInfo pick = LLToolPie::getInstance()->getPick(); +	LLViewerObject *object = pick.getObject();; +	if (!object || pick.mPickType == LLPickInfo::PICK_FLORA)  	{  		return true;  	} @@ -2888,17 +2906,13 @@ bool handle_sit_or_stand()  	if (object && object->getPCode() == LL_PCODE_VOLUME)  	{ -		LLVector3d offset_double = gViewerWindow->lastNonFloraObjectHitOffset(); -		LLVector3 offset_single; -		offset_single.setVec(offset_double); -		  		gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);  		gMessageSystem->nextBlockFast(_PREHASH_AgentData);  		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());  		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  		gMessageSystem->nextBlockFast(_PREHASH_TargetObject);  		gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); -		gMessageSystem->addVector3Fast(_PREHASH_Offset, offset_single); +		gMessageSystem->addVector3Fast(_PREHASH_Offset, pick.mObjectOffset);  		object->getRegion()->sendReliableMessage();  	} @@ -2932,7 +2946,7 @@ class LLLandSit : public view_listener_t  		gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);  		LLViewerParcelMgr::getInstance()->deselectLand(); -		LLVector3d posGlobal = gLastHitPosGlobal; +		LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;  		LLQuaternion target_rot;  		if (gAgent.getAvatarObject()) @@ -5028,7 +5042,7 @@ class LLAvatarInviteToGroup : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); +		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getFirstObject() );  		if(avatar)  		{  			invite_to_group(avatar->getID()); @@ -5041,7 +5055,7 @@ class LLAvatarAddFriend : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); +		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getFirstObject() );  		if(avatar && !is_agent_friend(avatar->getID()))  		{  			request_friendship(avatar->getID()); @@ -5114,11 +5128,11 @@ class LLEnablePayObject : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object(gViewerWindow->lastObjectHit()); +		LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getFirstObject());  		bool new_value = (avatar != NULL);  		if (!new_value)  		{ -			LLViewerObject* object = gViewerWindow->lastObjectHit(); +			LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  			if( object )  			{  				LLViewerObject *parent = (LLViewerObject *)object->getParent(); @@ -5138,8 +5152,9 @@ class LLObjectEnableSitOrStand : public view_listener_t  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{  		bool new_value = false; -		LLViewerObject* dest_object = NULL; -		if((dest_object = gObjectList.findObject(gLastHitObjectID))) +		LLViewerObject* dest_object = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + +		if(dest_object)  		{  			if(dest_object->getPCode() == LL_PCODE_VOLUME)  			{ @@ -5502,7 +5517,11 @@ class LLShowAgentProfile : public view_listener_t  		}  		else if (userdata.asString() == "hit object")  		{ -			agent_id = gLastHitObjectID; +			LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); +			if (objectp) +			{ +				agent_id = objectp->getID(); +			}  		}  		else  		{ @@ -5538,12 +5557,12 @@ void handle_focus(void *)  	{  		// zoom in if we're looking at the avatar  		gAgent.setFocusOnAvatar(FALSE, ANIMATE); -		gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +		gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  		gAgent.cameraZoomIn(0.666f);  	}  	else  	{ -		gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +		gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  	}  	gViewerWindow->moveCursorToCenter(); @@ -5561,19 +5580,19 @@ class LLLandEdit : public view_listener_t  		{  			// zoom in if we're looking at the avatar  			gAgent.setFocusOnAvatar(FALSE, ANIMATE); -			gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  			gAgent.cameraOrbitOver( F_PI * 0.25f );  			gViewerWindow->moveCursorToCenter();  		}  		else if ( gSavedSettings.getBOOL("EditCameraMovement") )  		{ -			gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  			gViewerWindow->moveCursorToCenter();  		} -		LLViewerParcelMgr::getInstance()->selectParcelAt( gLastHitPosGlobal ); +		LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal );  		gFloaterTools->showMore(TRUE);  		gFloaterView->bringToFront( gFloaterTools ); @@ -5611,13 +5630,13 @@ void handle_move(void*)  	{  		// zoom in if we're looking at the avatar  		gAgent.setFocusOnAvatar(FALSE, ANIMATE); -		gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +		gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  		gAgent.cameraZoomIn(0.666f);  	}  	else  	{ -		gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); +		gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());  	}  	gViewerWindow->moveCursorToCenter(); @@ -5719,7 +5738,7 @@ class LLAttachmentDrop : public view_listener_t  	{  		// Called when the user clicked on an object attached to them  		// and selected "Drop". -		LLViewerObject *object = gViewerWindow->lastObjectHit(); +		LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		if (!object)  		{  			llwarns << "handle_drop_attachment() - no object to drop" << llendl; @@ -5819,7 +5838,7 @@ class LLAttachmentDetach : public view_listener_t  	{  		// Called when the user clicked on an object attached to them  		// and selected "Detach". -		LLViewerObject *object = gViewerWindow->lastObjectHit(); +		LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		if (!object)  		{  			llwarns << "handle_detach() - no object to detach" << llendl; @@ -5899,7 +5918,7 @@ class LLAttachmentEnableDrop : public view_listener_t  		// in your inventory.  Therefore, we disable the drop option until the  		// item is in your inventory -		LLViewerObject*              object         = gViewerWindow->lastObjectHit(); +		LLViewerObject*              object         = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  		LLViewerJointAttachment*     attachment_pt  = NULL;  		LLInventoryItem*             item           = NULL; @@ -5941,7 +5960,7 @@ class LLAttachmentEnableDrop : public view_listener_t  BOOL enable_detach(void*)  { -	LLViewerObject* object = gViewerWindow->lastObjectHit(); +	LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  	if (!object) return FALSE;  	if (!object->isAttachment()) return FALSE; @@ -6045,7 +6064,7 @@ class LLAvatarSendIM : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); +		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getFirstObject() );  		if(avatar)  		{  			std::string name("IM"); @@ -6821,7 +6840,11 @@ void handle_dump_avatar_local_textures(void*)  void handle_debug_avatar_textures(void*)  { -	LLFloaterAvatarTextures::show(gLastHitObjectID); +	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); +	if (objectp) +	{ +		LLFloaterAvatarTextures::show(objectp->getID()); +	}  }  void handle_grab_texture(void* data) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 19025b34a4..1aa7d2c3ff 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3039,7 +3039,7 @@ void LLViewerObject::updatePositionCaches() const  const LLVector3d LLViewerObject::getPositionGlobal() const  { -	LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());; +	LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());  	if (isAttachment())  	{ @@ -3365,6 +3365,19 @@ LLViewerObject* LLViewerObject::getRootEdit() const  	return (LLViewerObject*)root;  } + +BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +										  S32 face, +										  S32* face_hit, +										  LLVector3* intersection, +										  LLVector2* tex_coord, +										  LLVector3* normal, +										  LLVector3* bi_normal) +{ +	return false; +} + +  U8 LLViewerObject::getMediaType() const  {  	if (mMedia) @@ -4836,11 +4849,6 @@ BOOL LLViewerObject::setFlags(U32 flags, BOOL state)  	return setit;  } -BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, LLVector3& end) const -{ -	return FALSE; -} -  void LLViewerObject::applyAngularVelocity(F32 dt)  {  	//do target omega here diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 0f0fa62ea1..a143589ee9 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -242,9 +242,15 @@ public:  	//detect if given line segment (in agent space) intersects with this viewer object. -	//returns TRUE if intersection detected and moves end to the point of intersection -	//closest to start. -	virtual BOOL lineSegmentIntersect(const LLVector3& start, LLVector3& end) const; +	//returns TRUE if intersection detected and returns information about intersection +	virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES +									  S32* face_hit = NULL,                   // which face was hit +									  LLVector3* 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 +		);  	virtual const LLVector3d getPositionGlobal() const;  	virtual const LLVector3 &getPositionRegion() const; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 8cd295b8a8..a37120451e 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1078,14 +1078,14 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 ¢er)  {  } - -U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parcel_wall, BOOL keep_pick_list) +void LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, const LLRect& screen_rect, BOOL pick_parcel_wall, BOOL render_transparent)  { -	gRenderForSelect = TRUE; +	generatePickList(camera); +	renderPickList(screen_rect, pick_parcel_wall, render_transparent); +} -	//	LLTimer pick_timer; -	if (!keep_pick_list) -	{ +void LLViewerObjectList::generatePickList(LLCamera &camera) +{  		LLViewerObject *objectp;  		S32 i;  		// Reset all of the GL names to zero. @@ -1199,11 +1199,14 @@ U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parce  			}  			LLHUDIcon::generatePickIDs(i * step, step); -		 -			// At this point, we should only have live drawables/viewer objects -			gPipeline.renderForSelect(mSelectPickList); -		}  	} +} + +void LLViewerObjectList::renderPickList(const LLRect& screen_rect, BOOL pick_parcel_wall, BOOL render_transparent) +{ +	gRenderForSelect = TRUE; +		 +	gPipeline.renderForSelect(mSelectPickList, render_transparent, screen_rect);  	//  	// Render pass for selected objects @@ -1220,7 +1223,6 @@ U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parce  	//llinfos << "Rendered " << count << " for select" << llendl;  	//llinfos << "Took " << pick_timer.getElapsedTimeF32()*1000.f << "ms to pick" << llendl; -	return 0;  }  LLViewerObject *LLViewerObjectList::getSelectedObject(const U32 object_id) @@ -1526,3 +1528,4 @@ bool LLViewerObjectList::OrphanInfo::operator!=(const OrphanInfo &rhs) const  	return !operator==(rhs);  } + diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index b9b6ff243f..a5285930b2 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -108,7 +108,10 @@ public:  	void updateAvatarVisibility();  	// Selection related stuff -	U32 renderObjectsForSelect(LLCamera &camera, BOOL pick_parcel_wall = FALSE, BOOL keep_pick_list = FALSE); +	void renderObjectsForSelect(LLCamera &camera, const LLRect& screen_rect, BOOL pick_parcel_wall = FALSE, BOOL render_transparent = TRUE); +	void generatePickList(LLCamera &camera); +	void renderPickList(const LLRect& screen_rect, BOOL pick_parcel_wall, BOOL render_transparent); +  	LLViewerObject *getSelectedObject(const U32 object_id);  	inline S32 getNumObjects() { return mObjects.count(); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 0296aee8ca..4c575ff139 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -203,32 +203,8 @@ extern S32 gJamesInt;  LLViewerWindow	*gViewerWindow = NULL;  LLVelocityBar	*gVelocityBar = NULL; -LLVector3d		gLastHitPosGlobal; -LLVector3d		gLastHitObjectOffset; -LLUUID			gLastHitObjectID; -S32				gLastHitObjectFace = -1; -BOOL			gLastHitLand = FALSE; -F32				gLastHitUCoord; -F32				gLastHitVCoord; - - -LLVector3d		gLastHitNonFloraPosGlobal; -LLVector3d		gLastHitNonFloraObjectOffset; -LLUUID			gLastHitNonFloraObjectID; -S32				gLastHitNonFloraObjectFace = -1; -BOOL			gLastHitParcelWall = FALSE; - -S32				gLastHitUIElement = 0; -LLHUDIcon*		gLastHitHUDIcon = NULL;  BOOL			gDebugSelect = FALSE; -U8				gLastPickAlpha = 255; -BOOL			gUseGLPick = FALSE; - -// On the next pick pass (whenever that happens) -// should we try to pick individual faces? -// Cleared to FALSE every time a pick happens. -BOOL			gPickFaces = FALSE;  LLFrameTimer	gMouseIdleTimer;  LLFrameTimer	gAwayTimer; @@ -239,6 +215,11 @@ BOOL			gShowOverlayTitle = FALSE;  BOOL			gPickTransparent = TRUE;  BOOL			gDebugFastUIRender = FALSE; +LLViewerObject*  gDebugRaycastObject = NULL; +LLVector3       gDebugRaycastIntersection; +LLVector2       gDebugRaycastTexCoord; +LLVector3       gDebugRaycastNormal; +LLVector3       gDebugRaycastBinormal;  // HUD display lines in lower right  BOOL				gDisplayWindInfo = FALSE; @@ -256,9 +237,6 @@ const F32 MIN_AFK_TIME = 2.f; // minimum time after setting away state before co  const F32 MAX_FAST_FRAME_TIME = 0.5f;  const F32 FAST_FRAME_INCREMENT = 0.1f; -const S32 PICK_HALF_WIDTH = 5; -const S32 PICK_DIAMETER = 2 * PICK_HALF_WIDTH+1; -  const F32 MIN_DISPLAY_SCALE = 0.85f;  const S32 CONSOLE_BOTTOM_PAD = 40; @@ -1509,8 +1487,8 @@ LLViewerWindow::LLViewerWindow(  	mToolStored( NULL ),  	mSuppressToolbox( FALSE ),  	mHideCursorPermanent( FALSE ), -	mPickPending(FALSE), -	mIgnoreActivate( FALSE ) +	mIgnoreActivate( FALSE ), +	mHoverPick()  {  	// Default to application directory.  	LLViewerWindow::sSnapshotBaseName = "Snapshot"; @@ -1618,8 +1596,6 @@ LLViewerWindow::LLViewerWindow(  	mCurrentMousePoint.mX = getWindowWidth() / 2;  	mCurrentMousePoint.mY = getWindowHeight() / 2; -	mPickBuffer = new U8[PICK_DIAMETER * PICK_DIAMETER * 4]; -  	gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle");  	mOverlayTitle = gSavedSettings.getString("OverlayTitle");  	// Can't have spaces in settings.ini strings, so use underscores instead and convert them. @@ -2032,9 +2008,6 @@ LLViewerWindow::~LLViewerWindow()  	LLViewerImage::cleanupClass(); -	delete[] mPickBuffer; -	mPickBuffer = NULL; -  	llinfos << "Cleaning up select manager" << llendl;  	LLSelectMgr::getInstance()->cleanup(); @@ -2733,6 +2706,10 @@ BOOL LLViewerWindow::handlePerFrameHover()  	LLView::sMouseHandlerMessage.clear(); +	S32 x = mCurrentMousePoint.mX; +	S32 y = mCurrentMousePoint.mY; +	MASK mask = gKeyboard->currentMask(TRUE); +  	//RN: fix for asynchronous notification of mouse leaving window not working  	LLCoordWindow mouse_pos;  	mWindow->getCursorPosition(&mouse_pos); @@ -2748,6 +2725,7 @@ BOOL LLViewerWindow::handlePerFrameHover()  		mMouseInWindow = TRUE;  	} +  	S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);  	S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]); @@ -2778,10 +2756,6 @@ BOOL LLViewerWindow::handlePerFrameHover()  		return TRUE;  	} -	S32 x = mCurrentMousePoint.mX; -	S32 y = mCurrentMousePoint.mY; -	MASK mask = gKeyboard->currentMask(TRUE); -  	// clean up current focus  	LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();  	if (cur_focus) @@ -3123,10 +3097,41 @@ BOOL LLViewerWindow::handlePerFrameHover()  		LLSelectMgr::getInstance()->deselectUnused();  	} +	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) +	{ +		gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, +											  NULL, +											  &gDebugRaycastIntersection, +											  &gDebugRaycastTexCoord, +											  &gDebugRaycastNormal, +											  &gDebugRaycastBinormal); +	} + +	static U16 frame_counter = 0; +	static S32 previous_x = -1; +	static S32 previous_y = -1; +	 +	if (((previous_x != x) || (previous_y != y)) || +		((gSavedSettings.getBOOL("PerFrameHoverPick")) +		 && ((frame_counter % gSavedSettings.getS32("PerFrameHoverPickCount")) == 0))) +		{ +			pickAsync(getCurrentMouseX(), getCurrentMouseY(), mask, hoverPickCallback, TRUE); +		} +	frame_counter++; +	previous_x = x; +	previous_y = y; +	  	return handled;  } +/* static */ +void LLViewerWindow::hoverPickCallback(const LLPickInfo& pick_info) +{ +	gViewerWindow->mHoverPick = pick_info; +} +	 +  void LLViewerWindow::saveLastMouse(const LLCoordGL &point)  {  	// Store last mouse location. @@ -3220,7 +3225,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,  			glPushMatrix();  			if (selection->getSelectType() == SELECT_TYPE_HUD)  			{ -				F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom; +				F32 zoom = gAgent.mHUDCurZoom;  				glScalef(zoom, zoom, zoom);  			} @@ -3372,19 +3377,14 @@ BOOL LLViewerWindow::clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewe  	return intersect;  } -void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(S32 x, S32 y, MASK mask), BOOL pick_transparent, BOOL pick_parcel_walls) +void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& info), BOOL pick_transparent, BOOL get_surface_info)  {  	if (gNoRender)  	{  		return;  	} -	glClear(GL_DEPTH_BUFFER_BIT); -	gDepthDirty = TRUE; - -	S32 scaled_x = llround((F32)x * mDisplayScale.mV[VX]); -	S32 scaled_y = llround((F32)y_from_bot * mDisplayScale.mV[VY]); - +	// push back pick info object  	BOOL in_build_mode = gFloaterTools && gFloaterTools->getVisible();  	if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)  	{ @@ -3392,29 +3392,44 @@ void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask  		// "Show Debug Alpha" means no object actually transparent  		pick_transparent = TRUE;  	} -	gPickTransparent = pick_transparent; -	gUseGLPick = FALSE; -	mPickCallback = callback; +	// center initial pick frame buffer region under mouse cursor +	// since that area is guaranteed to be onscreen and hence a valid +	// part of the framebuffer +	if (mPicks.empty()) +	{ +		mPickScreenRegion.setCenterAndSize(x, y_from_bot, PICK_DIAMETER, PICK_DIAMETER); -	// Default to not hitting anything -	gLastHitPosGlobal.zeroVec(); -	gLastHitObjectOffset.zeroVec(); -	gLastHitObjectID.setNull(); -	gLastHitObjectFace = -1; +		if (mPickScreenRegion.mLeft < 0) mPickScreenRegion.translate(-mPickScreenRegion.mLeft, 0); +		if (mPickScreenRegion.mBottom < 0) mPickScreenRegion.translate(0, -mPickScreenRegion.mBottom); +		if (mPickScreenRegion.mRight > mWindowRect.getWidth() ) mPickScreenRegion.translate(mWindowRect.getWidth() - mPickScreenRegion.mRight, 0); +		if (mPickScreenRegion.mTop > mWindowRect.getHeight() ) mPickScreenRegion.translate(0, mWindowRect.getHeight() - mPickScreenRegion.mTop); +	} -	gLastHitNonFloraPosGlobal.zeroVec(); -	gLastHitNonFloraObjectOffset.zeroVec(); -	gLastHitNonFloraObjectID.setNull(); -	gLastHitNonFloraObjectFace = -1; +	// set frame buffer region for picking results +	// stack multiple picks left to right +	LLRect screen_region = mPickScreenRegion; +	screen_region.translate(mPicks.size() * PICK_DIAMETER, 0); -	gLastHitParcelWall = FALSE; +	LLPickInfo pick(LLCoordGL(x, y_from_bot), screen_region, mask, pick_transparent, get_surface_info, callback); +	schedulePick(pick); +} + +void LLViewerWindow::schedulePick(LLPickInfo& pick_info) +{ +	llassert_always(pick_info.mScreenRegion.notNull()); +	mPicks.push_back(pick_info); +	 +	S32 scaled_x = llround((F32)pick_info.mMousePt.mX * mDisplayScale.mV[VX]); +	S32 scaled_y = llround((F32)pick_info.mMousePt.mY * mDisplayScale.mV[VY]); + +	// Default to not hitting anything  	LLCamera pick_camera;  	pick_camera.setOrigin(LLViewerCamera::getInstance()->getOrigin());  	pick_camera.setOriginAndLookAt(LLViewerCamera::getInstance()->getOrigin(),  								   LLViewerCamera::getInstance()->getUpAxis(), -								   LLViewerCamera::getInstance()->getOrigin() + mouseDirectionGlobal(x, y_from_bot)); +								   LLViewerCamera::getInstance()->getOrigin() + mouseDirectionGlobal(pick_info.mMousePt.mX, pick_info.mMousePt.mY));  	pick_camera.setView(0.5f*DEG_TO_RAD);  	pick_camera.setNear(LLViewerCamera::getInstance()->getNear());  	pick_camera.setFar(LLViewerCamera::getInstance()->getFar()); @@ -3431,117 +3446,38 @@ void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask  	glPushMatrix();  	glLoadIdentity(); -	// build perspective transform and picking viewport -	// Perform pick on a PICK_DIAMETER x PICK_DIAMETER pixel region around cursor point. -	// Don't limit the select distance for this pick. -	LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, scaled_x - (PICK_HALF_WIDTH + 2), scaled_y - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4, FALSE); -	// make viewport big enough to handle antialiased frame buffers -	gGLViewport[0] = scaled_x - (PICK_HALF_WIDTH + 2); -	gGLViewport[1] = scaled_y - (PICK_HALF_WIDTH + 2); -	gGLViewport[2] = PICK_DIAMETER + 4; -	gGLViewport[3] = PICK_DIAMETER + 4; -	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -	LLViewerCamera::updateFrustumPlanes(pick_camera); -	stop_glerror(); - +	// clear work area +	{ +		LLGLState scissor_state(GL_SCISSOR_TEST); +		scissor_state.enable(); +		glScissor(pick_info.mScreenRegion.mLeft, pick_info.mScreenRegion.mBottom, pick_info.mScreenRegion.getWidth(), pick_info.mScreenRegion.getHeight());  	glClearColor(0.f, 0.f, 0.f, 0.f);  	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);  	//glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - -	// Draw the objects so the user can select them. -	// The starting ID is 1, since land is zero. -	gObjectList.renderObjectsForSelect(pick_camera, pick_parcel_walls); - -	stop_glerror(); - -	// restore drawing state -	glMatrixMode(GL_PROJECTION); -	glPopMatrix(); -	glMatrixMode(GL_MODELVIEW); -	glPopMatrix(); - -	setupViewport(); - -	mPickPoint.set(x, y_from_bot); -	mPickOffset.set(0, 0); -	mPickMask = mask; -	mPickPending = TRUE; - -	// delay further event processing until we receive results of pick -	mWindow->delayInputProcessing(); -} - -void LLViewerWindow::hitUIElementImmediate(S32 x, S32 y, void (*callback)(S32 x, S32 y, MASK mask)) -{ -	// Performs the GL UI pick. -	// Stores its results in global, gLastHitUIElement -	if (gNoRender) -	{ -		return; -	} -	 -	hitUIElementAsync(x, y, gKeyboard->currentMask(TRUE), NULL); -	performPick(); -	if (callback) -	{ -		callback(x, y, gKeyboard->currentMask(TRUE)); -	} -} - -//RN: this currently doesn't do anything -void LLViewerWindow::hitUIElementAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(S32 x, S32 y, MASK mask)) -{ -	if (gNoRender) -	{ -		return;  	} - -// 	F32 delta_time = gAlphaFadeTimer.getElapsedTimeAndResetF32(); - -	gUseGLPick = FALSE; -	mPickCallback = callback; - -	// Default to not hitting anything -	gLastHitUIElement = 0; - -	LLCamera pick_camera; -	pick_camera.setOrigin(LLViewerCamera::getInstance()->getOrigin()); -	pick_camera.setOriginAndLookAt(LLViewerCamera::getInstance()->getOrigin(), -								   LLViewerCamera::getInstance()->getUpAxis(), -								   LLViewerCamera::getInstance()->getOrigin() + mouseDirectionGlobal(x, y_from_bot)); -	pick_camera.setView(0.5f*DEG_TO_RAD); -	pick_camera.setNear(LLViewerCamera::getInstance()->getNear()); -	pick_camera.setFar(LLViewerCamera::getInstance()->getFar()); -	pick_camera.setAspect(1.f); - -	// save our drawing state -	glMatrixMode(GL_MODELVIEW); -	glPushMatrix(); -	glLoadIdentity(); -	glMatrixMode(GL_PROJECTION); -	glPushMatrix(); -	glLoadIdentity(); - -	// build orthogonal transform and picking viewport +	// build perspective transform and picking viewport  	// Perform pick on a PICK_DIAMETER x PICK_DIAMETER pixel region around cursor point.  	// Don't limit the select distance for this pick. -	setup2DRender(); -	const LLVector2& display_scale = getDisplayScale(); -	glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); +	LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, scaled_x - PICK_HALF_WIDTH, scaled_y - PICK_HALF_WIDTH, PICK_DIAMETER, PICK_DIAMETER, FALSE); -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +	// render for object picking  	// make viewport big enough to handle antialiased frame buffers -	glViewport(x - (PICK_HALF_WIDTH + 2), y_from_bot - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4); -	stop_glerror(); +	gGLViewport[0] = pick_info.mScreenRegion.mLeft; +	gGLViewport[1] = pick_info.mScreenRegion.mBottom; +	gGLViewport[2] = pick_info.mScreenRegion.getWidth(); +	gGLViewport[3] = pick_info.mScreenRegion.getHeight(); -	glClearColor(0.f, 0.f, 0.f, 0.f); -	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); +	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); +	LLViewerCamera::updateFrustumPlanes(pick_camera); +	stop_glerror();  	// Draw the objects so the user can select them.  	// The starting ID is 1, since land is zero. -	//drawForSelect(); +	LLRect pick_region; +	pick_region.setOriginAndSize(scaled_x - PICK_HALF_WIDTH, scaled_y - PICK_HALF_WIDTH, PICK_DIAMETER, PICK_DIAMETER); +	gObjectList.renderObjectsForSelect(pick_camera, pick_region, FALSE, pick_info.mPickTransparent);  	stop_glerror(); @@ -3551,309 +3487,121 @@ void LLViewerWindow::hitUIElementAsync(S32 x, S32 y_from_bot, MASK mask, void (*  	glMatrixMode(GL_MODELVIEW);  	glPopMatrix(); +	setup3DRender(); +	setup2DRender();  	setupViewport(); -	mPickPoint.set(x, y_from_bot); -	mPickOffset.set(0, 0); -	mPickMask = mask; -	mPickPending = TRUE; +	// delay further event processing until we receive results of pick +	mWindow->delayInputProcessing();  } +  void LLViewerWindow::performPick()  { -	if (gNoRender || !mPickPending) +	if (gNoRender)  	{  		return;  	} -	mPickPending = FALSE; -	U32	te_offset = NO_FACE; -	 -	// find pick region that is fully onscreen -	LLCoordGL scaled_pick_point = mPickPoint; -	scaled_pick_point.mX = llclamp(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX]), PICK_HALF_WIDTH, getWindowDisplayWidth() - PICK_HALF_WIDTH); -	scaled_pick_point.mY = llclamp(llround((F32)mPickPoint.mY * mDisplayScale.mV[VY]), PICK_HALF_WIDTH, getWindowDisplayHeight() - PICK_HALF_WIDTH); - -	glReadPixels(scaled_pick_point.mX - PICK_HALF_WIDTH, scaled_pick_point.mY - PICK_HALF_WIDTH, PICK_DIAMETER, PICK_DIAMETER, GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer); - -	S32 pixel_index = PICK_HALF_WIDTH * PICK_DIAMETER + PICK_HALF_WIDTH; -	S32 name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2]; -	gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3]; - -	if (name >= (S32)GL_NAME_UI_RESERVED && name < (S32)GL_NAME_INDEX_OFFSET) -	{ -		// hit a UI element -		gLastHitUIElement = name; -		if (mPickCallback) -		{ -			mPickCallback(mPickPoint.mX, mPickPoint.mY, mPickMask); -		} -	} - -	//imdebug("rgba rbga=bbba b=8 w=%d h=%d %p", PICK_DIAMETER, PICK_DIAMETER, mPickBuffer); - -	S32 x_offset = mPickPoint.mX - llround((F32)scaled_pick_point.mX / mDisplayScale.mV[VX]); -	S32 y_offset = mPickPoint.mY - llround((F32)scaled_pick_point.mY / mDisplayScale.mV[VY]); - -	 -	// we hit nothing, scan surrounding pixels for something useful -	if (!name) +	if (!mPicks.empty())  	{ -		S32 closest_distance = 10000; -		//S32 closest_pick_name = 0; -		for (S32 col = 0; col < PICK_DIAMETER; col++) +		std::vector<LLPickInfo>::iterator pick_it; +		for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it)  		{ -			for (S32 row = 0; row < PICK_DIAMETER; row++) -			{ -				S32 distance_squared = (llabs(col - x_offset - PICK_HALF_WIDTH) * llabs(col - x_offset - PICK_HALF_WIDTH)) + (llabs(row - y_offset - PICK_HALF_WIDTH) * llabs(row - y_offset - PICK_HALF_WIDTH)); -				pixel_index = row * PICK_DIAMETER + col; -				S32 test_name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2]; -				gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3]; -				if (test_name && distance_squared < closest_distance) -				{ -					closest_distance = distance_squared; -					name = test_name; -					gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3]; -					mPickOffset.mX = col - PICK_HALF_WIDTH; -					mPickOffset.mY = row - PICK_HALF_WIDTH; -				} -			} +			pick_it->fetchResults();  		} -	} -	if (name) -	{ -		mPickPoint.mX += llround((F32)mPickOffset.mX * mDisplayScale.mV[VX]); -		mPickPoint.mY += llround((F32)mPickOffset.mY * mDisplayScale.mV[VY]); -	} - -	if (gPickFaces) -	{ -		te_offset = ((U32)name >> 20); -		name &= 0x000fffff; -		// don't clear gPickFaces, as we still need to check for UV coordinates +		mLastPick = mPicks.back(); +		mPicks.clear();  	} -	LLViewerObject	*objectp = NULL; - -	// Frontmost non-foreground object that isn't trees or grass -	LLViewerObject* nonflora_objectp = NULL; -	S32 nonflora_name = -1; -	S32 nonflora_te_offset = NO_FACE; - -	if (name == (S32)GL_NAME_PARCEL_WALL) -	{ -		gLastHitParcelWall = TRUE; -	} - -	gLastHitHUDIcon = NULL; - -	objectp = gObjectList.getSelectedObject(name); -	if (objectp) -	{ -		LLViewerObject* parent = (LLViewerObject*)(objectp->getParent()); -		if (NULL == parent) { -			// if you are the parent -			parent = objectp; -		} -		if (objectp->mbCanSelect) -		{ -			te_offset = (te_offset == 16) ? NO_FACE : te_offset; - -			// If the hit object isn't a plant, store it as the frontmost non-flora object. -			LLPCode pcode = objectp->getPCode(); -			if( (LL_PCODE_LEGACY_GRASS != pcode) && -				(LL_PCODE_LEGACY_TREE != pcode) && -				(LL_PCODE_TREE_NEW != pcode)) -			{ -				nonflora_objectp = objectp; -				nonflora_name = name; -				nonflora_te_offset = te_offset; -			} -		} -		else -		{ -			//llinfos << "Hit object you can't select" << llendl; -		} -	} -	else -	{ -		// was this name referring to a hud icon? -		gLastHitHUDIcon = LLHUDIcon::handlePick(name); -	} - -	analyzeHit(  -		mPickPoint.mX, mPickPoint.mY, objectp, te_offset, -		&gLastHitObjectID, &gLastHitObjectFace, &gLastHitPosGlobal, &gLastHitLand, &gLastHitUCoord, &gLastHitVCoord ); - -	if (objectp && !gLastHitObjectID.isNull()) -	{ -		gLastHitObjectOffset = gAgent.calcFocusOffset(objectp, mPickPoint.mX, mPickPoint.mY); -	} +} -	if( objectp == nonflora_objectp ) -	{ -		gLastHitNonFloraObjectID	= gLastHitObjectID; -		gLastHitNonFloraObjectFace	= gLastHitObjectFace; -		gLastHitNonFloraPosGlobal	= gLastHitPosGlobal; -		gLastHitNonFloraObjectOffset= gLastHitObjectOffset; -	} -	else +// Performs the GL object/land pick. +LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_transparent) +{ +	if (gNoRender)  	{ -		analyzeHit(  mPickPoint.mX, mPickPoint.mY, nonflora_objectp, nonflora_te_offset, -			&gLastHitNonFloraObjectID, &gLastHitNonFloraObjectFace, &gLastHitNonFloraPosGlobal, -			&gLastHitLand, &gLastHitUCoord, &gLastHitVCoord); - -		if( nonflora_objectp ) -		{ -			gLastHitNonFloraObjectOffset = gAgent.calcFocusOffset(nonflora_objectp, mPickPoint.mX, mPickPoint.mY); -		} +		return LLPickInfo();  	} -	if (mPickCallback) -	{ -		mPickCallback(mPickPoint.mX, mPickPoint.mY, mPickMask); -	} +	pickAsync(x, y_from_bot, gKeyboard->currentMask(TRUE), NULL, pick_transparent); +	// assume that pickAsync put the results in the back of the mPicks list +	mLastPick = mPicks.back(); +	mLastPick.fetchResults(); +	mPicks.pop_back(); -	gPickFaces = FALSE; +	return mLastPick;  } -// Performs the GL object/land pick. -// Stores its results in globals, gHit* -void LLViewerWindow::hitObjectOrLandGlobalImmediate(S32 x, S32 y_from_bot, void (*callback)(S32 x, S32 y, MASK mask), BOOL pick_transparent) +LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth, +												LLViewerObject *this_object, +												S32 this_face, +												S32* face_hit, +												LLVector3 *intersection, +												LLVector2 *uv, +												LLVector3 *normal, +												LLVector3 *binormal)  { -	if (gNoRender) -	{ -		return; -	} -	 -	hitObjectOrLandGlobalAsync(x, y_from_bot, gKeyboard->currentMask(TRUE), NULL, pick_transparent); -	performPick(); -	if (callback) +	S32 x = mouse_x; +	S32 y = mouse_y; + +	if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position  	{ -		callback(x, y_from_bot, gKeyboard->currentMask(TRUE)); +		x = getCurrentMouseX(); +		y = getCurrentMouseY();  	} -} -LLViewerObject* LLViewerWindow::getObjectUnderCursor(const F32 depth) -{ -	S32 x = getCurrentMouseX(); -	S32 y = getCurrentMouseY(); +	// HUD coordinates of mouse +	LLVector3 mouse_point_hud = mousePointHUD(x, y); +	LLVector3 mouse_hud_start = mouse_point_hud - LLVector3(depth, 0, 0); +	LLVector3 mouse_hud_end   = mouse_point_hud + LLVector3(depth, 0, 0); +	// world coordinates of mouse  	LLVector3		mouse_direction_global = mouseDirectionGlobal(x,y); -	LLVector3		camera_pos_global = LLViewerCamera::getInstance()->getOrigin(); -	LLVector3		pick_end = camera_pos_global + mouse_direction_global * depth; -	LLVector3		collision_point; -	return gPipeline.pickObject(camera_pos_global, pick_end, collision_point); -} - -void LLViewerWindow::analyzeHit( -	S32				x,				// input -	S32				y_from_bot,		// input -	LLViewerObject* objectp,		// input -	U32				te_offset,		// input -	LLUUID*			hit_object_id_p,// output -	S32*			hit_face_p,		// output -	LLVector3d*		hit_pos_p,		// output -	BOOL*			hit_land,		// output -	F32*			hit_u_coord,	// output -	F32*			hit_v_coord)	// output -{ -	// Clean up inputs -	S32 face = -1; -	 -	if (te_offset != NO_FACE )  -	{ -		face = te_offset; -	} +	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; -	*hit_land = FALSE; +	 +	LLViewerObject* found = NULL; -	if (objectp) +	if (this_object)  // check only this object  	{ -		if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH ) +		if (this_object->isHUDAttachment()) // is a HUD object?  		{ -			// Hit land -			*hit_land = TRUE; - -			// put global position into land_pos -			LLVector3d land_pos; -			if (mousePointOnLandGlobal(x, y_from_bot, &land_pos)) +			if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, +												  face_hit, intersection, uv, normal, binormal))  			{ -				*hit_object_id_p = LLUUID::null; -				*hit_face_p = -1; - -				// Fudge the land focus a little bit above ground. -				*hit_pos_p = land_pos + LLVector3d(0.f, 0.f, 0.1f); -				//llinfos << "DEBUG Hit Land " << *hit_pos_p  << llendl; -				return; +				found = this_object;  			} -			else -			{ -				//llinfos << "Hit land but couldn't find position" << llendl; -				// Fall through to "Didn't hit anything"  			} -		} -		else +		 +		else // is a world object  		{ -			*hit_object_id_p = objectp->mID; -			*hit_face_p = face; - -			// Hit an object -			if (objectp->isAvatar()) +			if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, +												  face_hit, intersection, uv, normal, binormal))  			{ -				*hit_pos_p = gAgent.getPosGlobalFromAgent(((LLVOAvatar*)objectp)->mPelvisp->getWorldPosition()); +				found = this_object;  			} -			else if (objectp->mDrawable.notNull()) -			{ -				*hit_pos_p = gAgent.getPosGlobalFromAgent(objectp->getRenderPosition());  			} -			else -			{ -				// regular object -				*hit_pos_p = objectp->getPositionGlobal();  			} -			if (gPickFaces && face > -1 && -				objectp->mDrawable.notNull() && objectp->getPCode() == LL_PCODE_VOLUME && -				face < objectp->mDrawable->getNumFaces()) +	else // check ALL objects  			{ -				// render red-blue gradient to get 1/256 precision -				// then render green grid to get final 1/4096 precision -				S32 scaled_x = llround((F32)x * mDisplayScale.mV[VX]); -				S32 scaled_y = llround((F32)y_from_bot * mDisplayScale.mV[VY]); -				const S32 UV_PICK_WIDTH = 41; -				const S32 UV_PICK_HALF_WIDTH = (UV_PICK_WIDTH - 1) / 2; -				U8 uv_pick_buffer[UV_PICK_WIDTH * UV_PICK_WIDTH * 4]; -				S32 pick_face = face; -				LLFace* facep = objectp->mDrawable->getFace(pick_face); -				LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, FALSE); -				glViewport(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH); -				gPipeline.renderFaceForUVSelect(facep); - -				glReadPixels(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, GL_RGBA, GL_UNSIGNED_BYTE, uv_pick_buffer); -				U8* center_pixel = &uv_pick_buffer[4 * ((UV_PICK_WIDTH * UV_PICK_HALF_WIDTH) + UV_PICK_HALF_WIDTH + 1)]; -				*hit_u_coord = (F32)((center_pixel[VGREEN] & 0xf) + (16.f * center_pixel[VRED])) / 4095.f; -				*hit_v_coord = (F32)((center_pixel[VGREEN] >> 4) + (16.f * center_pixel[VBLUE])) / 4095.f; -			} -			else +		found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, +													face_hit, intersection, uv, normal, binormal); + +		if (!found) // if not found in HUD, look in world: +  			{ -				*hit_u_coord = 0.f; -				*hit_v_coord = 0.f; +			found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, +														  face_hit, intersection, uv, normal, binormal);  			} -			//llinfos << "DEBUG Hit Object " << *hit_pos_p << llendl; -			return; -		}  	} -	// Didn't hit anything. -	*hit_object_id_p = LLUUID::null; -	*hit_face_p = -1; -	*hit_pos_p = LLVector3d::zero; -	*hit_u_coord = 0.f; -	*hit_v_coord = 0.f; -	//llinfos << "DEBUG Hit Nothing " << llendl; +	return found;  }  // Returns unit vector relative to camera @@ -3884,6 +3632,18 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const  	return mouse_vector;  } +LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const +{ +	// find screen resolution +	S32			height = getWindowHeight(); +	S32			width = getWindowWidth(); + +	// remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5 +	F32 hud_x = -((F32)x - (F32)width/2.f)  / height; +	F32 hud_y = ((F32)y - (F32)height/2.f) / height; + +	return LLVector3(0.f, hud_x, hud_y); +}  // Returns unit vector relative to camera in camera space  // indicating direction of point on screen x,y @@ -4249,8 +4009,7 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p  	LLHUDText::setDisplayText(FALSE) ;  	if (type == SNAPSHOT_TYPE_OBJECT_ID)  	{ -		gPickTransparent = FALSE; -		gObjectList.renderObjectsForSelect(*LLViewerCamera::getInstance(), FALSE, FALSE); +		gObjectList.renderPickList(gViewerWindow->getVirtualWindowRect(), FALSE, FALSE);  	}  	else  	{ @@ -4452,6 +4211,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());  	F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear()); +	gObjectList.generatePickList(*LLViewerCamera::getInstance()); +  	for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)  	{  		S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);; @@ -4472,9 +4233,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  				LLViewerCamera::getInstance()->setZoomParameters(scale_factor, subimage_x+(subimage_y*llceil(scale_factor)));  				setup3DRender();  				setupViewport(); -				BOOL first_time_through = (subimage_x + subimage_y == 0); -				gPickTransparent = FALSE; -				gObjectList.renderObjectsForSelect(*LLViewerCamera::getInstance(), FALSE, !first_time_through); +				gObjectList.renderPickList(gViewerWindow->getVirtualWindowRect(), FALSE, FALSE);  			}  			else  			{ @@ -4723,27 +4482,6 @@ void LLViewerWindow::setup2DRender()  	gl_state_for_2d(mWindowRect.getWidth(), mWindowRect.getHeight());  } -// Could cache the pointer from the last hitObjectOrLand here. -LLViewerObject *LLViewerWindow::lastObjectHit() -{ -	return gObjectList.findObject( gLastHitObjectID ); -} - -const LLVector3d& LLViewerWindow::lastObjectHitOffset() -{ -	return gLastHitObjectOffset; -} - -// Could cache the pointer from the last hitObjectOrLand here. -LLViewerObject *LLViewerWindow::lastNonFloraObjectHit() -{ -	return gObjectList.findObject( gLastHitNonFloraObjectID ); -} - -const LLVector3d& LLViewerWindow::lastNonFloraObjectHitOffset() -{ -	return gLastHitNonFloraObjectOffset; -}  void LLViewerWindow::setShowProgress(const BOOL show) @@ -5166,46 +4904,7 @@ F32 LLViewerWindow::getDisplayAspectRatio() const  void LLViewerWindow::drawPickBuffer() const  { -	if (mPickBuffer) -	{ -		gGL.color4f(1,1,1,1); -		gGL.pushMatrix(); -		LLGLDisable no_blend(GL_BLEND); -		LLGLDisable no_alpha_test(GL_ALPHA_TEST); -		LLGLSNoTexture no_texture; -		glPixelZoom(10.f, 10.f); -		glRasterPos2f(((F32)mPickPoint.mX * mDisplayScale.mV[VX] + 10.f),  -			((F32)mPickPoint.mY * mDisplayScale.mV[VY] + 10.f)); -		glDrawPixels(PICK_DIAMETER, PICK_DIAMETER, GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer); -		glPixelZoom(1.f, 1.f); -		gGL.color4fv(LLColor4::white.mV); -		gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] - (F32)(PICK_HALF_WIDTH)),  -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH)), -			llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH)), -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] - (F32)(PICK_HALF_WIDTH)), -			FALSE); -		gl_line_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] - (F32)(PICK_HALF_WIDTH)),  -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH)), -			llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + 10.f),  -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f + 10.f)); -		gl_line_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH)), -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] - (F32)(PICK_HALF_WIDTH)), -			llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f + 10.f),  -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + 10.f)); -		gGL.translatef(10.f, 10.f, 0.f); -		gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX]),  -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f), -			llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f), -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY]), -			FALSE); -		gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH + mPickOffset.mX)* 10.f),  -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH + mPickOffset.mY + 1) * 10.f), -			llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH + mPickOffset.mX + 1) * 10.f), -			llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH  + mPickOffset.mY) * 10.f), -			FALSE); -		gGL.popMatrix(); -		gGL.flush(); -	} +	mHoverPick.drawPickBuffer();  }  void LLViewerWindow::calcDisplayScale() @@ -5394,3 +5093,342 @@ void* LLBottomPanel::createToolBar(void* data)  	gToolBar = new LLToolBar();  	return gToolBar;  } + +// +// LLPickInfo +// +LLPickInfo::LLPickInfo() +	: mKeyMask(MASK_NONE), +	  mPickCallback(NULL), +	  mPickType(PICK_INVALID), +	  mWantSurfaceInfo(FALSE), +	  mObjectFace(-1), +	  mUVCoords(-1.f, -1.f), +	  mSTCoords(-1.f, -1.f), +	  mXYCoords(-1, -1), +	  mIntersection(), +	  mNormal(), +	  mBinormal(), +	  mHUDIcon(NULL), +	  mPickTransparent(FALSE) +{ +} + +LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,  +					   const LLRect& screen_region, +						MASK keyboard_mask,  +						BOOL pick_transparent, +						BOOL pick_uv_coords, +						void (*pick_callback)(const LLPickInfo& pick_info)) +	: mMousePt(mouse_pos), +	  mScreenRegion(screen_region), +	  mKeyMask(keyboard_mask), +	  mPickCallback(pick_callback), +	  mPickType(PICK_INVALID), +	  mWantSurfaceInfo(pick_uv_coords), +	  mObjectFace(-1), +	  mUVCoords(-1.f, -1.f), +	  mSTCoords(-1.f, -1.f), +	  mXYCoords(-1, -1), +	  mNormal(), +	  mBinormal(), +	  mHUDIcon(NULL), +	  mPickTransparent(pick_transparent) +{ +} + +LLPickInfo::~LLPickInfo() +{ +} + +void LLPickInfo::fetchResults() +{ +	// read back colors and depth values from buffer +	glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer); +	glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_DEPTH_COMPONENT, GL_FLOAT, mPickDepthBuffer ); + +	// find pick region that is fully onscreen +	LLCoordGL scaled_pick_point;; +	scaled_pick_point.mX = llclamp(llround((F32)mMousePt.mX * gViewerWindow->getDisplayScale().mV[VX]), PICK_HALF_WIDTH, gViewerWindow->getWindowDisplayWidth() - PICK_HALF_WIDTH); +	scaled_pick_point.mY = llclamp(llround((F32)mMousePt.mY * gViewerWindow->getDisplayScale().mV[VY]), PICK_HALF_WIDTH, gViewerWindow->getWindowDisplayHeight() - PICK_HALF_WIDTH); +	S32 pixel_index = PICK_HALF_WIDTH * PICK_DIAMETER + PICK_HALF_WIDTH; +	S32 pick_id = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2]; +	F32 depth = mPickDepthBuffer[pixel_index]; + +	S32 x_offset = mMousePt.mX - llround((F32)scaled_pick_point.mX / gViewerWindow->getDisplayScale().mV[VX]); +	S32 y_offset = mMousePt.mY - llround((F32)scaled_pick_point.mY / gViewerWindow->getDisplayScale().mV[VY]); + +	mPickPt = mMousePt; + +	// we hit nothing, scan surrounding pixels for something useful +	if (!pick_id) +	{ +		S32 closest_distance = 10000; +		//S32 closest_pick_name = 0; +		for (S32 col = 0; col < PICK_DIAMETER; col++) +		{ +			for (S32 row = 0; row < PICK_DIAMETER; row++) +			{ +				S32 distance_squared = (llabs(col - x_offset - PICK_HALF_WIDTH) * llabs(col - x_offset - PICK_HALF_WIDTH)) + (llabs(row - y_offset - PICK_HALF_WIDTH) * llabs(row - y_offset - PICK_HALF_WIDTH)); +				pixel_index = row * PICK_DIAMETER + col; +				S32 test_name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2]; +				if (test_name && distance_squared < closest_distance) +				{ +					closest_distance = distance_squared; +					pick_id = test_name; +					depth = mPickDepthBuffer[pixel_index]; +					mPickPt.mX = mMousePt.mX + (col - PICK_HALF_WIDTH); +					mPickPt.mY = mMousePt.mY + (row - PICK_HALF_WIDTH); +				} +			} +		} +	} + +	U32 te_offset = ((U32)pick_id >> 20); +	pick_id &= 0x000fffff; + +	//unproject relative clicked coordinate from window coordinate using GL +	GLint viewport[4]; +	GLdouble modelview[16]; +	GLdouble projection[16]; +	GLfloat winX, winY; +	GLdouble posX, posY, posZ; + +	LLViewerObject* objectp = gObjectList.getSelectedObject(pick_id); + +	if (pick_id == (S32)GL_NAME_PARCEL_WALL) +	{ +		mPickType = PICK_PARCEL_WALL; +	} +	else if (objectp) +	{ +		if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH ) +		{ +			// Hit land +			mPickType = PICK_LAND; +			mObjectID.setNull(); // land has no id + +			// put global position into land_pos +			LLVector3d land_pos; +			if (gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos)) +			{ +				// Fudge the land focus a little bit above ground. +				mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f; +			} +		} +		else +		{ +			if(isFlora(objectp)) +			{ +				mPickType = PICK_FLORA; +			} +			else +			{ +				mPickType = PICK_OBJECT; +			} +			mObjectOffset = gAgent.calcFocusOffset(objectp, mPickPt.mX, mPickPt.mY); +			mObjectID = objectp->mID; +			mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; + +			glh::matrix4f newModel((F32*)LLViewerCamera::getInstance()->getModelview().mMatrix); + +			for(U32 i = 0; i < 16; ++i) +			{ +				modelview[i] = newModel.m[i]; +				projection[i] = LLViewerCamera::getInstance()->getProjection().mMatrix[i/4][i%4]; +			} +			glGetIntegerv( GL_VIEWPORT, viewport ); + +			winX = ((F32)mPickPt.mX) * gViewerWindow->getDisplayScale().mV[VX]; +			winY = ((F32)mPickPt.mY) * gViewerWindow->getDisplayScale().mV[VY]; + +			gluUnProject( winX, winY, depth, modelview, projection, viewport, &posX, &posY, &posZ); + +			mPosGlobal = gAgent.getPosGlobalFromAgent(LLVector3(posX, posY, posZ)); +			 +			if (mWantSurfaceInfo) +			{ +				getSurfaceInfo(); +			} +		} +	} +	else +	{ +		// was this name referring to a hud icon? +		mHUDIcon = LLHUDIcon::handlePick(pick_id); +		if (mHUDIcon) +		{ +			mPickType = PICK_ICON; +			mPosGlobal = mHUDIcon->getPositionGlobal(); +		} +	} + +	if (mPickCallback) +	{ +		mPickCallback(*this); +	} +} + +LLPointer<LLViewerObject> LLPickInfo::getObject() const +{ +	return gObjectList.findObject( mObjectID ); +} + +void LLPickInfo::updateXYCoords() +{ +	const LLTextureEntry* tep = getObject()->getTE(mObjectFace); +	LLPointer<LLViewerImage> imagep = gImageList.getImage(tep->getID()); +	if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull()) +	{ +		LLCoordGL coords; +		 +		coords.mX = llround(mUVCoords.mV[VX] * (F32)imagep->getWidth()); +		coords.mY = llround(mUVCoords.mV[VY] * (F32)imagep->getHeight()); + +		gViewerWindow->getWindow()->convertCoords(coords, &mXYCoords); +	} +} + +void LLPickInfo::drawPickBuffer() const +{ +	if (mPickBuffer) +	{ +		gGL.pushMatrix(); +		LLGLDisable no_blend(GL_BLEND); +		LLGLDisable no_alpha_test(GL_ALPHA_TEST); +		LLGLSNoTexture no_texture; +		glPixelZoom(10.f, 10.f); +		LLVector2 display_scale = gViewerWindow->getDisplayScale(); +		glRasterPos2f(((F32)mMousePt.mX * display_scale.mV[VX] + 10.f),  +			((F32)mMousePt.mY * display_scale.mV[VY] + 10.f)); +		glDrawPixels(PICK_DIAMETER, PICK_DIAMETER, GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer); +		glPixelZoom(1.f, 1.f); +		gGL.color4fv(LLColor4::white.mV); +		gl_rect_2d(llround((F32)mMousePt.mX * display_scale.mV[VX] - (F32)(PICK_HALF_WIDTH)),  +			llround((F32)mMousePt.mY * display_scale.mV[VY] + (F32)(PICK_HALF_WIDTH)), +			llround((F32)mMousePt.mX * display_scale.mV[VX] + (F32)(PICK_HALF_WIDTH)), +			llround((F32)mMousePt.mY * display_scale.mV[VY] - (F32)(PICK_HALF_WIDTH)), +			FALSE); +		gl_line_2d(llround((F32)mMousePt.mX * display_scale.mV[VX] - (F32)(PICK_HALF_WIDTH)),  +			llround((F32)mMousePt.mY * display_scale.mV[VY] + (F32)(PICK_HALF_WIDTH)), +			llround((F32)mMousePt.mX * display_scale.mV[VX] + 10.f),  +			llround((F32)mMousePt.mY * display_scale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f + 10.f)); +		gl_line_2d(llround((F32)mMousePt.mX * display_scale.mV[VX] + (F32)(PICK_HALF_WIDTH)), +			llround((F32)mMousePt.mY * display_scale.mV[VY] - (F32)(PICK_HALF_WIDTH)), +			llround((F32)mMousePt.mX * display_scale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f + 10.f),  +			llround((F32)mMousePt.mY * display_scale.mV[VY] + 10.f)); +		gGL.translatef(10.f, 10.f, 0.f); +		gl_rect_2d(llround((F32)mPickPt.mX * display_scale.mV[VX]),  +			llround((F32)mPickPt.mY * display_scale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f), +			llround((F32)mPickPt.mX * display_scale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f), +			llround((F32)mPickPt.mY * display_scale.mV[VY]), +			FALSE); +		gl_rect_2d(llround((F32)mPickPt.mX * display_scale.mV[VX]),  +			llround((F32)mPickPt.mY * display_scale.mV[VY] + 10.f), +			llround((F32)mPickPt.mX * display_scale.mV[VX] + 10.f), +			llround((F32)mPickPt.mY * display_scale.mV[VY]), +			FALSE); +		gGL.popMatrix(); +	} +} + +void LLPickInfo::getSurfaceInfo() +{ +	// set values to uninitialized - this is what we return if no intersection is found +	mObjectFace   = -1; +	mUVCoords     = LLVector2(-1, -1); +	mSTCoords     = LLVector2(-1, -1); +	mXYCoords	  = LLCoordScreen(-1, -1); +	mIntersection = LLVector3(0,0,0); +	mNormal       = LLVector3(0,0,0); +	mBinormal     = LLVector3(0,0,0); +	 +	LLViewerObject* objectp = getObject(); + +	if (objectp) +	{ +		if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f, +										   objectp, -1, +										   &mObjectFace, +										   &mIntersection, +										   &mSTCoords, +										   &mNormal, +										   &mBinormal)) +		{ +			// if we succeeded with the intersect above, compute the texture coordinates: + +			if (objectp->mDrawable.notNull()) +			{ +				LLFace* facep = objectp->mDrawable->getFace(mObjectFace); + +				mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); +			} + +			// and XY coords: +			updateXYCoords(); +			 +		} +	} +} + + +/* code to get UV via a special UV render - removed in lieu of raycast method +LLVector2 LLPickInfo::pickUV() +{ +	LLVector2 result(-1.f, -1.f); + +	LLViewerObject* objectp = getObject(); +	if (!objectp) +	{ +		return result; +	} + +	if (mObjectFace > -1 && +		objectp->mDrawable.notNull() && objectp->getPCode() == LL_PCODE_VOLUME && +		mObjectFace < objectp->mDrawable->getNumFaces()) +	{ +		S32 scaled_x = llround((F32)mPickPt.mX * gViewerWindow->getDisplayScale().mV[VX]); +		S32 scaled_y = llround((F32)mPickPt.mY * gViewerWindow->getDisplayScale().mV[VY]); +		const S32 UV_PICK_WIDTH = 5; +		const S32 UV_PICK_HALF_WIDTH = (UV_PICK_WIDTH - 1) / 2; +		U8 uv_pick_buffer[UV_PICK_WIDTH * UV_PICK_WIDTH * 4]; +		LLFace* facep = objectp->mDrawable->getFace(mObjectFace); +		if (facep) +		{ +			LLGLState scissor_state(GL_SCISSOR_TEST); +			scissor_state.enable(); +			LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, FALSE); +			//glViewport(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH); +			glScissor(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH); + +			glClear(GL_DEPTH_BUFFER_BIT); + +			facep->renderSelectedUV(); + +			glReadPixels(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, GL_RGBA, GL_UNSIGNED_BYTE, uv_pick_buffer); +			U8* center_pixel = &uv_pick_buffer[4 * ((UV_PICK_WIDTH * UV_PICK_HALF_WIDTH) + UV_PICK_HALF_WIDTH + 1)]; + +			result.mV[VX] = (F32)((center_pixel[VGREEN] & 0xf) + (16.f * center_pixel[VRED])) / 4095.f; +			result.mV[VY] = (F32)((center_pixel[VGREEN] >> 4) + (16.f * center_pixel[VBLUE])) / 4095.f; +		} +	} + +	return result; +} */ + + +//static  +bool LLPickInfo::isFlora(LLViewerObject* object) +{ +	if (!object) return false; + +	LLPCode pcode = object->getPCode(); + +	if( (LL_PCODE_LEGACY_GRASS == pcode)  +		|| (LL_PCODE_LEGACY_TREE == pcode)  +		|| (LL_PCODE_TREE_NEW == pcode)) +	{ +		return true; +	} +	return false; +} diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 5c0eae61be..c7d02cb720 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -60,6 +60,70 @@ class LLTextBox;  class LLImageRaw;  class LLHUDIcon; +#define PICK_HALF_WIDTH 5 +#define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1) + +class LLPickInfo +{ +public: +	LLPickInfo(); +	LLPickInfo(const LLCoordGL& mouse_pos,  +		const LLRect& screen_region, +		MASK keyboard_mask,  +		BOOL pick_transparent,  +		BOOL pick_surface_info, +		void (*pick_callback)(const LLPickInfo& pick_info)); +	~LLPickInfo(); + +	void fetchResults(); +	LLPointer<LLViewerObject> getObject() const; +	LLUUID getObjectID() const { return mObjectID; } +	void drawPickBuffer() const; + +	static bool isFlora(LLViewerObject* object); + +	typedef enum e_pick_type +	{ +		PICK_OBJECT, +		PICK_FLORA, +		PICK_LAND, +		PICK_ICON, +		PICK_PARCEL_WALL, +		PICK_INVALID +	} EPickType; + +public: +	LLCoordGL		mMousePt; +	MASK			mKeyMask; +	void			(*mPickCallback)(const LLPickInfo& pick_info); + +	EPickType		mPickType; +	LLCoordGL		mPickPt; +	LLVector3d		mPosGlobal; +	LLVector3		mObjectOffset; +	LLUUID			mObjectID; +	S32				mObjectFace; +	LLHUDIcon*		mHUDIcon; +	LLVector3       mIntersection; +	LLVector2		mUVCoords; +	LLVector2       mSTCoords; +	LLCoordScreen	mXYCoords; +	LLVector3		mNormal; +	LLVector3		mBinormal; +	BOOL			mPickTransparent; +	LLRect			mScreenRegion; +	void		    getSurfaceInfo(); + +private: +	void			updateXYCoords(); + +	BOOL			mWantSurfaceInfo;   // do we populate mUVCoord, mNormal, mBinormal? +	U8				mPickBuffer[PICK_DIAMETER * PICK_DIAMETER * 4]; +	F32				mPickDepthBuffer[PICK_DIAMETER * PICK_DIAMETER]; +	BOOL			mPickParcelWall; + +}; +  #define MAX_IMAGE_SIZE 6144 //6 * 1024, max snapshot image size 6144 * 6144  class LLViewerWindow : public LLWindowCallbacks @@ -143,6 +207,9 @@ public:  	BOOL			getLeftMouseDown()	const	{ return mLeftMouseDown; }  	BOOL			getRightMouseDown()	const	{ return mRightMouseDown; } +	const LLPickInfo&	getLastPick() const { return mLastPick; } +	const LLPickInfo&	getHoverPick() const { return mHoverPick; } +  	LLUICtrl*		getTopCtrl() const;  	BOOL			hasTopCtrl(LLView* view) const; @@ -150,10 +217,10 @@ public:  	void			setup3DRender();  	void			setup2DRender(); -	BOOL			isPickPending()				{ return mPickPending; } -  	LLVector3		mouseDirectionGlobal(const S32 x, const S32 y) const;  	LLVector3		mouseDirectionCamera(const S32 x, const S32 y) const; +	LLVector3       mousePointHUD(const S32 x, const S32 y) const; +		  	// Is window of our application frontmost?  	BOOL			getActive() const			{ return mActive; } @@ -244,20 +311,27 @@ public:  	void			renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud );  	void			performPick(); -	void			hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(S32 x, S32 y, MASK mask), BOOL pick_transparent = FALSE, BOOL pick_parcel_walls = FALSE); -	void			hitObjectOrLandGlobalImmediate(S32 x, S32 y, void (*callback)(S32 x, S32 y, MASK mask), BOOL pick_transparent); +	void			pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& pick_info), +							  BOOL pick_transparent = FALSE, BOOL get_surface_info = FALSE); +	LLPickInfo		pickImmediate(S32 x, S32 y, BOOL pick_transparent); +	static void     hoverPickCallback(const LLPickInfo& pick_info); +	 +	LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f, +									LLViewerObject *this_object = NULL, +									S32 this_face = -1, +									S32* face_hit = NULL, +									LLVector3 *intersection = NULL, +									LLVector2 *uv = NULL, +									LLVector3 *normal = NULL, +									LLVector3 *binormal = NULL); -	void			hitUIElementAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(S32 x, S32 y, MASK mask)); -	void			hitUIElementImmediate(S32 x, S32 y, void (*callback)(S32 x, S32 y, MASK mask)); - -	LLViewerObject*	getObjectUnderCursor(const F32 depth = 16.0f);  	// Returns a pointer to the last object hit -	LLViewerObject	*lastObjectHit(); -	LLViewerObject  *lastNonFloraObjectHit(); +	//LLViewerObject	*getObject(); +	//LLViewerObject  *lastNonFloraObjectHit(); -	const LLVector3d& lastObjectHitOffset(); -	const LLVector3d& lastNonFloraObjectHitOffset(); +	//const LLVector3d& getObjectOffset(); +	//const LLVector3d& lastNonFloraObjectHitOffset();  	// mousePointOnLand() returns true if found point  	BOOL			mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d *land_pos_global); @@ -306,19 +380,7 @@ private:  	void			stopGL(BOOL save_state = TRUE);  	void			restoreGL(const std::string& progress_message = LLStringUtil::null);  	void			initFonts(F32 zoom_factor = 1.f); -	 -	void			analyzeHit( -						S32				x,				// input -						S32				y_from_bot,		// input -						LLViewerObject* objectp,		// input -						U32				te_offset,		// input -						LLUUID*			hit_object_id_p,// output -						S32*			hit_face_p,		// output -						LLVector3d*		hit_pos_p,		// output -						BOOL*			hit_land,		// output -						F32*			hit_u_coord,	// output -						F32*			hit_v_coord);	// output - +	void			schedulePick(LLPickInfo& pick_info);  public:  	LLWindow*		mWindow;						// graphical window object @@ -354,16 +416,14 @@ protected:  	BOOL			mSuppressToolbox;	// sometimes hide the toolbox, despite  										// having a camera tool selected  	BOOL			mHideCursorPermanent;	// true during drags, mouselook -	LLCoordGL		mPickPoint; -	LLCoordGL		mPickOffset; -	MASK			mPickMask; -	BOOL			mPickPending; -	void			(*mPickCallback)(S32 x, S32 y, MASK mask); +	LLPickInfo		mLastPick; +	LLPickInfo		mHoverPick; +	std::vector<LLPickInfo> mPicks; +	LLRect			mPickScreenRegion; // area of frame buffer for rendering pick frames (generally follows mouse to avoid going offscreen)  	std::string		mOverlayTitle;		// Used for special titles such as "Second Life - Special E3 2003 Beta"  	BOOL			mIgnoreActivate; -	U8*				mPickBuffer;  	std::string		mInitAlert;			// Window / GL initialization requires an alert @@ -398,9 +458,7 @@ void toggle_first_person();  void toggle_build(void*);  void reset_viewer_state_on_sim(void);  void update_saved_window_size(const std::string& control,S32 delta_width, S32 delta_height); -// -// Constants -// +  // @@ -414,28 +472,15 @@ extern LLFrameTimer		gMouseIdleTimer;		// how long has it been since the mouse l  extern LLFrameTimer		gAwayTimer;				// tracks time before setting the avatar away state to true  extern LLFrameTimer		gAwayTriggerTimer;		// how long the avatar has been away -extern LLVector3d		gLastHitPosGlobal; -extern LLVector3d		gLastHitObjectOffset; -extern LLUUID			gLastHitObjectID; -extern S32				gLastHitObjectFace; -extern BOOL				gLastHitLand; -extern F32				gLastHitUCoord; -extern F32				gLastHitVCoord; - - -extern LLVector3d		gLastHitNonFloraPosGlobal; -extern LLVector3d		gLastHitNonFloraObjectOffset; -extern LLUUID			gLastHitNonFloraObjectID; -extern S32				gLastHitNonFloraObjectFace; - -extern S32				gLastHitUIElement; -extern LLHUDIcon*		gLastHitHUDIcon; -extern BOOL				gLastHitParcelWall;  extern BOOL				gDebugSelect; -extern BOOL				gPickFaces; -extern BOOL				gPickTransparent;  extern BOOL				gDebugFastUIRender; +extern LLViewerObject*  gDebugRaycastObject; +extern LLVector3        gDebugRaycastIntersection; +extern LLVector2        gDebugRaycastTexCoord; +extern LLVector3        gDebugRaycastNormal; +extern LLVector3        gDebugRaycastBinormal; +  extern S32 CHAT_BAR_HEIGHT;   extern BOOL			gDisplayCameraPos; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 287f063757..47090d5c65 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -622,8 +622,6 @@ LLVOAvatar::LLVOAvatar(  	LLViewerRegion* regionp)  	:  	LLViewerObject(id, pcode, regionp), -	mHUDTargetZoom(1.f), -	mHUDCurZoom(1.f),  	mLastHeadBakedID( IMG_DEFAULT_AVATAR ),  	mLastUpperBodyBakedID( IMG_DEFAULT_AVATAR ),  	mLastLowerBodyBakedID( IMG_DEFAULT_AVATAR ), @@ -3250,7 +3248,8 @@ void LLVOAvatar::idleUpdateTractorBeam()  			}  			else  			{ -				mBeam->setPositionGlobal(gLastHitNonFloraPosGlobal + gLastHitNonFloraObjectOffset); +				const LLPickInfo& pick = gViewerWindow->getLastPick(); +				mBeam->setPositionGlobal(pick.mPosGlobal);  			}  		} diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 54fd7d370f..ff846c8d83 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -636,8 +636,6 @@ public:  	// special purpose joint for HUD attachments  	//--------------------------------------------------------------------  	LLViewerJoint *mScreenp; -	F32				mHUDTargetZoom; -	F32				mHUDCurZoom;  	//--------------------------------------------------------------------  	// mesh objects for skinned avatar diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b84f8d8e4b..1e1f8be859 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1893,26 +1893,42 @@ LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const  LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const  { -	return dir * ~getRenderRotation(); +	LLVector3 ret = dir * ~getRenderRotation(); +	 +	LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); +	ret.scaleVec(objScale); + +	return ret;  }  LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const  {  	LLVector3 ret = dir; -	ret.scaleVec(getScale()); +	LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); +	ret.scaleVec(objScale);  	ret = ret * getRenderRotation();  	ret += getRenderPosition();  	return ret;  } -BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, LLVector3& end) const +LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const  { -	return FALSE; +	LLVector3 ret = dir; +	LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); +	LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); +	ret.scaleVec(invObjScale); +	ret = ret * getRenderRotation(); + +	return ret; +} + + +BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, S32 *face_hitp, +									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) -#if 0 // needs to be rewritten to use face extents instead of volume bounds +{  	LLVolume* volume = getVolume(); -	BOOL ret = FALSE;  	if (volume)  	{	  		LLVector3 v_start, v_end, v_dir; @@ -1920,17 +1936,38 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, LLVector3& end) co  		v_start = agentPositionToVolume(start);  		v_end = agentPositionToVolume(end); -		if (LLLineSegmentAABB(v_start, v_end, volume->mBounds[0], volume->mBounds[1])) +		S32 face_hit = volume->lineSegmentIntersect(v_start, v_end, face, +													intersection, tex_coord, normal, bi_normal); +		if (face_hit >= 0)  		{ -			if (volume->lineSegmentIntersect(v_start, v_end) >= 0) +			if (face_hitp != NULL) +			{ +				*face_hitp = face_hit; +			} +			 +			if (intersection != NULL) +			{ +				*intersection = volumePositionToAgent(*intersection);  // must map back to agent space +			} + +			if (normal != NULL) +			{ +				*normal = volumeDirectionToAgent(*normal); +				(*normal).normVec(); +			} + +			if (bi_normal != NULL)  			{ -				end = volumePositionToAgent(v_end); -				ret = TRUE; +				*bi_normal = volumeDirectionToAgent(*bi_normal); +				(*bi_normal).normVec();  			} + +			 +			return TRUE;  		}  	} -	return ret; -#endif +	 +	return FALSE;  }  U32 LLVOVolume::getPartitionType() const diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index d7b72f7a18..262d4ecc8d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -111,10 +111,20 @@ public:  	const LLMatrix3&	getRelativeXformInvTrans() const		{ return mRelativeXformInvTrans; }  	/*virtual*/	const LLMatrix4	getRenderMatrix() const; -	/*virtual*/ BOOL	lineSegmentIntersect(const LLVector3& start, LLVector3& end) const; + +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES +										  S32* face_hit = NULL,                 // which face was hit +										  LLVector3* 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 +		); +	  				LLVector3 agentPositionToVolume(const LLVector3& pos) const;  				LLVector3 agentDirectionToVolume(const LLVector3& dir) const;  				LLVector3 volumePositionToAgent(const LLVector3& dir) const; +				LLVector3 volumeDirectionToAgent(const LLVector3& dir) const;  				BOOL	getVolumeChanged() const				{ return mVolumeChanged; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f9a18bf192..c24d1b882a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2188,6 +2188,7 @@ void LLPipeline::renderHighlights()  	// Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD)  	// Render highlighted faces. +	LLGLSPipelineAlpha gls_pipeline_alpha;  	LLColor4 color(1.f, 1.f, 1.f, 0.5f);  	LLGLEnable color_mat(GL_COLOR_MATERIAL);  	disableLights(); @@ -2341,7 +2342,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)  	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING))  	{ -		gObjectList.renderObjectsForSelect(camera); +		gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect());  	}  	else if (gSavedSettings.getBOOL("RenderDeferred"))  	{ @@ -2591,7 +2592,7 @@ void LLPipeline::renderDebug()  	gGL.flush();  } -void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects) +void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render_transparent, const LLRect& screen_rect)  {  	assertInitialized(); @@ -2644,7 +2645,7 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects)  	}	  	LLGLEnable alpha_test(GL_ALPHA_TEST); -	if (gPickTransparent) +	if (render_transparent)  	{  		gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f);  	} @@ -2689,14 +2690,7 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects)  		glh::matrix4f save_proj(glh_get_current_projection());  		glh::matrix4f save_model(glh_get_current_modelview()); -		U32 viewport[4]; - -		for (U32 i = 0; i < 4; i++) -		{ -			viewport[i] = gGLViewport[i]; -		} -		 -		setup_hud_matrices(TRUE); +		setup_hud_matrices(screen_rect);  		for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();   			 iter != avatarp->mAttachmentPoints.end(); )  		{ @@ -2748,11 +2742,6 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects)  		glh_set_current_modelview(save_model); -		for (U32 i = 0; i < 4; i++) -		{ -			gGLViewport[i] = viewport[i]; -		} -		glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);  	}  	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); @@ -2762,11 +2751,6 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects)  	gGL.setColorMask(true, true);  } -void LLPipeline::renderFaceForUVSelect(LLFace* facep) -{ -	if (facep) facep->renderSelectedUV(); -} -  void LLPipeline::rebuildPools()  {  	LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -3959,7 +3943,13 @@ BOOL LLPipeline::getProcessBeacons(void* data)  	return sRenderProcessBeacons;  } -LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) +LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +														S32* face_hit, +														LLVector3* 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 +	)  {  	LLDrawable* drawable = NULL; @@ -3967,10 +3957,45 @@ LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &  			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)  	{  		LLViewerRegion* region = *iter; -		LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); + +		for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) +		{ +			if ((j == LLViewerRegion::PARTITION_VOLUME) || (j == LLViewerRegion::PARTITION_BRIDGE))  // only check these partitions for now +			{ +				LLSpatialPartition* part = region->getSpatialPartition(j); +				if (part) +				{ +					LLDrawable* hit = part->lineSegmentIntersect(start, end, face_hit, intersection, tex_coord, normal, bi_normal); +					if (hit) +					{ +						drawable = hit; +					} +				} +			} +		} +	} +	return drawable ? drawable->getVObj().get() : NULL; +} + +LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +													  S32* face_hit, +													  LLVector3* 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 +	) +{ +	LLDrawable* drawable = NULL; + +	for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();  +			iter != LLWorld::getInstance()->getRegionList().end(); ++iter) +	{ +		LLViewerRegion* region = *iter; + +		LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);  		if (part)  		{ -			LLDrawable* hit = part->pickDrawable(start, end, collision); +			LLDrawable* hit = part->lineSegmentIntersect(start, end, face_hit, intersection, tex_coord, normal, bi_normal);  			if (hit)  			{  				drawable = hit; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e98be79120..ac2c32fedd 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -65,8 +65,8 @@ typedef enum e_avatar_skinning_method  BOOL compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn't be defined here!  bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon = 0); -BOOL LLLineSegmentAABB(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); -BOOL setup_hud_matrices(BOOL for_select); +BOOL setup_hud_matrices(); // use whole screen to render hud +BOOL setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking)  glh::matrix4f glh_copy_matrix(GLdouble* src);  glh::matrix4f glh_get_current_modelview();  void glh_set_current_modelview(const glh::matrix4f& mat); @@ -129,8 +129,21 @@ public:  	void        markTextured(LLDrawable *drawablep);  	void        markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); -	//get the object between start and end that's closest to start.  Return the point of collision in collision. -	LLViewerObject* pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision); +	//get the object between start and end that's closest to start. +	LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +												S32* face_hit,                          // return the face hit +												LLVector3* 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* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +											  S32* face_hit,                          // return the face hit +											  LLVector3* 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 +		);  	// Something about these textures has changed.  Dirty them.  	void        dirtyPoolObjectTextures(const std::set<LLViewerImage*>& textures); @@ -185,8 +198,7 @@ public:  	void renderHighlights();  	void renderDebug(); -	void renderForSelect(std::set<LLViewerObject*>& objects); -	void renderFaceForUVSelect(LLFace* facep); +	void renderForSelect(std::set<LLViewerObject*>& objects, BOOL render_transparent, const LLRect& screen_rect);  	void rebuildPools(); // Rebuild pools  	void findReferences(LLDrawable *drawablep);	// Find the lists which have references to this object @@ -329,7 +341,8 @@ public:  		RENDER_DEBUG_TEXTURE_ANIM		= 0x080000,  		RENDER_DEBUG_LIGHTS				= 0x100000,  		RENDER_DEBUG_BATCH_SIZE			= 0x200000, -		RENDER_DEBUG_SHAME				= 0x400000, +		RENDER_DEBUG_RAYCAST            = 0x400000, +		RENDER_DEBUG_SHAME				= 0x800000  	};  public: diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index 7761283239..6f49ef25b5 100644 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -2436,6 +2436,15 @@ version 2.0  		{	LocalID				U32  }  		{	GrabOffset			LLVector3 }  	} +	{ +		SurfaceInfo     Variable +		{   UVCoord     LLVector3 } +		{   STCoord     LLVector3 } +       	{   FaceIndex   S32 } +       	{   Position    LLVector3 } +       	{   Normal      LLVector3 } +       	{   Binormal    LLVector3 } +	}  } @@ -2457,6 +2466,16 @@ version 2.0  		{	GrabPosition		LLVector3	}	// LLVector3, region local  		{	TimeSinceLast		U32	}  	} +	{ +		SurfaceInfo     Variable +		{   UVCoord     LLVector3 } +		{   STCoord     LLVector3 } +       	{   FaceIndex   S32 } +       	{   Position    LLVector3 } +       	{   Normal      LLVector3 } +       	{   Binormal    LLVector3 } +	} +  } @@ -2472,6 +2491,15 @@ version 2.0  		ObjectData			Single  		{	LocalID				U32  }  	} +	{ +		SurfaceInfo     Variable +		{   UVCoord     LLVector3 } +		{   STCoord     LLVector3 } +       	{   FaceIndex   S32 } +       	{   Position    LLVector3 } +       	{   Normal      LLVector3 } +       	{   Binormal    LLVector3 } +	}  } | 
