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