lltoolselect.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /**
  2. * @file lltoolselect.cpp
  3. * @brief LLToolSelect class implementation
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "lltoolselect.h"
  34. #include "llagent.h"
  35. #include "llagentpilot.h"
  36. #include "lldrawable.h"
  37. #include "llmanip.h"
  38. //MK
  39. #include "mkrlinterface.h"
  40. //mk
  41. #include "llselectmgr.h"
  42. #include "lltoolmgr.h"
  43. #include "llviewercamera.h"
  44. #include "llviewercontrol.h"
  45. #include "llviewermenu.h"
  46. #include "llviewerobjectlist.h"
  47. #include "llviewerregion.h"
  48. #include "llvoavatarself.h"
  49. #include "llworld.h"
  50. // Globals
  51. constexpr F32 SELECTION_ROTATION_TRESHOLD = 0.1f;
  52. constexpr F32 SELECTION_SITTING_ROTATION_TRESHOLD = 3.2f;
  53. LLToolSelect::LLToolSelect(LLToolComposite* composite)
  54. : LLTool("Select", composite),
  55. mIgnoreGroup(false)
  56. {
  57. }
  58. // True if you selected an object.
  59. bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
  60. {
  61. // Do immediate pick query
  62. mPick = gViewerWindowp->pickImmediate(x, y, true);
  63. //MK
  64. LLViewerObject* object = mPick.getObject();
  65. if (gRLenabled && object)
  66. {
  67. if (!gRLInterface.canEdit(object))
  68. {
  69. return false;
  70. }
  71. if (!gRLInterface.canTouchFar(object, mPick.mIntersection))
  72. {
  73. return false;
  74. }
  75. }
  76. //mk
  77. // Pass mousedown to agent
  78. LLTool::handleMouseDown(x, y, mask);
  79. return mPick.getObject().notNull();
  80. }
  81. // static
  82. LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick,
  83. bool ignore_group,
  84. bool temp_select,
  85. bool select_root)
  86. {
  87. LLViewerObject* object = pick.getObject();
  88. if (select_root)
  89. {
  90. object = object->getRootEdit();
  91. }
  92. //MK
  93. if (gRLenabled && object)
  94. {
  95. if (!temp_select && !gRLInterface.canEdit(object))
  96. {
  97. return NULL;
  98. }
  99. if (!gRLInterface.canTouchFar(object))
  100. {
  101. return NULL;
  102. }
  103. }
  104. //mk
  105. bool select_owned = gSavedSettings.getBool("SelectOwnedOnly");
  106. bool select_movable = gSavedSettings.getBool("SelectMovableOnly");
  107. // *NOTE: These settings must be cleaned up at bottom of function.
  108. if (temp_select || gSelectMgr.mAllowSelectAvatar)
  109. {
  110. gSavedSettings.setBool("SelectOwnedOnly", false);
  111. gSavedSettings.setBool("SelectMovableOnly", false);
  112. gSelectMgr.setForceSelection(true);
  113. }
  114. bool extend_select = pick.mKeyMask == MASK_SHIFT ||
  115. pick.mKeyMask == MASK_CONTROL;
  116. // If no object, check for icon, then just deselect
  117. if (!object)
  118. {
  119. LLViewerObject* src_obj = NULL;
  120. LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon;
  121. if (last_hit_hud_icon)
  122. {
  123. src_obj = last_hit_hud_icon->getSourceObject();
  124. }
  125. if (src_obj)
  126. {
  127. const LLUUID& object_id = src_obj->getID();
  128. last_hit_hud_icon->fireClickedCallback(object_id);
  129. }
  130. else if (!extend_select)
  131. {
  132. gSelectMgr.deselectAll();
  133. }
  134. }
  135. else
  136. {
  137. bool already_selected = object->isSelected();
  138. if (extend_select)
  139. {
  140. if (already_selected)
  141. {
  142. if (ignore_group)
  143. {
  144. gSelectMgr.deselectObjectOnly(object);
  145. }
  146. else
  147. {
  148. gSelectMgr.deselectObjectAndFamily(object, true, true);
  149. }
  150. }
  151. else if (ignore_group)
  152. {
  153. gSelectMgr.selectObjectOnly(object, SELECT_ALL_TES);
  154. }
  155. else
  156. {
  157. gSelectMgr.selectObjectAndFamily(object);
  158. }
  159. }
  160. else
  161. {
  162. // Save the current zoom values because deselect resets them.
  163. F32 target_zoom;
  164. F32 current_zoom;
  165. gAgent.getHUDZoom(target_zoom, current_zoom);
  166. // JC - Change behavior to make it easier to select children
  167. // of linked sets. 9/3/2002
  168. if (!already_selected || ignore_group)
  169. {
  170. // ...loose current selection in favor of just this object
  171. gSelectMgr.deselectAll();
  172. }
  173. if (ignore_group)
  174. {
  175. gSelectMgr.selectObjectOnly(object, SELECT_ALL_TES,
  176. pick.mGLTFNodeIndex,
  177. pick.mGLTFPrimIndex);
  178. }
  179. else
  180. {
  181. gSelectMgr.selectObjectAndFamily(object);
  182. }
  183. // Restore the zoom to the previously stored values.
  184. gAgent.setHUDZoom(target_zoom, current_zoom);
  185. }
  186. static LLCachedControl<bool> do_turn(gSavedSettings,
  187. "TurnTowardsSelectedObject");
  188. if (do_turn &&
  189. // If object is not an avatar
  190. !object->isAvatar() &&
  191. // If camera not glued to avatar
  192. !gAgent.getFocusOnAvatar() &&
  193. // And it is not one of our attachments
  194. isAgentAvatarValid() &&
  195. LLVOAvatar::findAvatarFromAttachment(object) != gAgentAvatarp)
  196. {
  197. // Have avatar turn to face the selected object(s)
  198. LLVector3 selection_dir(gSelectMgr.getSelectionCenterGlobal() -
  199. gAgent.getPositionGlobal());
  200. selection_dir.mV[VZ] = 0.f;
  201. selection_dir.normalize();
  202. if (gAgent.getAtAxis() * selection_dir < 0.6f)
  203. {
  204. LLQuaternion target_rot;
  205. target_rot.shortestArc(LLVector3::x_axis, selection_dir);
  206. F32 rot_threshold;
  207. if (gAgentAvatarp->mIsSitting)
  208. {
  209. rot_threshold = SELECTION_SITTING_ROTATION_TRESHOLD;
  210. }
  211. else
  212. {
  213. rot_threshold = SELECTION_ROTATION_TRESHOLD;
  214. }
  215. gAgentPilot.startAutoPilotGlobal(gAgent.getPositionGlobal(),
  216. "", &target_rot, NULL, NULL,
  217. MAX_FAR_CLIP, rot_threshold,
  218. gAgent.getFlying());
  219. }
  220. }
  221. if (temp_select && !already_selected)
  222. {
  223. LLViewerObject* root_obj = (LLViewerObject*)object->getRootEdit();
  224. LLObjectSelectionHandle selection = gSelectMgr.getSelection();
  225. // This is just a temporary selection
  226. LLSelectNode* select_node = selection->findNode(root_obj);
  227. if (select_node)
  228. {
  229. select_node->setTransient(true);
  230. }
  231. LLViewerObject::const_child_list_t& child_list =
  232. root_obj->getChildren();
  233. for (LLViewerObject::child_list_t::const_iterator
  234. iter = child_list.begin(), end = child_list.end();
  235. iter != end; iter++)
  236. {
  237. LLViewerObject* child = *iter;
  238. select_node = selection->findNode(child);
  239. if (select_node)
  240. {
  241. select_node->setTransient(true);
  242. }
  243. }
  244. }
  245. }
  246. // Cleanup temp select settings above.
  247. if (temp_select || gSelectMgr.mAllowSelectAvatar)
  248. {
  249. gSavedSettings.setBool("SelectOwnedOnly", select_owned);
  250. gSavedSettings.setBool("SelectMovableOnly", select_movable);
  251. gSelectMgr.setForceSelection(false);
  252. }
  253. return gSelectMgr.getSelection();
  254. }
  255. bool LLToolSelect::handleMouseUp(S32 x, S32 y, MASK mask)
  256. {
  257. mIgnoreGroup = gSavedSettings.getBool("EditLinkedParts");
  258. handleObjectSelection(mPick, mIgnoreGroup, false);
  259. return LLTool::handleMouseUp(x, y, mask);
  260. }
  261. void LLToolSelect::handleDeselect()
  262. {
  263. if (hasMouseCapture())
  264. {
  265. setMouseCapture(false); // Calls onMouseCaptureLost() indirectly
  266. }
  267. }
  268. void LLToolSelect::stopEditing()
  269. {
  270. if (hasMouseCapture())
  271. {
  272. setMouseCapture(false); // Calls onMouseCaptureLost() indirectly
  273. }
  274. }
  275. void LLToolSelect::onMouseCaptureLost()
  276. {
  277. gSelectMgr.enableSilhouette(true);
  278. // Clean up drag-specific variables
  279. mIgnoreGroup = false;
  280. }