00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034
00035 #include "lltoolfocus.h"
00036
00037
00038 #include "v3math.h"
00039 #include "llfontgl.h"
00040 #include "llui.h"
00041
00042
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
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
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
00093 void LLToolCamera::handleSelect()
00094 {
00095 if (gFloaterTools)
00096 {
00097 gFloaterTools->setStatusText("camera");
00098 }
00099 }
00100
00101
00102 void LLToolCamera::handleDeselect()
00103 {
00104
00105 }
00106
00107 BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
00108 {
00109
00110 setMouseCapture(TRUE);
00111
00112
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
00124
00125 mMouseUpX = x;
00126 mMouseUpY = y;
00127 mMouseUpMask = mask;
00128
00129 gViewerWindow->hideCursor();
00130
00131 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback);
00132
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
00149 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00150
00151
00152 if (!hit_obj && gLastHitPosGlobal.isExactlyZero())
00153 {
00154 gToolCamera->mValidClickPoint = FALSE;
00155 return;
00156 }
00157
00158
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
00178 good_customize_avatar_hit = TRUE;
00179 }
00180 else
00181 if( hit_obj->isAttachment() && hit_obj->permYouOwner() )
00182 {
00183
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
00200 else if (mask & MASK_ALT ||
00201 (gToolMgr->getCurrentTool()->getName() == "Camera"))
00202 {
00203 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00204 if (hit_obj)
00205 {
00206
00207
00208
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
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
00249
00250
00251 void LLToolCamera::releaseMouse()
00252 {
00253
00254
00255
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
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
00302 LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY);
00303 }
00304
00305
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
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
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
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
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 }