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 "llviewercamera.h"
00054 #include "llviewerobject.h"
00055 #include "llviewerwindow.h"
00056 #include "llvoavatar.h"
00057 #include "llmorphview.h"
00058
00059
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
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
00091 void LLToolCamera::handleSelect()
00092 {
00093 if (gFloaterTools)
00094 {
00095 gFloaterTools->setStatusText("camera");
00096 }
00097 }
00098
00099
00100 void LLToolCamera::handleDeselect()
00101 {
00102
00103 }
00104
00105 BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
00106 {
00107
00108 setMouseCapture(TRUE);
00109
00110
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
00122
00123 mMouseUpX = x;
00124 mMouseUpY = y;
00125 mMouseUpMask = mask;
00126
00127 gViewerWindow->hideCursor();
00128
00129 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback);
00130
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
00147 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00148
00149
00150 if (!hit_obj && gLastHitPosGlobal.isExactlyZero())
00151 {
00152 LLToolCamera::getInstance()->mValidClickPoint = FALSE;
00153 return;
00154 }
00155
00156
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
00176 good_customize_avatar_hit = TRUE;
00177 }
00178 else
00179 if( hit_obj->isAttachment() && hit_obj->permYouOwner() )
00180 {
00181
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
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
00205
00206
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
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
00247
00248
00249 void LLToolCamera::releaseMouse()
00250 {
00251
00252
00253
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
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
00300 LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY);
00301 }
00302
00303
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
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
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
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
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 }