summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llmath/llrect.h5
-rw-r--r--indra/llmath/llvolume.cpp224
-rw-r--r--indra/llmath/llvolume.h14
-rw-r--r--indra/llmath/v2math.cpp1
-rw-r--r--indra/llmath/v2math.h14
-rw-r--r--indra/llmath/v3math.cpp8
-rw-r--r--indra/llmath/v3math.h2
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp4
-rw-r--r--indra/llmessage/message_prehash.cpp3
-rw-r--r--indra/llmessage/message_prehash.h4
-rw-r--r--indra/llui/llview.cpp1
-rw-r--r--indra/llwindow/llwindowmacosx.cpp5
-rw-r--r--indra/llwindow/llwindowwin32.cpp4
-rw-r--r--indra/lscript/lscript_library/lscript_library.cpp8
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/llagent.cpp28
-rw-r--r--indra/newview/llagent.h8
-rw-r--r--indra/newview/lldrawpoolavatar.cpp11
-rw-r--r--indra/newview/llface.cpp238
-rw-r--r--indra/newview/llface.h3
-rw-r--r--indra/newview/llhudobject.h2
-rw-r--r--indra/newview/llmanip.cpp19
-rw-r--r--indra/newview/llmanip.h1
-rw-r--r--indra/newview/llmaniprotate.cpp25
-rw-r--r--indra/newview/llmaniprotate.h3
-rw-r--r--indra/newview/llmanipscale.cpp22
-rw-r--r--indra/newview/llmanipscale.h2
-rw-r--r--indra/newview/llmaniptranslate.cpp20
-rw-r--r--indra/newview/llmaniptranslate.h2
-rw-r--r--indra/newview/llselectmgr.cpp37
-rw-r--r--indra/newview/llspatialpartition.cpp171
-rw-r--r--indra/newview/llspatialpartition.h9
-rw-r--r--indra/newview/lltexturectrl.cpp8
-rw-r--r--indra/newview/lltoolcomp.cpp76
-rw-r--r--indra/newview/lltoolcomp.h11
-rw-r--r--indra/newview/lltooldraganddrop.cpp31
-rw-r--r--indra/newview/lltooldraganddrop.h3
-rw-r--r--indra/newview/lltoolface.cpp13
-rw-r--r--indra/newview/lltoolface.h3
-rw-r--r--indra/newview/lltoolfocus.cpp28
-rw-r--r--indra/newview/lltoolfocus.h4
-rw-r--r--indra/newview/lltoolgrab.cpp346
-rw-r--r--indra/newview/lltoolgrab.h19
-rw-r--r--indra/newview/lltoolindividual.cpp6
-rw-r--r--indra/newview/lltoolindividual.h4
-rw-r--r--indra/newview/lltoolobjpicker.cpp15
-rw-r--r--indra/newview/lltoolobjpicker.h4
-rw-r--r--indra/newview/lltoolpie.cpp87
-rw-r--r--indra/newview/lltoolpie.h13
-rw-r--r--indra/newview/lltoolpipette.cpp14
-rw-r--r--indra/newview/lltoolpipette.h3
-rw-r--r--indra/newview/lltoolplacer.cpp18
-rw-r--r--indra/newview/lltoolselect.cpp45
-rw-r--r--indra/newview/lltoolselect.h5
-rw-r--r--indra/newview/lltoolselectrect.cpp22
-rw-r--r--indra/newview/lltoolselectrect.h2
-rw-r--r--indra/newview/llviewerdisplay.cpp85
-rw-r--r--indra/newview/llviewermedia.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp133
-rw-r--r--indra/newview/llviewerobject.cpp20
-rw-r--r--indra/newview/llviewerobject.h12
-rw-r--r--indra/newview/llviewerobjectlist.cpp25
-rw-r--r--indra/newview/llviewerobjectlist.h5
-rw-r--r--indra/newview/llviewerwindow.cpp994
-rw-r--r--indra/newview/llviewerwindow.h151
-rw-r--r--indra/newview/llvoavatar.cpp5
-rw-r--r--indra/newview/llvoavatar.h2
-rw-r--r--indra/newview/llvovolume.cpp61
-rw-r--r--indra/newview/llvovolume.h12
-rw-r--r--indra/newview/pipeline.cpp73
-rw-r--r--indra/newview/pipeline.h27
71 files changed, 1973 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 &current_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 &center)
{
}
-
-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 &center, 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: