summaryrefslogtreecommitdiff
path: root/indra/newview/lltoolgrab.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lltoolgrab.cpp')
-rw-r--r--indra/newview/lltoolgrab.cpp542
1 files changed, 373 insertions, 169 deletions
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 3f19ed4330..b6c0f662e5 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -2,30 +2,25 @@
* @file lltoolgrab.cpp
* @brief LLToolGrab class implementation
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -45,7 +40,7 @@
// newview headers
#include "llagent.h"
-//#include "llfloateravatarinfo.h"
+#include "llagentcamera.h"
#include "lldrawable.h"
#include "llfloatertools.h"
#include "llhudeffect.h"
@@ -60,7 +55,7 @@
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llworld.h"
const S32 SLOP_DIST_SQ = 4;
@@ -69,22 +64,24 @@ const S32 SLOP_DIST_SQ = 4;
BOOL gGrabBtnVertical = FALSE;
BOOL gGrabBtnSpin = FALSE;
LLTool* gGrabTransientTool = NULL;
-LLToolGrab *gToolGrab = NULL;
extern BOOL gDebugClicks;
//
// Methods
//
LLToolGrab::LLToolGrab( LLToolComposite* composite )
-: LLTool( "Grab", composite ),
+: LLTool( std::string("Grab"), composite ),
mMode( GRAB_INACTIVE ),
mVerticalDragging( FALSE ),
mHitLand(FALSE),
- mHitObjectID(),
- mGrabObject( NULL ),
- mMouseDownX( -1 ),
- mMouseDownY( -1 ),
+ mLastMouseX(0),
+ mLastMouseY(0),
+ mAccumDeltaX(0),
+ mAccumDeltaY(0),
mHasMoved( FALSE ),
+ mOutsideSlop(FALSE),
+ mDeselectedThisClick(FALSE),
+ mLastFace(0),
mSpinGrabbing( FALSE ),
mSpinRotation(),
mHideBuildHighlight(FALSE)
@@ -132,57 +129,55 @@ 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 && !gSelectMgr->getSelection()->isEmpty())
+ if (!extend_select && !LLSelectMgr::getInstance()->getSelection()->isEmpty())
{
- gSelectMgr->deselectAll();
- gToolGrab->mDeselectedThisClick = TRUE;
+ LLSelectMgr::getInstance()->deselectAll();
+ LLToolGrab::getInstance()->mDeselectedThisClick = TRUE;
}
else
{
- gToolGrab->mDeselectedThisClick = FALSE;
+ LLToolGrab::getInstance()->mDeselectedThisClick = FALSE;
}
// if not over object, do nothing
if (!objectp)
{
- gToolGrab->setMouseCapture(TRUE);
- gToolGrab->mMode = GRAB_NOOBJECT;
- gToolGrab->mHitObjectID.setNull();
+ LLToolGrab::getInstance()->setMouseCapture(TRUE);
+ LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT;
+ LLToolGrab::getInstance()->mGrabPick.mObjectID.setNull();
}
else
{
- gToolGrab->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
@@ -203,8 +198,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();
@@ -217,22 +210,29 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas
if (!objectp->usePhysics())
{
- // In mouselook, we shouldn't be able to grab non-physical,
- // non-touchable objects. If it has a touch handler, we
- // do grab it (so llDetectedGrab works), but movement is
- // blocked on the server side. JC
- if (gAgent.cameraMouselook() && !script_touch)
+ if (script_touch)
{
- mMode = GRAB_LOCKED;
+ mMode = GRAB_NONPHYSICAL; // if it has a script, use the non-physical grab
}
else
{
- mMode = GRAB_NONPHYSICAL;
+ // In mouselook, we shouldn't be able to grab non-physical,
+ // non-touchable objects. If it has a touch handler, we
+ // do grab it (so llDetectedGrab works), but movement is
+ // blocked on the server side. JC
+ if (gAgentCamera.cameraMouselook())
+ {
+ mMode = GRAB_LOCKED;
+ }
+ else
+ {
+ mMode = GRAB_ACTIVE_CENTER;
+ }
+
+ gViewerWindow->hideCursor();
+ gViewerWindow->moveCursorToCenter();
+
}
- gViewerWindow->hideCursor();
- gViewerWindow->moveCursorToCenter();
- // Don't bail out here, go on and grab so buttons can get
- // their "touched" event.
}
else if( !objectp->permMove() )
{
@@ -255,35 +255,33 @@ 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;
-
- mGrabOffset.clearVec();
+ mVerticalDragging = (info.mKeyMask == MASK_VERTICAL) || gGrabBtnVertical;
- mVerticalDragging = (mask == MASK_VERTICAL) || gGrabBtnVertical;
+ startGrab();
- startGrab(x, y);
-
- if ((mask == MASK_SPIN) || gGrabBtnSpin)
+ if ((info.mKeyMask == MASK_SPIN) || gGrabBtnSpin)
{
startSpin();
}
- gSelectMgr->updateSelectionCenter(); // update selection beam
+ 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 );
- gAgent.setLookAt(LOOKAT_TARGET_SELECT, edit_object, local_edit_point );
+ gAgentCamera.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point );
+ gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, edit_object, local_edit_point );
}
// on transient grabs (clicks on world objects), kill the grab immediately
@@ -301,10 +299,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;
@@ -313,8 +316,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() );
}
@@ -322,6 +325,12 @@ void LLToolGrab::stopSpin()
{
mSpinGrabbing = FALSE;
+ LLViewerObject* objectp = mGrabPick.getObject();
+ if (!objectp)
+ {
+ return;
+ }
+
LLMessageSystem *msg = gMessageSystem;
switch(mMode)
{
@@ -333,8 +342,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:
@@ -346,11 +355,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();
@@ -359,7 +374,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);
@@ -370,7 +385,7 @@ void LLToolGrab::startGrab(S32 x, S32 y)
// This planar drag starts at the grab point
mDragStartPointGlobal = grab_start_global;
- mDragStartFromCamera = grab_start_global - gAgent.getCameraPositionGlobal();
+ mDragStartFromCamera = grab_start_global - gAgentCamera.getCameraPositionGlobal();
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ObjectGrab);
@@ -378,22 +393,34 @@ 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;
mGrabTimer.reset();
+
+ mLastUVCoords = mGrabPick.mUVCoords;
+ mLastSTCoords = mGrabPick.mSTCoords;
+ mLastFace = mGrabPick.mObjectFace;
+ mLastIntersection = mGrabPick.mIntersection;
+ mLastNormal = mGrabPick.mNormal;
+ mLastBinormal = mGrabPick.mBinormal;
+ mLastGrabPos = LLVector3(-1.f, -1.f, -1.f);
}
BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
{
- mLastMouseX = x;
- mLastMouseY = y;
-
if (!gViewerWindow->getLeftMouseDown())
{
gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
@@ -405,9 +432,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
@@ -420,18 +450,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);
@@ -460,26 +496,23 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
// ...switch to horizontal dragging
mVerticalDragging = FALSE;
- mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, mGrabObject);
- mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();
+ mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, objectp);
+ mDragStartFromCamera = mDragStartPointGlobal - gAgentCamera.getCameraPositionGlobal();
}
else if (!mVerticalDragging && (mask == MASK_VERTICAL) )
{
// ...switch to vertical dragging
mVerticalDragging = TRUE;
- mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, mGrabObject);
- mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();
+ mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, objectp);
+ mDragStartFromCamera = mDragStartPointGlobal - gAgentCamera.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);
+ S32 dx = x - (gViewerWindow->getWorldViewWidthScaled() / 2);
+ S32 dy = y - (gViewerWindow->getWorldViewHeightScaled() / 2);
if (dx != 0 || dy != 0)
{
@@ -505,7 +538,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
LLQuaternion rotation_around_vertical( dx*RADIANS_PER_PIXEL_X, up );
// y motion maps to rotation around left axis
- const LLVector3 &agent_left = gCamera->getLeftAxis();
+ const LLVector3 &agent_left = LLViewerCamera::getInstance()->getLeftAxis();
LLQuaternion rotation_around_left( dy*RADIANS_PER_PIXEL_Y, agent_left );
// compose with current rotation
@@ -519,9 +552,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
{
@@ -530,14 +563,14 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
//------------------------------------------------------
LLVector3d x_part;
- x_part.setVec(gCamera->getLeftAxis());
+ x_part.setVec(LLViewerCamera::getInstance()->getLeftAxis());
x_part.mdV[VZ] = 0.0;
x_part.normVec();
LLVector3d y_part;
if( mVerticalDragging )
{
- y_part.setVec(gCamera->getUpAxis());
+ y_part.setVec(LLViewerCamera::getInstance()->getUpAxis());
// y_part.setVec(0.f, 0.f, 1.f);
}
else
@@ -549,8 +582,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.
@@ -560,7 +593,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
// need to return offset from mGrabStartPoint
LLVector3d grab_point_global;
- grab_point_global = gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
+ grab_point_global = gAgentCamera.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
/* Snap to grid disabled for grab tool - very confusing
// Handle snapping to grid, but only when the tool is formally selected.
@@ -579,7 +612,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
*/
// Don't let object centers go underground.
- F32 land_height = gWorldPointer->resolveLandHeightGlobal(grab_point_global);
+ F32 land_height = LLWorld::getInstance()->resolveLandHeightGlobal(grab_point_global);
if (grab_point_global.mdV[VZ] < land_height)
{
@@ -592,49 +625,49 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
grab_point_global.mdV[VZ] = MAX_OBJECT_Z;
}
- grab_point_global = gWorldp->clipToVisibleRegions(mDragStartPointGlobal, grab_point_global);
+ grab_point_global = LLWorld::getInstance()->clipToVisibleRegions(mDragStartPointGlobal, grab_point_global);
// propagate constrained grab point back to grab offset
- mGrabHiddenOffsetFromCamera = grab_point_global - gAgent.getCameraPositionGlobal();
+ mGrabHiddenOffsetFromCamera = grab_point_global - gAgentCamera.getCameraPositionGlobal();
// Handle auto-rotation at screen edge.
LLVector3 grab_pos_agent = gAgent.getPosAgentFromGlobal( grab_point_global );
- LLCoordGL grab_center_gl( gViewerWindow->getWindowWidth() / 2, gViewerWindow->getWindowHeight() / 2);
- gCamera->projectPosAgentToScreen(grab_pos_agent, grab_center_gl);
+ LLCoordGL grab_center_gl( gViewerWindow->getWorldViewWidthScaled() / 2, gViewerWindow->getWorldViewHeightScaled() / 2);
+ LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_pos_agent, grab_center_gl);
- const S32 ROTATE_H_MARGIN = gViewerWindow->getWindowWidth() / 20;
+ const S32 ROTATE_H_MARGIN = gViewerWindow->getWorldViewWidthScaled() / 20;
const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD;
const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
// ...build mode moves camera about focus point
if (grab_center_gl.mX < ROTATE_H_MARGIN)
{
- if (gAgent.getFocusOnAvatar())
+ if (gAgentCamera.getFocusOnAvatar())
{
gAgent.yaw(rotate_angle);
}
else
{
- gAgent.cameraOrbitAround(rotate_angle);
+ gAgentCamera.cameraOrbitAround(rotate_angle);
}
}
- else if (grab_center_gl.mX > gViewerWindow->getWindowWidth() - ROTATE_H_MARGIN)
+ else if (grab_center_gl.mX > gViewerWindow->getWorldViewWidthScaled() - ROTATE_H_MARGIN)
{
- if (gAgent.getFocusOnAvatar())
+ if (gAgentCamera.getFocusOnAvatar())
{
gAgent.yaw(-rotate_angle);
}
else
{
- gAgent.cameraOrbitAround(-rotate_angle);
+ gAgentCamera.cameraOrbitAround(-rotate_angle);
}
}
// Don't move above top of screen or below bottom
- if ((grab_center_gl.mY < gViewerWindow->getWindowHeight() - 6)
+ if ((grab_center_gl.mY < gViewerWindow->getWorldViewHeightScaled() - 6)
&& (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);
@@ -642,34 +675,42 @@ 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() );
}
}
gViewerWindow->moveCursorToCenter();
- gSelectMgr->updateSelectionCenter();
+ LLSelectMgr::getInstance()->updateSelectionCenter();
}
// once we've initiated a drag, lock the camera down
if (mHasMoved)
{
- if (!gAgent.cameraMouselook() &&
- !mGrabObject->isHUDAttachment() &&
- mGrabObject->getRoot() == gAgent.getAvatarObject()->getRoot())
+ if (!gAgentCamera.cameraMouselook() &&
+ !objectp->isHUDAttachment() &&
+ objectp->getRoot() == gAgentAvatarp->getRoot())
{
// force focus to point in space where we were looking previously
- gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null);
- gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+ gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
}
else
{
- gAgent.clearFocusObject();
+ gAgentCamera.clearFocusObject();
}
}
@@ -680,31 +721,165 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
}
-// Not dragging. Just showing affordances
-void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
+void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask)
{
- const F32 ROTATE_ANGLE_PER_SECOND = 40.f * DEG_TO_RAD;
- const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
+ 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();
- // Look for cursor against the edge of the screen
- // Only works in fullscreen
- if (gSavedSettings.getBOOL("FullScreen"))
+ // 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)
{
- if (gAgent.cameraThirdPerson() )
+ //--------------------------------------------------
+ // 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)
{
- if (x == 0)
+ mAccumDeltaX += dx;
+ mAccumDeltaY += dy;
+
+ S32 dist_sq = mAccumDeltaX * mAccumDeltaX + mAccumDeltaY * mAccumDeltaY;
+ if (dist_sq > SLOP_DIST_SQ)
{
- gAgent.yaw(rotate_angle);
- //gAgent.setControlFlags(AGENT_CONTROL_YAW_POS);
+ mOutsideSlop = TRUE;
}
- else if (x == (gViewerWindow->getWindowWidth() - 1) )
+
+ // 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
{
- gAgent.yaw(-rotate_angle);
- //gAgent.setControlFlags(AGENT_CONTROL_YAW_NEG);
+ // 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 = gAgentCamera.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
+ grab_pos_region = objectp->getRegion()->getPosRegionFromGlobal( grab_point_global );
+ }
+
+
+ // only send message if something has changed since last message
+
+ BOOL changed_since_last_update = FALSE;
+
+ // test if touch data needs to be updated
+ if ((pick.mObjectFace != mLastFace) ||
+ (pick.mUVCoords != mLastUVCoords) ||
+ (pick.mSTCoords != mLastSTCoords) ||
+ (pick.mIntersection != mLastIntersection) ||
+ (pick.mNormal != mLastNormal) ||
+ (pick.mBinormal != mLastBinormal) ||
+ (grab_pos_region != mLastGrabPos))
+ {
+ changed_since_last_update = TRUE;
}
+ if (changed_since_last_update)
+ {
+ 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() );
+
+ mLastUVCoords = pick.mUVCoords;
+ mLastSTCoords = pick.mSTCoords;
+ mLastFace = pick.mObjectFace;
+ mLastIntersection = pick.mIntersection;
+ mLastNormal= pick.mNormal;
+ mLastBinormal= pick.mBinormal;
+ mLastGrabPos = grab_pos_region;
+ }
+
+ // 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();
+ gAgentCamera.setPointAt(POINTAT_TARGET_GRAB, objectp, local_edit_point );
+ gAgentCamera.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)
+{
// JC - TODO - change cursor based on gGrabBtnVertical, gGrabBtnSpin
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolGrab (inactive-not over editable object)" << llendl;
gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
@@ -720,7 +895,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;
@@ -785,50 +960,56 @@ 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))
+ if( !gAgentCamera.cameraMouselook()
+ && (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;
- LLUI::setCursorPositionScreen(x, y);
+ S32 x = mGrabPick.mMousePt.mX + mAccumDeltaX;
+ S32 y = mGrabPick.mMousePt.mY + mAccumDeltaY;
+ LLUI::setMousePositionScreen(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 (gCamera->projectPosAgentToScreen(grab_point_agent, gl_point))
+ if (LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_point_agent, gl_point))
{
- LLUI::setCursorPositionScreen(gl_point.mX, gl_point.mY);
+ LLUI::setMousePositionScreen(gl_point.mX, gl_point.mY);
}
}
else
{
// ...move cursor back to click position
- LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY);
+ LLUI::setMousePositionScreen(mGrabPick.mMousePt.mX, mGrabPick.mMousePt.mY);
}
gViewerWindow->showCursor();
}
stopGrab();
+ if (mSpinGrabbing)
stopSpin();
+
mMode = GRAB_INACTIVE;
mHideBuildHighlight = FALSE;
- mGrabObject = NULL;
+ mGrabPick.mObjectID.setNull();
- gSelectMgr->updateSelectionCenter();
- gAgent.setPointAt(POINTAT_TARGET_CLEAR);
- gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
+ LLSelectMgr::getInstance()->updateSelectionCenter();
+ gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR);
+ gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
dialog_refresh_all();
}
@@ -836,6 +1017,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)
@@ -848,11 +1047,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(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());
mVerticalDragging = FALSE;
- mGrabOffset.clearVec();
break;
case GRAB_NOOBJECT:
@@ -874,14 +1080,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();
}
@@ -897,7 +1101,7 @@ LLVector3d LLToolGrab::getGrabPointGlobal()
case GRAB_ACTIVE_CENTER:
case GRAB_NONPHYSICAL:
case GRAB_LOCKED:
- return gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
+ return gAgentCamera.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
case GRAB_NOOBJECT:
case GRAB_INACTIVE: