lltoolfocus.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 // File includes
00035 #include "lltoolfocus.h" 
00036 
00037 // Library includes
00038 #include "v3math.h"
00039 #include "llfontgl.h"
00040 #include "llui.h"
00041 
00042 // Viewer includes
00043 #include "llagent.h"
00044 #include "llbutton.h"
00045 #include "llviewercontrol.h"
00046 #include "lldrawable.h"
00047 #include "llhoverview.h"
00048 #include "llhudmanager.h"
00049 #include "llfloatertools.h"
00050 #include "llselectmgr.h"
00051 #include "llstatusbar.h"
00052 #include "lltoolmgr.h"
00053 #include "llviewercamera.h"
00054 #include "llviewerobject.h"
00055 #include "llviewerwindow.h"
00056 #include "llvoavatar.h"
00057 #include "llmorphview.h"
00058 
00059 // Globals
00060 BOOL gCameraBtnZoom = TRUE;
00061 BOOL gCameraBtnOrbit = FALSE;
00062 BOOL gCameraBtnPan = FALSE;
00063 
00064 const S32 SLOP_RANGE = 4;
00065 const F32 FOCUS_OFFSET_FACTOR = 1.f;
00066 
00067 //
00068 // Camera - shared functionality
00069 //
00070 
00071 LLToolCamera::LLToolCamera()
00072 :       LLTool("Camera"),
00073         mAccumX(0),
00074         mAccumY(0),
00075         mMouseDownX(0),
00076         mMouseDownY(0),
00077         mOutsideSlopX(FALSE),
00078         mOutsideSlopY(FALSE),
00079         mValidClickPoint(FALSE),
00080         mMouseSteering(FALSE),
00081         mMouseUpX(0),
00082         mMouseUpY(0),
00083         mMouseUpMask(MASK_NONE)
00084 { }
00085 
00086 
00087 LLToolCamera::~LLToolCamera()
00088 { }
00089 
00090 // virtual
00091 void LLToolCamera::handleSelect()
00092 {
00093         if (gFloaterTools)
00094         {
00095                 gFloaterTools->setStatusText("camera");
00096         }
00097 }
00098 
00099 // virtual
00100 void LLToolCamera::handleDeselect()
00101 {
00102 //      gAgent.setLookingAtAvatar(FALSE);
00103 }
00104 
00105 BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
00106 {
00107         // Ensure a mouseup
00108         setMouseCapture(TRUE);
00109 
00110         // call the base class to propogate info to sim
00111         LLTool::handleMouseDown(x, y, mask);
00112 
00113         mAccumX = 0;
00114         mAccumY = 0;
00115 
00116         mOutsideSlopX = FALSE;
00117         mOutsideSlopY = FALSE;
00118 
00119         mValidClickPoint = FALSE;
00120 
00121         // If mouse capture gets ripped away, claim we moused up
00122         // at the point we moused down. JC
00123         mMouseUpX = x;
00124         mMouseUpY = y;
00125         mMouseUpMask = mask;
00126 
00127         gViewerWindow->hideCursor();
00128 
00129         gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback);
00130         // don't steal focus from UI
00131         return FALSE;
00132 }
00133 
00134 void LLToolCamera::pickCallback(S32 x, S32 y, MASK mask)
00135 {
00136         if (!LLToolCamera::getInstance()->hasMouseCapture())
00137         {
00138                 return;
00139         }
00140 
00141         LLToolCamera::getInstance()->mMouseDownX = x;
00142         LLToolCamera::getInstance()->mMouseDownY = y;
00143 
00144         gViewerWindow->moveCursorToCenter();
00145 
00146         // Potentially recenter if click outside rectangle
00147         LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00148 
00149         // Check for hit the sky, or some other invalid point
00150         if (!hit_obj && gLastHitPosGlobal.isExactlyZero())
00151         {
00152                 LLToolCamera::getInstance()->mValidClickPoint = FALSE;
00153                 return;
00154         }
00155 
00156         // check for hud attachments
00157         if (hit_obj && hit_obj->isHUDAttachment())
00158         {
00159                 LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
00160                 if (!selection->getObjectCount() || selection->getSelectType() != SELECT_TYPE_HUD)
00161                 {
00162                         LLToolCamera::getInstance()->mValidClickPoint = FALSE;
00163                         return;
00164                 }
00165         }
00166 
00167         if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
00168         {
00169                 BOOL good_customize_avatar_hit = FALSE;
00170                 if( hit_obj )
00171                 {
00172                         LLVOAvatar* avatar = gAgent.getAvatarObject();
00173                         if( hit_obj == avatar) 
00174                         {
00175                                 // It's you
00176                                 good_customize_avatar_hit = TRUE;
00177                         }
00178                         else
00179                         if( hit_obj->isAttachment() && hit_obj->permYouOwner() )
00180                         {
00181                                 // It's an attachment that you're wearing
00182                                 good_customize_avatar_hit = TRUE;
00183                         }
00184                 }
00185 
00186                 if( !good_customize_avatar_hit )
00187                 {
00188                         LLToolCamera::getInstance()->mValidClickPoint = FALSE;
00189                         return;
00190                 }
00191 
00192                 if( gMorphView )
00193                 {
00194                         gMorphView->setCameraDrivenByKeys( FALSE );
00195                 }
00196         }
00197         //RN: check to see if this is mouse-driving as opposed to ALT-zoom or Focus tool
00198         else if (mask & MASK_ALT || 
00199                         (LLToolMgr::getInstance()->getCurrentTool()->getName() == "Camera")) 
00200         {
00201                 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00202                 if (hit_obj)
00203                 {
00204                         // ...clicked on a world object, so focus at its position
00205                         // Use "gLastHitPosGlobal" because it's correct for avatar heads,
00206                         // not pelvis.
00207                         if (!hit_obj->isHUDAttachment())
00208                         {
00209                                 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
00210                                 gAgent.setFocusGlobal( gLastHitObjectOffset + gLastHitPosGlobal, gLastHitObjectID);
00211                         }
00212                 }
00213                 else if (!gLastHitPosGlobal.isExactlyZero())
00214                 {
00215                         // Hit the ground
00216                         gAgent.setFocusOnAvatar(FALSE, ANIMATE);
00217                         gAgent.setFocusGlobal( gLastHitPosGlobal, gLastHitObjectID);
00218                 }
00219 
00220                 if (!(mask & MASK_ALT) &&
00221                         gAgent.cameraThirdPerson() &&
00222                         gViewerWindow->getLeftMouseDown() && 
00223                         !gSavedSettings.getBOOL("FreezeTime") &&
00224                         (hit_obj == gAgent.getAvatarObject() || 
00225                                 (hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->mIsSelf)))
00226                 {
00227                         LLToolCamera::getInstance()->mMouseSteering = TRUE;
00228                 }
00229 
00230         }
00231 
00232         LLToolCamera::getInstance()->mValidClickPoint = TRUE;
00233 
00234         if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
00235         {
00236                 gAgent.setFocusOnAvatar(FALSE, FALSE);
00237                 
00238                 LLVector3d cam_pos = gAgent.getCameraPositionGlobal();
00239                 cam_pos -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * gAgent.calcCustomizeAvatarUIOffset( cam_pos ));
00240 
00241                 gAgent.setCameraPosAndFocusGlobal( cam_pos, gLastHitObjectOffset + gLastHitPosGlobal, gLastHitObjectID);
00242         }
00243 }
00244 
00245 
00246 // "Let go" of the mouse, for example on mouse up or when
00247 // we lose mouse capture.  This ensures that cursor becomes visible
00248 // if a modal dialog pops up during Alt-Zoom. JC
00249 void LLToolCamera::releaseMouse()
00250 {
00251         // Need to tell the sim that the mouse button is up, since this
00252         // tool is no longer working and cursor is visible (despite actual
00253         // mouse button status).
00254         LLTool::handleMouseUp(mMouseUpX, mMouseUpY, mMouseUpMask);
00255 
00256         gViewerWindow->showCursor();
00257 
00258         LLToolMgr::getInstance()->clearTransientTool();
00259 
00260         mMouseSteering = FALSE;
00261         mValidClickPoint = FALSE;
00262         mOutsideSlopX = FALSE;
00263         mOutsideSlopY = FALSE;
00264 }
00265 
00266 
00267 BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask)
00268 {
00269         // Claim that we're mousing up somewhere
00270         mMouseUpX = x;
00271         mMouseUpY = y;
00272         mMouseUpMask = mask;
00273 
00274         if (hasMouseCapture())
00275         {
00276                 if (mValidClickPoint)
00277                 {
00278                         if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
00279                         {
00280                                 LLCoordGL mouse_pos;
00281                                 LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgent.getFocusGlobal());
00282                                 BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos);
00283                                 if (success)
00284                                 {
00285                                         LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY);
00286                                 }
00287                         }
00288                         else if (mMouseSteering)
00289                         {
00290                                 LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY);
00291                         }
00292                         else
00293                         {
00294                                 gViewerWindow->moveCursorToCenter();
00295                         }
00296                 }
00297                 else
00298                 {
00299                         // not a valid zoomable object
00300                         LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY);
00301                 }
00302 
00303                 // calls releaseMouse() internally
00304                 setMouseCapture(FALSE);
00305         }
00306         else
00307         {
00308                 releaseMouse();
00309         }
00310 
00311         return TRUE;
00312 }
00313 
00314 
00315 BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
00316 {
00317         S32 dx = gViewerWindow->getCurrentMouseDX();
00318         S32 dy = gViewerWindow->getCurrentMouseDY();
00319         
00320         BOOL moved_outside_slop = FALSE;
00321         
00322         if (hasMouseCapture() && mValidClickPoint)
00323         {
00324                 mAccumX += llabs(dx);
00325                 mAccumY += llabs(dy);
00326 
00327                 if (mAccumX >= SLOP_RANGE)
00328                 {
00329                         if (!mOutsideSlopX)
00330                         {
00331                                 moved_outside_slop = TRUE;
00332                         }
00333                         mOutsideSlopX = TRUE;
00334                 }
00335 
00336                 if (mAccumY >= SLOP_RANGE)
00337                 {
00338                         if (!mOutsideSlopY)
00339                         {
00340                                 moved_outside_slop = TRUE;
00341                         }
00342                         mOutsideSlopY = TRUE;
00343                 }
00344         }
00345 
00346         if (mOutsideSlopX || mOutsideSlopY)
00347         {
00348                 if (!mValidClickPoint)
00349                 {
00350                         lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolFocus [invalid point]" << llendl;
00351                         gViewerWindow->setCursor(UI_CURSOR_NO);
00352                         gViewerWindow->showCursor();
00353                         return TRUE;
00354                 }
00355 
00356                 if (gCameraBtnOrbit ||
00357                         mask == MASK_ORBIT || 
00358                         mask == (MASK_ALT | MASK_ORBIT))
00359                 {
00360                         // Orbit tool
00361                         if (hasMouseCapture())
00362                         {
00363                                 const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth();
00364 
00365                                 if (dx != 0)
00366                                 {
00367                                         gAgent.cameraOrbitAround( -dx * RADIANS_PER_PIXEL );
00368                                 }
00369 
00370                                 if (dy != 0)
00371                                 {
00372                                         gAgent.cameraOrbitOver( -dy * RADIANS_PER_PIXEL );
00373                                 }
00374 
00375                                 gViewerWindow->moveCursorToCenter();
00376                         }
00377                         lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolFocus [active]" << llendl;
00378                 }
00379                 else if (       gCameraBtnPan ||
00380                                         mask == MASK_PAN ||
00381                                         mask == (MASK_PAN | MASK_ALT) )
00382                 {
00383                         // Pan tool
00384                         if (hasMouseCapture())
00385                         {
00386                                 LLVector3d camera_to_focus = gAgent.getCameraPositionGlobal();
00387                                 camera_to_focus -= gAgent.getFocusGlobal();
00388                                 F32 dist = (F32) camera_to_focus.normVec();
00389 
00390                                 // Fudge factor for pan
00391                                 F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWindowWidth();
00392 
00393                                 if (dx != 0)
00394                                 {
00395                                         gAgent.cameraPanLeft( dx * meters_per_pixel );
00396                                 }
00397 
00398                                 if (dy != 0)
00399                                 {
00400                                         gAgent.cameraPanUp( -dy * meters_per_pixel );
00401                                 }
00402 
00403                                 gViewerWindow->moveCursorToCenter();
00404                         }
00405                         lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPan" << llendl;
00406                 }
00407                 else if (gCameraBtnZoom)
00408                 {
00409                         // Zoom tool
00410                         if (hasMouseCapture())
00411                         {
00412 
00413                                 const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth();
00414 
00415                                 if (dx != 0)
00416                                 {
00417                                         gAgent.cameraOrbitAround( -dx * RADIANS_PER_PIXEL );
00418                                 }
00419 
00420                                 const F32 IN_FACTOR = 0.99f;
00421 
00422                                 if (dy != 0 && mOutsideSlopY )
00423                                 {
00424                                         if (mMouseSteering)
00425                                         {
00426                                                 gAgent.cameraOrbitOver( -dy * RADIANS_PER_PIXEL );
00427                                         }
00428                                         else
00429                                         {
00430                                                 gAgent.cameraZoomIn( pow( IN_FACTOR, dy ) );
00431                                         }
00432                                 }
00433 
00434                                 gViewerWindow->moveCursorToCenter();
00435                         }
00436 
00437                         lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolZoom" << llendl;         
00438                 }
00439         }
00440 
00441         if (gCameraBtnOrbit ||
00442                 mask == MASK_ORBIT || 
00443                 mask == (MASK_ALT | MASK_ORBIT))
00444         {
00445                 gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
00446         }
00447         else if (       gCameraBtnPan ||
00448                                 mask == MASK_PAN ||
00449                                 mask == (MASK_PAN | MASK_ALT) )
00450         {
00451                 gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
00452         }
00453         else
00454         {
00455                 gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
00456         }
00457         
00458         return TRUE;
00459 }
00460 
00461 
00462 void LLToolCamera::onMouseCaptureLost()
00463 {
00464         releaseMouse();
00465 }

Generated on Fri May 16 08:34:07 2008 for SecondLife by  doxygen 1.5.5