svn merge -r92720:92721 svn+ssh://svn.lindenlab.com/svn/linden/branches/uv-picking-merge

QAR-698 / DEV-9985 add touch "position" information to touch-events in LSL
master
Karl Steifvater 2008-07-23 21:20:19 +00:00
parent bc39ad916e
commit 52562e2e66
72 changed files with 2039 additions and 1372 deletions

View File

@ -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;
}

View File

@ -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;
LLVector3 norm = V1 % V2;
F32 dotprod = norm * vect;
float fAWdU[3];
LLVector3 dir;
LLVector3 diff;
if(dotprod < 0)
for (U32 i = 0; i < 3; i++)
{
//Find point of intersect to triangle plane.
//find t to intersect point
F32 t = -(norm * (linept-pt1))/dotprod;
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;
}
// if ds is neg line started past triangle so can't hit triangle.
if (t > 0)
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;
}
// 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;
/* if determinant is near zero, ray lies in plane of triangle */
F32 det = edge1 * pvec;
if (!two_sided)
{
if (det < F_APPROXIMATELY_ZERO)
{
return FALSE;
}
/* calculate distance from vert0 to ray origin */
LLVector3 tvec = orig - vert0;
/* 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))
{
if(check_same_clock_dir(pt3, pt1, pt_int, norm))
{
// answer in pt_int is insde triangle
linept.setVec(pt_int);
return TRUE;
}
}
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;
}
return FALSE;
else // two sided
{
if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO)
{
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;
}
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;
LLVector3 vec = end - start;
S32 start_face;
S32 end_face;
for (S32 i = 0; i < getNumFaces(); i++)
if (face == -1) // ALL_SIDES
{
const LLVolumeFace& face = getVolumeFace(i);
start_face = 0;
end_face = getNumFaces() - 1;
}
else
{
start_face = face;
end_face = face;
}
for (U32 j = 0; j < face.mIndices.size()/3; j++)
LLVector3 dir = end - start;
F32 closest_t = 2.f; // must be larger than 1
for (S32 i = start_face; i <= end_face; 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))
{
//approximate normal
S32 v1 = face.mIndices[j*3+0];
S32 v2 = face.mIndices[j*3+1];
S32 v3 = face.mIndices[j*3+2];
LLVector3 norm = (face.mVertices[v2].mPosition - face.mVertices[v1].mPosition) %
(face.mVertices[v3].mPosition - face.mVertices[v2].mPosition);
if (norm.magVecSquared() >= 0.00000001f)
if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them
{
//get view vector
//LLVector3 view = (start-face.mVertices[v1].mPosition);
//if (view * norm < 0.0f)
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];
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 (LLTriangleLineSegmentIntersect( face.mVertices[v1].mPosition,
face.mVertices[v2].mPosition,
face.mVertices[v3].mPosition,
end,
vec))
if ((t >= 0.f) && // if hit is after start
(t <= 1.f) && // and before end
(t < closest_t)) // and this hit is closer
{
closest_t = t;
hit_face = i;
if (intersection != NULL)
{
*intersection = start + dir * closest_t;
}
if (tex_coord != NULL)
{
*tex_coord = ((1.f - a - b) * face.mVertices[index1].mTexCoord +
a * face.mVertices[index2].mTexCoord +
b * face.mVertices[index3].mTexCoord);
}
if (normal != NULL)
{
*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

View File

@ -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

View File

@ -33,6 +33,7 @@
//#include "vmath.h"
#include "v2math.h"
#include "v3math.h"
#include "v4math.h"
#include "m4math.h"
#include "m3math.h"

View File

@ -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

View File

@ -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];

View File

@ -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);

View File

@ -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;

View File

@ -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");

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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>

View File

@ -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));

View File

@ -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)

View File

@ -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();

View File

@ -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);
LLGLSUVSelect object_select;
// use red/blue gradient to get coarse UV coordinates
renderSelected(red_blue_imagep, LLColor4::white);
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);
static F32 bias = 0.f;
static F32 factor = -10.f;
glPolygonOffset(factor, bias);
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);
}
// 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);
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);
}
}
}
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);
}
}
}
//restore blend func
gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
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;

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -155,6 +155,7 @@ protected:
BOOL mInSnapRegime;
LLSafeHandle<LLObjectSelection> mObjectSelection;
EManipPart mHighlightedPart;
EManipPart mManipPart;
static F32 sHelpTextVisibleTime;
static F32 sHelpTextFadeTime;

View File

@ -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);

View File

@ -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;

View File

@ -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
{

View File

@ -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;

View File

@ -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
{

View File

@ -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;

View File

@ -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() :

View File

@ -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;
}
virtual void visit(const LLSpatialGroup::OctreeNode* branch)
{
for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
{
check(*i);
}
return mHit;
}
virtual bool check(LLDrawable* drawable)
{
if (drawable->isSpatialBridge())
{
LLSpatialPartition *part = drawable->asPartition();
check(part->mOctree);
}
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,

View File

@ -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);

View File

@ -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 )

View File

@ -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 );
}
}

View File

@ -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;

View File

@ -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 );

View File

@ -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:

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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();
}

View File

@ -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

View File

@ -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)
{

View File

@ -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:

View File

@ -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()
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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()

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -694,5 +694,3 @@ void LLViewerMedia::setMimeType(std::string mime_type)
{
sViewerMediaImpl.mMimeType = mime_type;
}

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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(); }

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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);
}
}

View File

@ -636,8 +636,6 @@ public:
// special purpose joint for HUD attachments
//--------------------------------------------------------------------
LLViewerJoint *mScreenp;
F32 mHUDTargetZoom;
F32 mHUDCurZoom;
//--------------------------------------------------------------------
// mesh objects for skinned avatar

View File

@ -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)
{
end = volumePositionToAgent(v_end);
ret = TRUE;
*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)
{
*bi_normal = volumeDirectionToAgent(*bi_normal);
(*bi_normal).normVec();
}
return TRUE;
}
}
return ret;
#endif
return FALSE;
}
U32 LLVOVolume::getPartitionType() const

View File

@ -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; }

View File

@ -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;

View File

@ -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:

View File

@ -2436,6 +2436,15 @@ version 2.0
{ LocalID U32 }
{ GrabOffset LLVector3 }
}
{
SurfaceInfo Variable
{ UVCoord LLVector3 }
{ STCoord LLVector3 }
{ FaceIndex S32 }
{ Position LLVector3 }
{ Normal LLVector3 }
{ Binormal LLVector3 }
}
}
@ -2457,6 +2466,16 @@ version 2.0
{ GrabPosition LLVector3 } // LLVector3, region local
{ TimeSinceLast U32 }
}
{
SurfaceInfo Variable
{ UVCoord LLVector3 }
{ STCoord LLVector3 }
{ FaceIndex S32 }
{ Position LLVector3 }
{ Normal LLVector3 }
{ Binormal LLVector3 }
}
}
@ -2472,6 +2491,15 @@ version 2.0
ObjectData Single
{ LocalID U32 }
}
{
SurfaceInfo Variable
{ UVCoord LLVector3 }
{ STCoord LLVector3 }
{ FaceIndex S32 }
{ Position LLVector3 }
{ Normal LLVector3 }
{ Binormal LLVector3 }
}
}