00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "lltoolgrab.h"
00035
00036
00037 #include "indra_constants.h"
00038 #include "llviewercontrol.h"
00039 #include "llquaternion.h"
00040 #include "llbox.h"
00041 #include "message.h"
00042 #include "llview.h"
00043 #include "llfontgl.h"
00044 #include "llui.h"
00045
00046
00047 #include "llagent.h"
00048
00049 #include "lldrawable.h"
00050 #include "llfloatertools.h"
00051 #include "llhudeffect.h"
00052 #include "llhudmanager.h"
00053 #include "llregionposition.h"
00054 #include "llselectmgr.h"
00055 #include "llstatusbar.h"
00056 #include "lltoolmgr.h"
00057 #include "lltoolpie.h"
00058 #include "llviewercamera.h"
00059 #include "llviewerobject.h"
00060 #include "llviewerobjectlist.h"
00061 #include "llviewerregion.h"
00062 #include "llviewerwindow.h"
00063 #include "llvoavatar.h"
00064 #include "llworld.h"
00065 #include "viewer.h"
00066
00067 const S32 SLOP_DIST_SQ = 4;
00068
00069
00070 BOOL gGrabBtnVertical = FALSE;
00071 BOOL gGrabBtnSpin = FALSE;
00072 LLTool* gGrabTransientTool = NULL;
00073 LLToolGrab *gToolGrab = NULL;
00074 extern BOOL gDebugClicks;
00075
00076
00077
00078
00079 LLToolGrab::LLToolGrab( LLToolComposite* composite )
00080 : LLTool( "Grab", composite ),
00081 mMode( GRAB_INACTIVE ),
00082 mVerticalDragging( FALSE ),
00083 mHitLand(FALSE),
00084 mHitObjectID(),
00085 mGrabObject( NULL ),
00086 mMouseDownX( -1 ),
00087 mMouseDownY( -1 ),
00088 mHasMoved( FALSE ),
00089 mSpinGrabbing( FALSE ),
00090 mSpinRotation(),
00091 mHideBuildHighlight(FALSE)
00092 { }
00093
00094 LLToolGrab::~LLToolGrab()
00095 { }
00096
00097
00098
00099 void LLToolGrab::handleSelect()
00100 {
00101 if(gFloaterTools)
00102 {
00103
00104 gFloaterTools->setStatusText("grab");
00105 }
00106 gGrabBtnVertical = FALSE;
00107 gGrabBtnSpin = FALSE;
00108 }
00109
00110 void LLToolGrab::handleDeselect()
00111 {
00112 if( hasMouseCapture() )
00113 {
00114 setMouseCapture( FALSE );
00115 }
00116
00117 }
00118
00119 BOOL LLToolGrab::handleDoubleClick(S32 x, S32 y, MASK mask)
00120 {
00121 if (gDebugClicks)
00122 {
00123 llinfos << "LLToolGrab handleDoubleClick (becoming mouseDown)" << llendl;
00124 }
00125
00126 return FALSE;
00127 }
00128
00129 BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask)
00130 {
00131 if (gDebugClicks)
00132 {
00133 llinfos << "LLToolGrab handleMouseDown" << llendl;
00134 }
00135
00136 mHitLand = FALSE;
00137
00138
00139 LLTool::handleMouseDown(x, y, mask);
00140
00141 if (!gAgent.leftButtonGrabbed())
00142 {
00143
00144 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback, TRUE);
00145 }
00146 return TRUE;
00147 }
00148
00149 void LLToolGrab::pickCallback(S32 x, S32 y, MASK mask)
00150 {
00151 LLViewerObject *objectp = gObjectList.findObject( gLastHitObjectID );
00152
00153 BOOL extend_select = (mask & MASK_SHIFT);
00154
00155 if (!extend_select && !gSelectMgr->getSelection()->isEmpty())
00156 {
00157 gSelectMgr->deselectAll();
00158 gToolGrab->mDeselectedThisClick = TRUE;
00159 }
00160 else
00161 {
00162 gToolGrab->mDeselectedThisClick = FALSE;
00163 }
00164
00165
00166 if (!objectp)
00167 {
00168 gToolGrab->setMouseCapture(TRUE);
00169 gToolGrab->mMode = GRAB_NOOBJECT;
00170 gToolGrab->mHitObjectID.setNull();
00171 }
00172 else
00173 {
00174 gToolGrab->handleObjectHit(objectp, x, y, mask);
00175 }
00176 }
00177
00178 BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mask)
00179 {
00180 mMouseDownX = x;
00181 mMouseDownY = y;
00182 mMouseMask = mask;
00183
00184 if (gDebugClicks)
00185 {
00186 llinfos << "LLToolGrab handleObjectHit " << mMouseDownX << "," << mMouseDownY << llendl;
00187 }
00188
00189 if (NULL == objectp)
00190 {
00191 llwarns << "objectp was NULL; returning FALSE" << llendl;
00192 return FALSE;
00193 }
00194
00195 if (objectp->isAvatar())
00196 {
00197 if (gGrabTransientTool)
00198 {
00199 gBasicToolset->selectTool( gGrabTransientTool );
00200 gGrabTransientTool = NULL;
00201 }
00202 return TRUE;
00203 }
00204
00205 setMouseCapture( TRUE );
00206
00207 mHitObjectID = objectp->getID();
00208
00209
00210
00211
00212 LLViewerObject* parent = objectp->getRootEdit();
00213 BOOL script_touch = (objectp->flagHandleTouch()) || (parent && parent->flagHandleTouch());
00214
00215
00216
00217 mHideBuildHighlight = script_touch || objectp->usePhysics();
00218
00219 if (!objectp->usePhysics())
00220 {
00221
00222
00223
00224
00225 if (gAgent.cameraMouselook() && !script_touch)
00226 {
00227 mMode = GRAB_LOCKED;
00228 }
00229 else
00230 {
00231 mMode = GRAB_NONPHYSICAL;
00232 }
00233 gViewerWindow->hideCursor();
00234 gViewerWindow->moveCursorToCenter();
00235
00236
00237 }
00238 else if( !objectp->permMove() )
00239 {
00240
00241 mMode = GRAB_LOCKED;
00242
00243
00244
00245 }
00246 else
00247 {
00248
00249
00250
00251 mMode = GRAB_ACTIVE_CENTER;
00252
00253 gViewerWindow->hideCursor();
00254 gViewerWindow->moveCursorToCenter();
00255 }
00256
00257
00258
00259 mAccumDeltaX = 0;
00260 mAccumDeltaY = 0;
00261 mHasMoved = FALSE;
00262 mOutsideSlop = FALSE;
00263
00264 mGrabObject = objectp;
00265
00266 mGrabOffset.clearVec();
00267
00268 mVerticalDragging = (mask == MASK_VERTICAL) || gGrabBtnVertical;
00269
00270 startGrab(x, y);
00271
00272 if ((mask == MASK_SPIN) || gGrabBtnSpin)
00273 {
00274 startSpin();
00275 }
00276
00277 gSelectMgr->updateSelectionCenter();
00278
00279
00280 LLViewerObject *edit_object = gObjectList.findObject(mHitObjectID);
00281 if (edit_object)
00282 {
00283 LLVector3 local_edit_point = gAgent.getPosAgentFromGlobal(gLastHitNonFloraPosGlobal);
00284 local_edit_point -= edit_object->getPositionAgent();
00285 local_edit_point = local_edit_point * ~edit_object->getRenderRotation();
00286 gAgent.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point );
00287 gAgent.setLookAt(LOOKAT_TARGET_SELECT, edit_object, local_edit_point );
00288 }
00289
00290
00291 if (!gViewerWindow->getLeftMouseDown()
00292 && gGrabTransientTool
00293 && (mMode == GRAB_NONPHYSICAL || mMode == GRAB_LOCKED))
00294 {
00295 gBasicToolset->selectTool( gGrabTransientTool );
00296 gGrabTransientTool = NULL;
00297 }
00298
00299 return TRUE;
00300 }
00301
00302
00303 void LLToolGrab::startSpin()
00304 {
00305 mSpinGrabbing = TRUE;
00306
00307
00308 LLViewerObject *root = (LLViewerObject *)mGrabObject->getRoot();
00309 mSpinRotation = root->getRotation();
00310
00311 LLMessageSystem *msg = gMessageSystem;
00312 msg->newMessageFast(_PREHASH_ObjectSpinStart);
00313 msg->nextBlockFast(_PREHASH_AgentData);
00314 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00315 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00316 msg->nextBlockFast(_PREHASH_ObjectData);
00317 msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() );
00318 msg->sendMessage( mGrabObject->getRegion()->getHost() );
00319 }
00320
00321
00322 void LLToolGrab::stopSpin()
00323 {
00324 mSpinGrabbing = FALSE;
00325
00326 LLMessageSystem *msg = gMessageSystem;
00327 switch(mMode)
00328 {
00329 case GRAB_ACTIVE_CENTER:
00330 case GRAB_NONPHYSICAL:
00331 case GRAB_LOCKED:
00332 msg->newMessageFast(_PREHASH_ObjectSpinStop);
00333 msg->nextBlockFast(_PREHASH_AgentData);
00334 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00335 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00336 msg->nextBlockFast(_PREHASH_ObjectData);
00337 msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() );
00338 msg->sendMessage( mGrabObject->getRegion()->getHost() );
00339 break;
00340
00341 case GRAB_NOOBJECT:
00342 case GRAB_INACTIVE:
00343 default:
00344
00345 break;
00346 }
00347 }
00348
00349
00350 void LLToolGrab::startGrab(S32 x, S32 y)
00351 {
00352
00353
00354 LLViewerObject *root = (LLViewerObject *)mGrabObject->getRoot();
00355
00356
00357 LLVector3d grab_start_global = root->getPositionGlobal();
00358
00359
00360
00361
00362
00363 LLVector3d grab_offsetd = root->getPositionGlobal() - mGrabObject->getPositionGlobal();
00364
00365 LLVector3 grab_offset;
00366 grab_offset.setVec(grab_offsetd);
00367
00368 LLQuaternion rotation = root->getRotation();
00369 rotation.conjQuat();
00370 grab_offset = grab_offset * rotation;
00371
00372
00373 mDragStartPointGlobal = grab_start_global;
00374 mDragStartFromCamera = grab_start_global - gAgent.getCameraPositionGlobal();
00375
00376 LLMessageSystem *msg = gMessageSystem;
00377 msg->newMessageFast(_PREHASH_ObjectGrab);
00378 msg->nextBlockFast(_PREHASH_AgentData);
00379 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00380 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00381 msg->nextBlockFast(_PREHASH_ObjectData);
00382 msg->addU32Fast(_PREHASH_LocalID, mGrabObject->mLocalID);
00383 msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset );
00384 msg->sendMessage( mGrabObject->getRegion()->getHost());
00385
00386 mGrabOffsetFromCenterInitial = grab_offset;
00387 mGrabHiddenOffsetFromCamera = mDragStartFromCamera;
00388
00389 mGrabTimer.reset();
00390 }
00391
00392
00393 BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
00394 {
00395 mLastMouseX = x;
00396 mLastMouseY = y;
00397
00398 if (!gViewerWindow->getLeftMouseDown())
00399 {
00400 gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
00401 setMouseCapture(FALSE);
00402 return TRUE;
00403 }
00404
00405
00406 switch( mMode )
00407 {
00408 case GRAB_ACTIVE_CENTER:
00409 case GRAB_NONPHYSICAL:
00410 handleHoverActive( x, y, mask );
00411 break;
00412
00413 case GRAB_INACTIVE:
00414 handleHoverInactive( x, y, mask );
00415 break;
00416
00417 case GRAB_NOOBJECT:
00418 case GRAB_LOCKED:
00419 handleHoverFailed( x, y, mask );
00420 break;
00421
00422 }
00423
00424 return TRUE;
00425 }
00426
00427
00428
00429
00430
00431 void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
00432 {
00433 llassert( hasMouseCapture() );
00434 llassert( mGrabObject );
00435 if (mGrabObject->isDead())
00436 {
00437
00438 setMouseCapture(FALSE);
00439 return;
00440 }
00441
00442
00443
00444
00445 if (mSpinGrabbing && !(mask == MASK_SPIN) && !gGrabBtnSpin)
00446 {
00447
00448 stopSpin();
00449 }
00450 else if (!mSpinGrabbing && (mask == MASK_SPIN) )
00451 {
00452
00453 startSpin();
00454 }
00455
00456
00457
00458
00459 if (mVerticalDragging && !(mask == MASK_VERTICAL) && !gGrabBtnVertical)
00460 {
00461
00462 mVerticalDragging = FALSE;
00463
00464 mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, mGrabObject);
00465 mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();
00466 }
00467 else if (!mVerticalDragging && (mask == MASK_VERTICAL) )
00468 {
00469
00470 mVerticalDragging = TRUE;
00471
00472 mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, mGrabObject);
00473 mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();
00474 }
00475
00476 const F32 RADIANS_PER_PIXEL_X = 0.01f;
00477 const F32 RADIANS_PER_PIXEL_Y = 0.01f;
00478
00479 const F32 SENSITIVITY_X = 0.0075f;
00480 const F32 SENSITIVITY_Y = 0.0075f;
00481
00482 S32 dx = x - (gViewerWindow->getWindowWidth() / 2);
00483 S32 dy = y - (gViewerWindow->getWindowHeight() / 2);
00484
00485 if (dx != 0 || dy != 0)
00486 {
00487 mAccumDeltaX += dx;
00488 mAccumDeltaY += dy;
00489 S32 dist_sq = mAccumDeltaX * mAccumDeltaX + mAccumDeltaY * mAccumDeltaY;
00490 if (dist_sq > SLOP_DIST_SQ)
00491 {
00492 mOutsideSlop = TRUE;
00493 }
00494
00495
00496 mHasMoved = TRUE;
00497
00498 if (mSpinGrabbing)
00499 {
00500
00501
00502
00503
00504
00505 LLVector3 up(0.f, 0.f, 1.f);
00506 LLQuaternion rotation_around_vertical( dx*RADIANS_PER_PIXEL_X, up );
00507
00508
00509 const LLVector3 &agent_left = gCamera->getLeftAxis();
00510 LLQuaternion rotation_around_left( dy*RADIANS_PER_PIXEL_Y, agent_left );
00511
00512
00513 mSpinRotation = mSpinRotation * rotation_around_vertical;
00514 mSpinRotation = mSpinRotation * rotation_around_left;
00515
00516
00517 LLMessageSystem *msg = gMessageSystem;
00518 msg->newMessageFast(_PREHASH_ObjectSpinUpdate);
00519 msg->nextBlockFast(_PREHASH_AgentData);
00520 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00521 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00522 msg->nextBlockFast(_PREHASH_ObjectData);
00523 msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() );
00524 msg->addQuatFast(_PREHASH_Rotation, mSpinRotation );
00525 msg->sendMessage( mGrabObject->getRegion()->getHost() );
00526 }
00527 else
00528 {
00529
00530
00531
00532
00533 LLVector3d x_part;
00534 x_part.setVec(gCamera->getLeftAxis());
00535 x_part.mdV[VZ] = 0.0;
00536 x_part.normVec();
00537
00538 LLVector3d y_part;
00539 if( mVerticalDragging )
00540 {
00541 y_part.setVec(gCamera->getUpAxis());
00542
00543 }
00544 else
00545 {
00546
00547 y_part = x_part % LLVector3d::z_axis;
00548 y_part.mdV[VZ] = 0.0;
00549 y_part.normVec();
00550 }
00551
00552 mGrabHiddenOffsetFromCamera = mGrabHiddenOffsetFromCamera
00553 + (x_part * (-dx * SENSITIVITY_X))
00554 + (y_part * ( dy * SENSITIVITY_Y));
00555
00556
00557
00558 F32 dt = mGrabTimer.getElapsedTimeAndResetF32();
00559 U32 dt_milliseconds = (U32) (1000.f * dt);
00560
00561
00562 LLVector3d grab_point_global;
00563
00564 grab_point_global = gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 F32 land_height = gWorldPointer->resolveLandHeightGlobal(grab_point_global);
00584
00585 if (grab_point_global.mdV[VZ] < land_height)
00586 {
00587 grab_point_global.mdV[VZ] = land_height;
00588 }
00589
00590
00591 if (grab_point_global.mdV[VZ] > MAX_OBJECT_Z)
00592 {
00593 grab_point_global.mdV[VZ] = MAX_OBJECT_Z;
00594 }
00595
00596 grab_point_global = gWorldp->clipToVisibleRegions(mDragStartPointGlobal, grab_point_global);
00597
00598 mGrabHiddenOffsetFromCamera = grab_point_global - gAgent.getCameraPositionGlobal();
00599
00600
00601 LLVector3 grab_pos_agent = gAgent.getPosAgentFromGlobal( grab_point_global );
00602
00603 LLCoordGL grab_center_gl( gViewerWindow->getWindowWidth() / 2, gViewerWindow->getWindowHeight() / 2);
00604 gCamera->projectPosAgentToScreen(grab_pos_agent, grab_center_gl);
00605
00606 const S32 ROTATE_H_MARGIN = gViewerWindow->getWindowWidth() / 20;
00607 const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD;
00608 const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
00609
00610 if (grab_center_gl.mX < ROTATE_H_MARGIN)
00611 {
00612 if (gAgent.getFocusOnAvatar())
00613 {
00614 gAgent.yaw(rotate_angle);
00615 }
00616 else
00617 {
00618 gAgent.cameraOrbitAround(rotate_angle);
00619 }
00620 }
00621 else if (grab_center_gl.mX > gViewerWindow->getWindowWidth() - ROTATE_H_MARGIN)
00622 {
00623 if (gAgent.getFocusOnAvatar())
00624 {
00625 gAgent.yaw(-rotate_angle);
00626 }
00627 else
00628 {
00629 gAgent.cameraOrbitAround(-rotate_angle);
00630 }
00631 }
00632
00633
00634 if ((grab_center_gl.mY < gViewerWindow->getWindowHeight() - 6)
00635 && (grab_center_gl.mY > 24))
00636 {
00637
00638 LLVector3 grab_pos_region = mGrabObject->getRegion()->getPosRegionFromGlobal( grab_point_global );
00639
00640 LLMessageSystem *msg = gMessageSystem;
00641 msg->newMessageFast(_PREHASH_ObjectGrabUpdate);
00642 msg->nextBlockFast(_PREHASH_AgentData);
00643 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00644 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00645 msg->nextBlockFast(_PREHASH_ObjectData);
00646 msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() );
00647 msg->addVector3Fast(_PREHASH_GrabOffsetInitial, mGrabOffsetFromCenterInitial );
00648 msg->addVector3Fast(_PREHASH_GrabPosition, grab_pos_region );
00649 msg->addU32Fast(_PREHASH_TimeSinceLast, dt_milliseconds );
00650 msg->sendMessage( mGrabObject->getRegion()->getHost() );
00651 }
00652 }
00653
00654 gViewerWindow->moveCursorToCenter();
00655
00656 gSelectMgr->updateSelectionCenter();
00657
00658 }
00659
00660
00661 if (mHasMoved)
00662 {
00663 if (!gAgent.cameraMouselook() &&
00664 !mGrabObject->isHUDAttachment() &&
00665 mGrabObject->getRoot() == gAgent.getAvatarObject()->getRoot())
00666 {
00667
00668 gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null);
00669 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
00670 }
00671 else
00672 {
00673 gAgent.clearFocusObject();
00674 }
00675 }
00676
00677
00678 gViewerWindow->setCursor(UI_CURSOR_ARROW);
00679
00680 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolGrab (active) [cursor hidden]" << llendl;
00681 }
00682
00683
00684
00685 void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
00686 {
00687 const F32 ROTATE_ANGLE_PER_SECOND = 40.f * DEG_TO_RAD;
00688 const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
00689
00690
00691
00692 if (gSavedSettings.getBOOL("FullScreen"))
00693 {
00694 if (gAgent.cameraThirdPerson() )
00695 {
00696 if (x == 0)
00697 {
00698 gAgent.yaw(rotate_angle);
00699
00700 }
00701 else if (x == (gViewerWindow->getWindowWidth() - 1) )
00702 {
00703 gAgent.yaw(-rotate_angle);
00704
00705 }
00706 }
00707 }
00708
00709
00710 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolGrab (inactive-not over editable object)" << llendl;
00711 gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
00712 }
00713
00714
00715 void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask)
00716 {
00717 if( GRAB_NOOBJECT == mMode )
00718 {
00719 gViewerWindow->setCursor(UI_CURSOR_NO);
00720 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolGrab (not on object)" << llendl;
00721 }
00722 else
00723 {
00724 S32 dist_sq = (x-mMouseDownX) * (x-mMouseDownX) + (y-mMouseDownY) * (y-mMouseDownY);
00725 if( mOutsideSlop || dist_sq > SLOP_DIST_SQ )
00726 {
00727 mOutsideSlop = TRUE;
00728
00729 switch( mMode )
00730 {
00731 case GRAB_LOCKED:
00732 gViewerWindow->setCursor(UI_CURSOR_GRABLOCKED);
00733 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolGrab (grab failed, no move permission)" << llendl;
00734 break;
00735
00736
00737
00738
00739
00740
00741 default:
00742 llassert(0);
00743 }
00744 }
00745 else
00746 {
00747 gViewerWindow->setCursor(UI_CURSOR_ARROW);
00748 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolGrab (grab failed but within slop)" << llendl;
00749 }
00750 }
00751 }
00752
00753
00754
00755
00756 BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask)
00757 {
00758
00759 LLTool::handleMouseUp(x, y, mask);
00760
00761 if( hasMouseCapture() )
00762 {
00763 setMouseCapture( FALSE );
00764 }
00765 mMode = GRAB_INACTIVE;
00766
00767
00768 if (gGrabTransientTool)
00769 {
00770 gBasicToolset->selectTool( gGrabTransientTool );
00771 gGrabTransientTool = NULL;
00772 }
00773
00774
00775
00776 return TRUE;
00777 }
00778
00779 void LLToolGrab::stopEditing()
00780 {
00781 if( hasMouseCapture() )
00782 {
00783 setMouseCapture( FALSE );
00784 }
00785 }
00786
00787 void LLToolGrab::onMouseCaptureLost()
00788 {
00789
00790 if( !gAgent.cameraMouselook()
00791 && (GRAB_ACTIVE_CENTER == mMode || GRAB_NONPHYSICAL == mMode))
00792 {
00793 llassert( mGrabObject );
00794
00795 if (mGrabObject->isHUDAttachment())
00796 {
00797
00798 S32 x = mMouseDownX + mAccumDeltaX;
00799 S32 y = mMouseDownY + mAccumDeltaY;
00800 LLUI::setCursorPositionScreen(x, y);
00801 }
00802 else if (mHasMoved)
00803 {
00804
00805 LLVector3 grab_point_agent = mGrabObject->getRenderPosition();
00806
00807 LLCoordGL gl_point;
00808 if (gCamera->projectPosAgentToScreen(grab_point_agent, gl_point))
00809 {
00810 LLUI::setCursorPositionScreen(gl_point.mX, gl_point.mY);
00811 }
00812 }
00813 else
00814 {
00815
00816 LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY);
00817 }
00818
00819 gViewerWindow->showCursor();
00820 }
00821
00822 stopGrab();
00823 stopSpin();
00824 mMode = GRAB_INACTIVE;
00825
00826 mHideBuildHighlight = FALSE;
00827
00828 mGrabObject = NULL;
00829
00830 gSelectMgr->updateSelectionCenter();
00831 gAgent.setPointAt(POINTAT_TARGET_CLEAR);
00832 gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
00833
00834 dialog_refresh_all();
00835 }
00836
00837
00838 void LLToolGrab::stopGrab()
00839 {
00840
00841 LLMessageSystem *msg = gMessageSystem;
00842 switch(mMode)
00843 {
00844 case GRAB_ACTIVE_CENTER:
00845 case GRAB_NONPHYSICAL:
00846 case GRAB_LOCKED:
00847 msg->newMessageFast(_PREHASH_ObjectDeGrab);
00848 msg->nextBlockFast(_PREHASH_AgentData);
00849 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00850 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00851 msg->nextBlockFast(_PREHASH_ObjectData);
00852 msg->addU32Fast(_PREHASH_LocalID, mGrabObject->mLocalID);
00853 msg->sendMessage(mGrabObject->getRegion()->getHost());
00854
00855 mVerticalDragging = FALSE;
00856 mGrabOffset.clearVec();
00857 break;
00858
00859 case GRAB_NOOBJECT:
00860 case GRAB_INACTIVE:
00861 default:
00862
00863 break;
00864 }
00865
00866 mHideBuildHighlight = FALSE;
00867 }
00868
00869
00870 void LLToolGrab::draw()
00871 { }
00872
00873 void LLToolGrab::render()
00874 { }
00875
00876 BOOL LLToolGrab::isEditing()
00877 {
00878
00879 LLViewerObject *obj = mGrabObject;
00880 return (obj != NULL);
00881 }
00882
00883 LLViewerObject* LLToolGrab::getEditingObject()
00884 {
00885 return mGrabObject;
00886 }
00887
00888
00889 LLVector3d LLToolGrab::getEditingPointGlobal()
00890 {
00891 return getGrabPointGlobal();
00892 }
00893
00894 LLVector3d LLToolGrab::getGrabPointGlobal()
00895 {
00896 switch(mMode)
00897 {
00898 case GRAB_ACTIVE_CENTER:
00899 case GRAB_NONPHYSICAL:
00900 case GRAB_LOCKED:
00901 return gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
00902
00903 case GRAB_NOOBJECT:
00904 case GRAB_INACTIVE:
00905 default:
00906 return gAgent.getPositionGlobal();
00907 }
00908 }