diff options
Diffstat (limited to 'indra/newview/lltoolgrab.cpp')
| -rw-r--r-- | indra/newview/lltoolgrab.cpp | 542 |
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: |
