llfloaterpathfindingcharacters.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /**
  2. * @file llfloaterpathfindingcharacters.cpp
  3. * @brief Pathfinding characters floater, allowing for identification of
  4. * pathfinding characters and their cpu usage.
  5. *
  6. * $LicenseInfo:firstyear=2012&license=viewergpl$
  7. *
  8. * Copyright (c) 2012, Linden Research, Inc.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #include "llviewerprecompiledheaders.h"
  34. #include "llfloaterpathfindingcharacters.h"
  35. #include "llcheckboxctrl.h"
  36. #include "llscrolllistctrl.h"
  37. #include "lluictrlfactory.h"
  38. #include "llfloaterpathfindingobjects.h"
  39. #include "llpathfindingcharacter.h"
  40. #include "llpathfindingcharacterlist.h"
  41. #include "llpathfindingmanager.h"
  42. #if HAVE_PATHINGLIB
  43. #include "llpathinglib.h"
  44. #include "llpipeline.h"
  45. #endif
  46. //MK
  47. #include "mkrlinterface.h"
  48. //mk
  49. #include "llviewerobjectlist.h"
  50. void LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects()
  51. {
  52. LLFloaterPathfindingCharacters* self = findInstance();
  53. if (self)
  54. {
  55. self->open();
  56. }
  57. else
  58. {
  59. self = getInstance(); // Creates a new instance
  60. self->showFloaterWithSelectionObjects();
  61. }
  62. }
  63. LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD&)
  64. {
  65. LLUICtrlFactory* factory = LLUICtrlFactory::getInstance();
  66. factory->buildFloater(this, "floater_pathfinding_characters.xml");
  67. }
  68. bool LLFloaterPathfindingCharacters::postBuild()
  69. {
  70. mBeaconColor =
  71. LLUI::sColorsGroup->getColor("PathfindingCharacterBeaconColor");
  72. #if HAVE_PATHINGLIB
  73. mShowCapsuleCheck = getChild<LLCheckBoxCtrl>("show_physics_capsule");
  74. mShowCapsuleCheck->setCommitCallback(onShowPhysicsCapsuleClicked);
  75. mShowCapsuleCheck->setCallbackUserData(this);
  76. mShowCapsuleCheck->setVisible(true);
  77. mShowCapsuleCheck->setEnabled(LLPathingLib::getInstance() != NULL);
  78. #else
  79. childHide("show_physics_capsule");
  80. #endif
  81. return LLFloaterPathfindingObjects::postBuild();
  82. }
  83. void LLFloaterPathfindingCharacters::onClose(bool app_quitting)
  84. {
  85. #if HAVE_PATHINGLIB
  86. // Hide any capsule that might be showing on floater close
  87. hideCapsule();
  88. #endif
  89. LLFloaterPathfindingObjects::onClose(app_quitting);
  90. }
  91. void LLFloaterPathfindingCharacters::requestGetObjects()
  92. {
  93. LL_DEBUGS("NavMesh") << "Requesting characters list" << LL_ENDL;
  94. LLPathfindingManager* pmgrp = LLPathfindingManager::getInstance();
  95. pmgrp->requestGetCharacters(getNewRequestId(),
  96. boost::bind(&LLFloaterPathfindingCharacters::newObjectList,
  97. _1, _2, _3));
  98. }
  99. LLSD LLFloaterPathfindingCharacters::buildCharacterScrollListItemData(const LLPathfindingCharacter* charp) const
  100. {
  101. LLSD columns = LLSD::emptyArray();
  102. columns[0]["column"] = "name";
  103. columns[0]["value"] = charp->getName();
  104. columns[0]["font"] = "SANSSERIF";
  105. columns[0]["font-style"] = "NORMAL";
  106. columns[1]["column"] = "description";
  107. columns[1]["value"] = charp->getDescription();
  108. columns[1]["font"] = "SANSSERIF";
  109. columns[1]["font-style"] = "NORMAL";
  110. columns[2]["column"] = "owner";
  111. columns[2]["value"] = getOwnerName(charp);
  112. columns[2]["font"] = "SANSSERIF";
  113. columns[2]["font-style"] = "NORMAL";
  114. S32 cpu_time = ll_roundp(charp->getCPUTime());
  115. std::string cpu_timeString = llformat("%d", cpu_time);
  116. LLStringUtil::format_map_t string_args;
  117. string_args["[CPU_TIME]"] = cpu_timeString;
  118. columns[3]["column"] = "cpu_time";
  119. columns[3]["value"] = getString("character_cpu_time", string_args);
  120. columns[3]["font"] = "SANSSERIF";
  121. columns[3]["font-style"] = "NORMAL";
  122. std::string altitude = llformat("%1.0f m", charp->getLocation()[2]);
  123. //MK
  124. if (gRLenabled && gRLInterface.mContainsShowloc)
  125. {
  126. altitude = "?";
  127. }
  128. //mk
  129. columns[4]["column"] = "altitude";
  130. columns[4]["value"] = altitude;
  131. columns[4]["font"] = "SANSSERIF";
  132. columns[4]["font-style"] = "NORMAL";
  133. LLSD element;
  134. element["id"] = charp->getUUID();
  135. element["columns"] = columns;
  136. return element;
  137. }
  138. void LLFloaterPathfindingCharacters::addObjectsIntoScrollList(const LLPathfindingObjectList::ptr_t pobjects)
  139. {
  140. if (!pobjects || pobjects->isEmpty())
  141. {
  142. llassert(false);
  143. return;
  144. }
  145. for (LLPathfindingObjectList::const_iterator iter = pobjects->begin(),
  146. end = pobjects->end();
  147. iter != end; ++iter)
  148. {
  149. const LLPathfindingObject::ptr_t objectp = iter->second;
  150. if (!objectp) continue;
  151. const LLPathfindingCharacter* charp = objectp.get()->asCharacter();
  152. if (!charp) continue;
  153. LLSD row = buildCharacterScrollListItemData(charp);
  154. mObjectsScrollList->addElement(row, ADD_BOTTOM);
  155. if (charp->hasOwner() && !charp->hasOwnerName())
  156. {
  157. rebuildScrollListAfterAvatarNameLoads(objectp);
  158. }
  159. }
  160. }
  161. //static
  162. void LLFloaterPathfindingCharacters::handleObjectNameResponse(const LLPathfindingObject* pobj)
  163. {
  164. LLFloaterPathfindingCharacters* self = findInstance();
  165. if (!self) return;
  166. uuid_list_t::iterator it = self->mLoadingNameObjects.find(pobj->getUUID());
  167. if (it != self->mLoadingNameObjects.end())
  168. {
  169. self->mLoadingNameObjects.erase(it);
  170. if (self->mLoadingNameObjects.empty())
  171. {
  172. self->rebuildObjectsScrollList();
  173. }
  174. }
  175. }
  176. void LLFloaterPathfindingCharacters::rebuildScrollListAfterAvatarNameLoads(const LLPathfindingObject::ptr_t pobj)
  177. {
  178. mLoadingNameObjects.emplace(pobj->getUUID());
  179. pobj->registerOwnerNameListener(boost::bind(&LLFloaterPathfindingCharacters::handleObjectNameResponse,
  180. _1));
  181. }
  182. // NOTE: we need a static function to prevent crash in case the floater is
  183. // closed while the object list is being received... This static function
  184. // then calls the inherited parent class' function only when the floater
  185. // instance still exists.
  186. //static
  187. void LLFloaterPathfindingCharacters::newObjectList(LLPathfindingManager::request_id_t request_id,
  188. LLPathfindingManager::ERequestStatus req_status,
  189. LLPathfindingObjectList::ptr_t pobjects)
  190. {
  191. LLFloaterPathfindingCharacters* self = findInstance();
  192. if (self)
  193. {
  194. self->handleNewObjectList(request_id, req_status, pobjects);
  195. }
  196. }
  197. void LLFloaterPathfindingCharacters::updateControlsOnScrollListChange()
  198. {
  199. LLFloaterPathfindingObjects::updateControlsOnScrollListChange();
  200. #if HAVE_PATHINGLIB
  201. updateStateOnDisplayControls();
  202. showSelectedCharacterCapsules();
  203. #endif
  204. }
  205. std::string LLFloaterPathfindingCharacters::getOwnerName(const LLPathfindingObject* obj) const
  206. {
  207. if (!obj->hasOwner())
  208. {
  209. static std::string unknown = getString("character_owner_unknown");
  210. return unknown;
  211. }
  212. if (!obj->hasOwnerName())
  213. {
  214. static std::string loading = getString("character_owner_loading");
  215. return loading;
  216. }
  217. std::string owner = obj->getOwnerName();
  218. //MK
  219. if (gRLenabled &&
  220. (gRLInterface.mContainsShownames ||
  221. gRLInterface.mContainsShownametags) &&
  222. !obj->isGroupOwned())
  223. {
  224. owner = gRLInterface.getDummyName(owner);
  225. }
  226. //mk
  227. if (obj->isGroupOwned())
  228. {
  229. static std::string group = " " + getString("character_owner_group");
  230. owner += group;
  231. }
  232. return owner;
  233. }
  234. LLPathfindingObjectList::ptr_t LLFloaterPathfindingCharacters::getEmptyObjectList() const
  235. {
  236. LLPathfindingObjectList::ptr_t objlistp(new LLPathfindingCharacterList());
  237. return objlistp;
  238. }
  239. #if HAVE_PATHINGLIB
  240. bool LLFloaterPathfindingCharacters::isPhysicsCapsuleEnabled(LLUUID& id,
  241. LLVector3& pos,
  242. LLQuaternion& rot) const
  243. {
  244. id = mSelectedCharacterId;
  245. // Physics capsule is enable if the checkbox is enabled and if we can get
  246. // the required render parameters for any selected object
  247. return mShowCapsuleCheck->get() && getCapsuleRenderData(pos, rot);
  248. }
  249. //static
  250. void LLFloaterPathfindingCharacters::onShowPhysicsCapsuleClicked(LLUICtrl* ctrl,
  251. void* data)
  252. {
  253. LLFloaterPathfindingCharacters* self = (LLFloaterPathfindingCharacters*)data;
  254. LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl;
  255. if (!self || !check) return;
  256. bool enabled = check->get();
  257. if (LLPathingLib::getInstance() == NULL)
  258. {
  259. if (enabled)
  260. {
  261. check->set(false);
  262. }
  263. }
  264. else if (self->mSelectedCharacterId.notNull() && enabled)
  265. {
  266. showCapsule();
  267. }
  268. else
  269. {
  270. hideCapsule();
  271. }
  272. }
  273. void LLFloaterPathfindingCharacters::updateStateOnDisplayControls()
  274. {
  275. bool enabled = getNumSelectedObjects() == 1 && LLPathingLib::getInstance();
  276. mShowCapsuleCheck->setEnabled(enabled);
  277. if (!enabled)
  278. {
  279. mShowCapsuleCheck->set(false);
  280. }
  281. }
  282. void LLFloaterPathfindingCharacters::showSelectedCharacterCapsules()
  283. {
  284. // Hide any previous capsule
  285. hideCapsule();
  286. // Get the only selected object, or set the selected object to null if we
  287. // do not have exactly one object selected
  288. if (getNumSelectedObjects() == 1)
  289. {
  290. LLPathfindingObject::ptr_t objectp = getFirstSelectedObject();
  291. if (objectp) // Paranoia
  292. {
  293. mSelectedCharacterId = objectp->getUUID();
  294. }
  295. else
  296. {
  297. mSelectedCharacterId.setNull();
  298. }
  299. }
  300. else
  301. {
  302. mSelectedCharacterId.setNull();
  303. }
  304. // Show any capsule if enabled
  305. showCapsule();
  306. }
  307. void LLFloaterPathfindingCharacters::showCapsule() const
  308. {
  309. if (mSelectedCharacterId.isNull() || !mShowCapsuleCheck->get())
  310. {
  311. return;
  312. }
  313. LLPathfindingObject::ptr_t objectp = getFirstSelectedObject();
  314. if (!objectp)
  315. {
  316. return;
  317. }
  318. const LLPathfindingCharacter* charp = objectp.get()->asCharacter();
  319. if (!charp || charp->getUUID() != mSelectedCharacterId)
  320. {
  321. llassert(false);
  322. return;
  323. }
  324. gPipeline.hideObject(mSelectedCharacterId);
  325. LLPathingLib* pthlip = LLPathingLib::getInstance();
  326. if (pthlip)
  327. {
  328. pthlip->createPhysicsCapsuleRep(charp->getLength(),
  329. charp->getRadius(),
  330. charp->isHorizontal(),
  331. charp->getUUID());
  332. }
  333. }
  334. void LLFloaterPathfindingCharacters::hideCapsule() const
  335. {
  336. if (mSelectedCharacterId.notNull())
  337. {
  338. gPipeline.restoreHiddenObject(mSelectedCharacterId);
  339. }
  340. LLPathingLib* pthlip = LLPathingLib::getInstance();
  341. if (pthlip)
  342. {
  343. pthlip->cleanupPhysicsCapsuleRepResiduals();
  344. }
  345. }
  346. bool LLFloaterPathfindingCharacters::getCapsuleRenderData(LLVector3& pos,
  347. LLQuaternion& rot) const
  348. {
  349. // If we have a selected object, find the object on the viewer object list
  350. // and return its position. Else, return false indicating that we either do
  351. // not have a selected object or we cannot find the selected object on the
  352. // viewer object list
  353. if (mSelectedCharacterId.notNull())
  354. {
  355. LLViewerObject* vobj = gObjectList.findObject(mSelectedCharacterId);
  356. if (vobj)
  357. {
  358. rot = vobj->getRotation();
  359. pos = vobj->getRenderPosition();
  360. return true;
  361. }
  362. }
  363. return false;
  364. }
  365. #endif