PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/lltoolfocus.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 462 lines | 330 code | 71 blank | 61 comment | 88 complexity | f7cee15745ff55f860b31e5255938917 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lltoolfocus.cpp
  3. * @brief A tool to set the build focus point.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. // File includes
  28. #include "lltoolfocus.h"
  29. // Library includes
  30. #include "v3math.h"
  31. #include "llfontgl.h"
  32. #include "llui.h"
  33. // Viewer includes
  34. #include "llagent.h"
  35. #include "llagentcamera.h"
  36. #include "llbutton.h"
  37. #include "llviewercontrol.h"
  38. #include "lldrawable.h"
  39. #include "lltooltip.h"
  40. #include "llhudmanager.h"
  41. #include "llfloatertools.h"
  42. #include "llselectmgr.h"
  43. #include "llstatusbar.h"
  44. #include "lltoolmgr.h"
  45. #include "llviewercamera.h"
  46. #include "llviewerobject.h"
  47. #include "llviewerwindow.h"
  48. #include "llvoavatarself.h"
  49. #include "llmorphview.h"
  50. #include "llfloaterreg.h"
  51. #include "llfloatercamera.h"
  52. // Globals
  53. BOOL gCameraBtnZoom = TRUE;
  54. BOOL gCameraBtnOrbit = FALSE;
  55. BOOL gCameraBtnPan = FALSE;
  56. const S32 SLOP_RANGE = 4;
  57. const F32 FOCUS_OFFSET_FACTOR = 1.f;
  58. //
  59. // Camera - shared functionality
  60. //
  61. LLToolCamera::LLToolCamera()
  62. : LLTool(std::string("Camera")),
  63. mAccumX(0),
  64. mAccumY(0),
  65. mMouseDownX(0),
  66. mMouseDownY(0),
  67. mOutsideSlopX(FALSE),
  68. mOutsideSlopY(FALSE),
  69. mValidClickPoint(FALSE),
  70. mMouseSteering(FALSE),
  71. mMouseUpX(0),
  72. mMouseUpY(0),
  73. mMouseUpMask(MASK_NONE)
  74. { }
  75. LLToolCamera::~LLToolCamera()
  76. { }
  77. // virtual
  78. void LLToolCamera::handleSelect()
  79. {
  80. if (gFloaterTools)
  81. {
  82. gFloaterTools->setStatusText("camera");
  83. }
  84. }
  85. // virtual
  86. void LLToolCamera::handleDeselect()
  87. {
  88. // gAgent.setLookingAtAvatar(FALSE);
  89. }
  90. BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
  91. {
  92. // Ensure a mouseup
  93. setMouseCapture(TRUE);
  94. // call the base class to propogate info to sim
  95. LLTool::handleMouseDown(x, y, mask);
  96. mAccumX = 0;
  97. mAccumY = 0;
  98. mOutsideSlopX = FALSE;
  99. mOutsideSlopY = FALSE;
  100. mValidClickPoint = FALSE;
  101. // If mouse capture gets ripped away, claim we moused up
  102. // at the point we moused down. JC
  103. mMouseUpX = x;
  104. mMouseUpY = y;
  105. mMouseUpMask = mask;
  106. gViewerWindow->hideCursor();
  107. gViewerWindow->pickAsync(x, y, mask, pickCallback);
  108. return TRUE;
  109. }
  110. void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
  111. {
  112. if (!LLToolCamera::getInstance()->hasMouseCapture())
  113. {
  114. return;
  115. }
  116. LLToolCamera::getInstance()->mMouseDownX = pick_info.mMousePt.mX;
  117. LLToolCamera::getInstance()->mMouseDownY = pick_info.mMousePt.mY;
  118. gViewerWindow->moveCursorToCenter();
  119. // Potentially recenter if click outside rectangle
  120. LLViewerObject* hit_obj = pick_info.getObject();
  121. // Check for hit the sky, or some other invalid point
  122. if (!hit_obj && pick_info.mPosGlobal.isExactlyZero())
  123. {
  124. LLToolCamera::getInstance()->mValidClickPoint = FALSE;
  125. return;
  126. }
  127. // check for hud attachments
  128. if (hit_obj && hit_obj->isHUDAttachment())
  129. {
  130. LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
  131. if (!selection->getObjectCount() || selection->getSelectType() != SELECT_TYPE_HUD)
  132. {
  133. LLToolCamera::getInstance()->mValidClickPoint = FALSE;
  134. return;
  135. }
  136. }
  137. if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
  138. {
  139. BOOL good_customize_avatar_hit = FALSE;
  140. if( hit_obj )
  141. {
  142. if (isAgentAvatarValid() && (hit_obj == gAgentAvatarp))
  143. {
  144. // It's you
  145. good_customize_avatar_hit = TRUE;
  146. }
  147. else if (hit_obj->isAttachment() && hit_obj->permYouOwner())
  148. {
  149. // It's an attachment that you're wearing
  150. good_customize_avatar_hit = TRUE;
  151. }
  152. }
  153. if( !good_customize_avatar_hit )
  154. {
  155. LLToolCamera::getInstance()->mValidClickPoint = FALSE;
  156. return;
  157. }
  158. if( gMorphView )
  159. {
  160. gMorphView->setCameraDrivenByKeys( FALSE );
  161. }
  162. }
  163. //RN: check to see if this is mouse-driving as opposed to ALT-zoom or Focus tool
  164. else if (pick_info.mKeyMask & MASK_ALT ||
  165. (LLToolMgr::getInstance()->getCurrentTool()->getName() == "Camera"))
  166. {
  167. LLViewerObject* hit_obj = pick_info.getObject();
  168. if (hit_obj)
  169. {
  170. // ...clicked on a world object, so focus at its position
  171. if (!hit_obj->isHUDAttachment())
  172. {
  173. gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
  174. gAgentCamera.setFocusGlobal(pick_info);
  175. }
  176. }
  177. else if (!pick_info.mPosGlobal.isExactlyZero())
  178. {
  179. // Hit the ground
  180. gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
  181. gAgentCamera.setFocusGlobal(pick_info);
  182. }
  183. if (!(pick_info.mKeyMask & MASK_ALT) &&
  184. gAgentCamera.cameraThirdPerson() &&
  185. gViewerWindow->getLeftMouseDown() &&
  186. !gSavedSettings.getBOOL("FreezeTime") &&
  187. (hit_obj == gAgentAvatarp ||
  188. (hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->isSelf())))
  189. {
  190. LLToolCamera::getInstance()->mMouseSteering = TRUE;
  191. }
  192. }
  193. LLToolCamera::getInstance()->mValidClickPoint = TRUE;
  194. if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
  195. {
  196. gAgentCamera.setFocusOnAvatar(FALSE, FALSE);
  197. LLVector3d cam_pos = gAgentCamera.getCameraPositionGlobal();
  198. gAgentCamera.setCameraPosAndFocusGlobal( cam_pos, pick_info.mPosGlobal, pick_info.mObjectID);
  199. }
  200. }
  201. // "Let go" of the mouse, for example on mouse up or when
  202. // we lose mouse capture. This ensures that cursor becomes visible
  203. // if a modal dialog pops up during Alt-Zoom. JC
  204. void LLToolCamera::releaseMouse()
  205. {
  206. // Need to tell the sim that the mouse button is up, since this
  207. // tool is no longer working and cursor is visible (despite actual
  208. // mouse button status).
  209. LLTool::handleMouseUp(mMouseUpX, mMouseUpY, mMouseUpMask);
  210. gViewerWindow->showCursor();
  211. //for the situation when left click was performed on the Agent
  212. if (!LLFloaterCamera::inFreeCameraMode())
  213. {
  214. LLToolMgr::getInstance()->clearTransientTool();
  215. }
  216. mMouseSteering = FALSE;
  217. mValidClickPoint = FALSE;
  218. mOutsideSlopX = FALSE;
  219. mOutsideSlopY = FALSE;
  220. }
  221. BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask)
  222. {
  223. // Claim that we're mousing up somewhere
  224. mMouseUpX = x;
  225. mMouseUpY = y;
  226. mMouseUpMask = mask;
  227. if (hasMouseCapture())
  228. {
  229. if (mValidClickPoint)
  230. {
  231. if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
  232. {
  233. LLCoordGL mouse_pos;
  234. LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal());
  235. BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos);
  236. if (success)
  237. {
  238. LLUI::setMousePositionScreen(mouse_pos.mX, mouse_pos.mY);
  239. }
  240. }
  241. else if (mMouseSteering)
  242. {
  243. LLUI::setMousePositionScreen(mMouseDownX, mMouseDownY);
  244. }
  245. else
  246. {
  247. gViewerWindow->moveCursorToCenter();
  248. }
  249. }
  250. else
  251. {
  252. // not a valid zoomable object
  253. LLUI::setMousePositionScreen(mMouseDownX, mMouseDownY);
  254. }
  255. // calls releaseMouse() internally
  256. setMouseCapture(FALSE);
  257. }
  258. else
  259. {
  260. releaseMouse();
  261. }
  262. return TRUE;
  263. }
  264. BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
  265. {
  266. S32 dx = gViewerWindow->getCurrentMouseDX();
  267. S32 dy = gViewerWindow->getCurrentMouseDY();
  268. BOOL moved_outside_slop = FALSE;
  269. if (hasMouseCapture() && mValidClickPoint)
  270. {
  271. mAccumX += llabs(dx);
  272. mAccumY += llabs(dy);
  273. if (mAccumX >= SLOP_RANGE)
  274. {
  275. if (!mOutsideSlopX)
  276. {
  277. moved_outside_slop = TRUE;
  278. }
  279. mOutsideSlopX = TRUE;
  280. }
  281. if (mAccumY >= SLOP_RANGE)
  282. {
  283. if (!mOutsideSlopY)
  284. {
  285. moved_outside_slop = TRUE;
  286. }
  287. mOutsideSlopY = TRUE;
  288. }
  289. }
  290. if (mOutsideSlopX || mOutsideSlopY)
  291. {
  292. if (!mValidClickPoint)
  293. {
  294. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolFocus [invalid point]" << llendl;
  295. gViewerWindow->setCursor(UI_CURSOR_NO);
  296. gViewerWindow->showCursor();
  297. return TRUE;
  298. }
  299. if (gCameraBtnOrbit ||
  300. mask == MASK_ORBIT ||
  301. mask == (MASK_ALT | MASK_ORBIT))
  302. {
  303. // Orbit tool
  304. if (hasMouseCapture())
  305. {
  306. const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidthScaled();
  307. if (dx != 0)
  308. {
  309. gAgentCamera.cameraOrbitAround( -dx * RADIANS_PER_PIXEL );
  310. }
  311. if (dy != 0)
  312. {
  313. gAgentCamera.cameraOrbitOver( -dy * RADIANS_PER_PIXEL );
  314. }
  315. gViewerWindow->moveCursorToCenter();
  316. }
  317. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolFocus [active]" << llendl;
  318. }
  319. else if ( gCameraBtnPan ||
  320. mask == MASK_PAN ||
  321. mask == (MASK_PAN | MASK_ALT) )
  322. {
  323. // Pan tool
  324. if (hasMouseCapture())
  325. {
  326. LLVector3d camera_to_focus = gAgentCamera.getCameraPositionGlobal();
  327. camera_to_focus -= gAgentCamera.getFocusGlobal();
  328. F32 dist = (F32) camera_to_focus.normVec();
  329. // Fudge factor for pan
  330. F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWorldViewWidthScaled();
  331. if (dx != 0)
  332. {
  333. gAgentCamera.cameraPanLeft( dx * meters_per_pixel );
  334. }
  335. if (dy != 0)
  336. {
  337. gAgentCamera.cameraPanUp( -dy * meters_per_pixel );
  338. }
  339. gViewerWindow->moveCursorToCenter();
  340. }
  341. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPan" << llendl;
  342. }
  343. else if (gCameraBtnZoom)
  344. {
  345. // Zoom tool
  346. if (hasMouseCapture())
  347. {
  348. const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidthScaled();
  349. if (dx != 0)
  350. {
  351. gAgentCamera.cameraOrbitAround( -dx * RADIANS_PER_PIXEL );
  352. }
  353. const F32 IN_FACTOR = 0.99f;
  354. if (dy != 0 && mOutsideSlopY )
  355. {
  356. if (mMouseSteering)
  357. {
  358. gAgentCamera.cameraOrbitOver( -dy * RADIANS_PER_PIXEL );
  359. }
  360. else
  361. {
  362. gAgentCamera.cameraZoomIn( pow( IN_FACTOR, dy ) );
  363. }
  364. }
  365. gViewerWindow->moveCursorToCenter();
  366. }
  367. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolZoom" << llendl;
  368. }
  369. }
  370. if (gCameraBtnOrbit ||
  371. mask == MASK_ORBIT ||
  372. mask == (MASK_ALT | MASK_ORBIT))
  373. {
  374. gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
  375. }
  376. else if ( gCameraBtnPan ||
  377. mask == MASK_PAN ||
  378. mask == (MASK_PAN | MASK_ALT) )
  379. {
  380. gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
  381. }
  382. else
  383. {
  384. gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
  385. }
  386. return TRUE;
  387. }
  388. void LLToolCamera::onMouseCaptureLost()
  389. {
  390. releaseMouse();
  391. }