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

Generated on Thu Jul 1 06:09:21 2010 for Second Life Viewer by  doxygen 1.4.7