llpanelminimap.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988
  1. /**
  2. * @file llpanelminimap.cpp (was llnetmap.cpp)
  3. * @brief Displays agent and surrounding regions, objects, and avatars.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Original code by James Cook. Copyright (c) 2001-2009, Linden Research, Inc.
  8. * Copyright (c) 2009-2022, Henri Beauchamp.
  9. * Changes by Henri Beauchamp:
  10. * - Rewrote and optimized part of the code.
  11. * - Added unknown altitude avatar plot type (the dash-like dot).
  12. * - Allowed both old style (T-like dots) and new style (V-like tiny icons)
  13. * for above/below-agent avatar plots.
  14. * - Added per-avatar dots coloring (via Lua).
  15. * - Added animesh, path-finding and physical objects plotting.
  16. * - Added agent sim borders drawing.
  17. * - _Mostly_ fixed terrain textures never rendering (via changes done in
  18. * llvlcomposition.cpp and in the texture cache) and added a terrain texture
  19. * manual refreshing feature to deal with the cases when they still fail to
  20. * render.
  21. * - Backported (and improved) the optional rendering of banned parcels (from
  22. * LL's viewer) and parcel borders (from LL's viewer for the nice but slow
  23. * algorithm and from Singularity+Catznip for the fast but less pretty one).
  24. * - Added parcel info ("About land" floater) for parcels in the context menu.
  25. * - Added optional plots color legend.
  26. *
  27. * Second Life Viewer Source Code
  28. * The source code in this file ("Source Code") is provided by Linden Lab
  29. * to you under the terms of the GNU General Public License, version 2.0
  30. * ("GPL"), unless you have obtained a separate licensing agreement
  31. * ("Other License"), formally executed by you and Linden Lab. Terms of
  32. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  33. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  34. *
  35. * There are special exceptions to the terms and conditions of the GPL as
  36. * it is applied to this Source Code. View the full text of the exception
  37. * in the file doc/FLOSS-exception.txt in this software distribution, or
  38. * online at
  39. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  40. *
  41. * By copying, modifying or distributing this software, you acknowledge
  42. * that you have read and understood your obligations described above,
  43. * and agree to abide by those obligations.
  44. *
  45. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  46. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  47. * COMPLETENESS OR PERFORMANCE.
  48. * $/LicenseInfo$
  49. */
  50. #include "llviewerprecompiledheaders.h"
  51. #include "llpanelminimap.h"
  52. #include "llcachename.h"
  53. #include "llfontgl.h"
  54. #include "llmenugl.h"
  55. #include "llparcel.h"
  56. #include "llrender.h"
  57. #include "lltextbox.h"
  58. #include "lluictrlfactory.h"
  59. #include "llagent.h"
  60. #include "llagentpilot.h"
  61. #include "llappviewer.h" // For gFrameTimeSeconds and constants
  62. #include "llavatartracker.h"
  63. #include "llfloateravatarinfo.h"
  64. #include "llfloaterland.h"
  65. #include "llfloaterworldmap.h"
  66. #include "llpanelworldmap.h" // For shared draw code
  67. //MK
  68. #include "mkrlinterface.h"
  69. //mk
  70. #include "llsurface.h"
  71. #include "lltracker.h"
  72. #include "llviewercamera.h"
  73. #include "llviewercontrol.h"
  74. #include "llviewermenu.h"
  75. #include "llviewerobjectlist.h"
  76. #include "llviewerparcelmgr.h"
  77. #include "llviewerparceloverlay.h"
  78. #include "llviewerregion.h"
  79. #include "llviewertexturelist.h"
  80. #include "llviewerwindow.h"
  81. #include "llvoavatar.h"
  82. #include "llvlcomposition.h"
  83. #include "llworld.h"
  84. using namespace LLOldEvents;
  85. constexpr F32 MAP_SCALE_MIN = 32;
  86. constexpr F32 MAP_SCALE_MID = 256;
  87. constexpr F32 MAP_SCALE_MAX = 4096;
  88. // Zoom in factor per click of the scroll wheel (10%):
  89. constexpr F32 MAP_SCALE_ZOOM_FACTOR = 1.1f;
  90. constexpr F32 MAP_MINOR_DIR_THRESHOLD = 0.08f;
  91. constexpr F32 MIN_DOT_RADIUS = 3.5f;
  92. constexpr F32 DOT_SCALE = 0.75f;
  93. constexpr F32 MIN_PICK_SCALE = 2.f;
  94. // How far the mouse needs to move before we think it is a drag:
  95. constexpr S32 MOUSE_DRAG_SLOP = 2;
  96. bool LLPanelMiniMap::sMiniMapRotate = true;
  97. S32 LLPanelMiniMap::sMiniMapCenter = 1;
  98. LLPanelMiniMap::LLPanelMiniMap(const std::string& name)
  99. : LLPanel(name),
  100. mNorthLabel(NULL),
  101. mSouthLabel(NULL),
  102. mWestLabel(NULL),
  103. mEastLabel(NULL),
  104. mNorthWestLabel(NULL),
  105. mNorthEastLabel(NULL),
  106. mSouthWestLabel(NULL),
  107. mSouthEastLabel(NULL),
  108. mFontp(LLFontGL::getFontMonospace()),
  109. mFriendLegendDeltaX(100),
  110. mScale(128.f),
  111. mObjectMapTPM(1.f),
  112. mObjectMapPixels(255.f),
  113. mTargetPanX(0.f),
  114. mTargetPanY(0.f),
  115. mCurPanX(0.f),
  116. mCurPanY(0.f),
  117. mUpdateObjectImage(false),
  118. mUpdateParcelImage(false),
  119. mHasDrawnParcels(false)
  120. {
  121. mBackgroundColor = isBackgroundOpaque() ? getBackgroundColor()
  122. : getTransparentColor();
  123. mScale = gSavedSettings.getF32("MiniMapScale");
  124. // Unintuitive and hacky... To support variable region size we must make
  125. // the mini-map believe regions got a fixed size of 256m...
  126. mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
  127. mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
  128. sMiniMapCenter = gSavedSettings.getS32("MiniMapCenter");
  129. sMiniMapRotate = gSavedSettings.getBool("MiniMapRotate");
  130. mObjectImageCenterGlobal = gAgent.getCameraPositionGlobal();
  131. // Register event listeners for popup menu
  132. (new LLScaleMap())->registerListener(this, "MiniMap.ZoomLevel");
  133. (new LLCenterMap())->registerListener(this, "MiniMap.Center");
  134. (new LLCheckCenterMap())->registerListener(this, "MiniMap.CheckCenter");
  135. (new LLRotateMap())->registerListener(this, "MiniMap.Rotate");
  136. (new LLCheckRotateMap())->registerListener(this, "MiniMap.CheckRotate");
  137. (new LLDrawObjects())->registerListener(this, "MiniMap.DrawObjects");
  138. (new LLCheckDrawObjects())->registerListener(this,
  139. "MiniMap.CheckDrawObjects");
  140. (new LLPlotPuppets())->registerListener(this, "MiniMap.PlotPuppets");
  141. (new LLCheckPlotPuppets())->registerListener(this,
  142. "MiniMap.CheckPlotPuppets");
  143. (new LLPlotChars())->registerListener(this, "MiniMap.PlotChars");
  144. (new LLCheckPlotChars())->registerListener(this, "MiniMap.CheckPlotChars");
  145. (new LLEnablePlotChars())->registerListener(this,
  146. "MiniMap.EnablePlotChars");
  147. (new LLPlotPhysical())->registerListener(this, "MiniMap.PlotPhysical");
  148. (new LLCheckPlotPhysical())->registerListener(this,
  149. "MiniMap.CheckPlotPhysical");
  150. (new LLEnablePlotPhysical())->registerListener(this,
  151. "MiniMap.EnablePlotPhysical");
  152. (new LLDrawWater())->registerListener(this, "MiniMap.DrawWater");
  153. (new LLCheckDrawWater())->registerListener(this, "MiniMap.CheckDrawWater");
  154. (new LLDrawBorders())->registerListener(this, "MiniMap.DrawBorders");
  155. (new LLCheckDrawBorders())->registerListener(this,
  156. "MiniMap.CheckDrawBorders");
  157. (new LLDrawBans())->registerListener(this, "MiniMap.DrawBans");
  158. (new LLCheckDrawBans())->registerListener(this, "MiniMap.CheckDrawBans");
  159. (new LLDrawParcels())->registerListener(this, "MiniMap.DrawParcels");
  160. (new LLCheckDrawParcels())->registerListener(this,
  161. "MiniMap.CheckDrawParcels");
  162. (new LLShowParcelInfo())->registerListener(this, "MiniMap.ShowParcelInfo");
  163. (new LLEnableParcelInfo())->registerListener(this, "MiniMap.EnableParcelInfo");
  164. (new LLRefreshTerrain())->registerListener(this, "MiniMap.Refresh");
  165. (new LLStopTracking())->registerListener(this, "MiniMap.StopTracking");
  166. (new LLEnableTracking())->registerListener(this, "MiniMap.EnableTracking");
  167. (new LLShowAgentProfile())->registerListener(this, "MiniMap.ShowProfile");
  168. (new LLEnableProfile())->registerListener(this, "MiniMap.EnableProfile");
  169. (new LLDrawLegend())->registerListener(this, "MiniMap.DrawLegend");
  170. (new LLCheckDrawLegend())->registerListener(this,
  171. "MiniMap.CheckDrawLegend");
  172. LLUICtrlFactory::getInstance()->buildPanel(this, "panel_mini_map.xml");
  173. LLMenuGL* menu =
  174. LLUICtrlFactory::getInstance()->buildMenu("menu_mini_map.xml", this);
  175. if (!menu)
  176. {
  177. menu = new LLMenuGL(LLStringUtil::null);
  178. }
  179. menu->setVisible(false);
  180. mPopupMenuHandle = menu->getHandle();
  181. }
  182. bool LLPanelMiniMap::postBuild()
  183. {
  184. mNorthLabel = getChild<LLTextBox>("n_label", true, false);
  185. if (mNorthLabel)
  186. {
  187. mSouthLabel = getChild<LLTextBox>("s_label");
  188. mWestLabel = getChild<LLTextBox>("w_label");
  189. mEastLabel = getChild<LLTextBox>("e_label");
  190. mNorthWestLabel = getChild<LLTextBox>("nw_label");
  191. mNorthEastLabel = getChild<LLTextBox>("ne_label");
  192. mSouthWestLabel = getChild<LLTextBox>("sw_label");
  193. mSouthEastLabel = getChild<LLTextBox>("se_label");
  194. updateMinorDirections();
  195. }
  196. mMapToolTip = getToolTip();
  197. mRegionPrefix = getString("region_prefix") + " ";
  198. mParcelPrefix = getString("parcel_prefix") + " ";
  199. mOwnerPrefix = getString("owner_prefix") + " ";
  200. mLegendAvatar = getString("avatar");
  201. mLegendFriend = getString("friend");
  202. mLegendAnimesh = getString("animesh");
  203. mLegendPhysical = getString("physical");
  204. mLegendPathFinding = getString("pathfinding");
  205. if (mFontp)
  206. {
  207. mFriendLegendDeltaX = mFontp->getWidth(mLegendAvatar) + 4;
  208. }
  209. return true;
  210. }
  211. void LLPanelMiniMap::setScale(F32 scale)
  212. {
  213. mScale = scale;
  214. if (mScale == 0.f)
  215. {
  216. mScale = 0.1f;
  217. }
  218. static F32 old_scale = 0.f;
  219. if (mScale != old_scale)
  220. {
  221. gSavedSettings.setF32("MiniMapScale", mScale);
  222. old_scale = mScale;
  223. }
  224. // Unintuitive and hacky... To support variable region size we must make
  225. // the mini-map believe regions got a fixed size of 256m...
  226. constexpr F32 region_width = REGION_WIDTH_METERS;
  227. if (mObjectImagep.notNull())
  228. {
  229. F32 width = (F32)(getRect().getWidth());
  230. F32 height = (F32)(getRect().getHeight());
  231. F32 diameter = sqrtf(width * width + height * height);
  232. F32 meters = diameter * region_width / mScale;
  233. F32 num_pixels = (F32)mObjectImagep->getWidth();
  234. mObjectMapTPM = num_pixels / meters;
  235. mObjectMapPixels = diameter;
  236. }
  237. mPixelsPerMeter = mScale / region_width;
  238. mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
  239. mUpdateObjectImage = mUpdateParcelImage = true;
  240. }
  241. //virtual
  242. void LLPanelMiniMap::draw()
  243. {
  244. if (mObjectImagep.isNull())
  245. {
  246. createObjectImage();
  247. }
  248. static LLCachedControl<bool> fast_parcels(gSavedSettings,
  249. "MinimapFastParcelBorders");
  250. if (fast_parcels && mParcelImagep.isNull())
  251. {
  252. createParcelImage();
  253. }
  254. if (sMiniMapCenter != MAP_CENTER_NONE)
  255. {
  256. F32 critical_damp = LLCriticalDamp::getInterpolant(0.1f);
  257. mCurPanX = lerp(mCurPanX, mTargetPanX, critical_damp);
  258. mCurPanY = lerp(mCurPanY, mTargetPanY, critical_damp);
  259. }
  260. mHasDrawnParcels = false;
  261. F32 rotation = 0;
  262. LLTexUnit* unit0 = gGL.getTexUnit(0);
  263. // Prepare a scissor region
  264. gGL.pushMatrix();
  265. gGL.pushUIMatrix();
  266. LLVector3 offset = gGL.getUITranslation();
  267. LLVector3 scale = gGL.getUIScale();
  268. // Plots colors.
  269. static LLCachedControl<LLColor4U> map_avatar(gColors, "MapAvatar");
  270. static LLCachedControl<LLColor4U> map_phys(gColors,
  271. "MiniMapPhysicalObject");
  272. static LLCachedControl<LLColor4U> map_chars(gColors,
  273. "MiniMapPathFindingChar");
  274. static LLCachedControl<LLColor4U> map_puppets(gColors,
  275. "MiniMapPuppetsColor");
  276. // Whether to plot various objects or not
  277. static LLCachedControl<bool> plot_puppets(gSavedSettings,
  278. "MiniMapPlotPuppets");
  279. static LLCachedControl<bool> draw_objects(gSavedSettings,
  280. "MiniMapDrawObjects");
  281. static LLCachedControl<bool> plot_physical(gSavedSettings,
  282. "MiniMapPlotPhysicalObj");
  283. static LLCachedControl<bool> plot_characters(gSavedSettings,
  284. "MiniMapPlotCharacters");
  285. gGL.loadIdentity();
  286. gGL.loadUIIdentity();
  287. gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]);
  288. gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
  289. {
  290. LLLocalClipRect clip(getLocalRect());
  291. {
  292. unit0->unbind(LLTexUnit::TT_TEXTURE);
  293. gGL.matrixMode(LLRender::MM_MODELVIEW);
  294. // Draw background rectangle
  295. gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0,
  296. mBackgroundColor);
  297. }
  298. // Region 0,0 is in the middle
  299. S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX);
  300. S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY);
  301. gGL.pushMatrix();
  302. gGL.translatef((F32)center_sw_left, (F32)center_sw_bottom, 0.f);
  303. if (sMiniMapRotate)
  304. {
  305. // Rotate subsequent draws to agent rotation
  306. rotation = atan2f(gViewerCamera.getAtAxis().mV[VX],
  307. gViewerCamera.getAtAxis().mV[VY]);
  308. gGL.rotatef(rotation * RAD_TO_DEG, 0.f, 0.f, 1.f);
  309. }
  310. // Scale in pixels per meter
  311. F32 scale = mScale / REGION_WIDTH_METERS;
  312. static LLCachedControl<LLColor4U> map_this(gColors,
  313. "MiniMapThisRegion");
  314. static LLCachedControl<LLColor4U> map_live(gColors,
  315. "MiniMapLiveRegion");
  316. static LLCachedControl<LLColor4U> map_dead(gColors,
  317. "MiniMapDeadRegion");
  318. static LLCachedControl<LLColor4U> map_banned(gColors,
  319. "MiniMapBannedParcels");
  320. static LLCachedControl<LLColor4U> map_parcel(gColors,
  321. "MiniMapParcelBorders");
  322. static LLCachedControl<LLColor4U> map_borders(gColors,
  323. "MiniMapRegionBorders");
  324. const LLColor4 this_region_color = LLColor4(map_this);
  325. const LLColor4 live_region_color = LLColor4(map_live);
  326. const LLColor4 dead_region_color = LLColor4(map_dead);
  327. const LLVector3& cam_pos_agent = gAgent.getCameraPositionAgent();
  328. LLViewerRegion* agent_regionp = gAgent.getRegion();
  329. F32 areg_top = 0.f;
  330. F32 areg_bottom = 0.f;
  331. F32 areg_left = 0.f;
  332. F32 areg_right = 0.f;
  333. for (LLWorld::region_list_t::const_iterator
  334. iter = gWorld.getRegionList().begin(),
  335. end = gWorld.getRegionList().end();
  336. iter != end; ++iter)
  337. {
  338. LLViewerRegion* regionp = *iter;
  339. if (regionp == agent_regionp)
  340. {
  341. gGL.color4fv(this_region_color.mV);
  342. }
  343. else if (!regionp->isAlive())
  344. {
  345. gGL.color4fv(dead_region_color.mV);
  346. }
  347. else
  348. {
  349. gGL.color4fv(live_region_color.mV);
  350. }
  351. // Find x and y position relative to the center of camera.
  352. LLVector3 origin_agent = regionp->getOriginAgent();
  353. LLVector3 rel_region_pos = origin_agent - cam_pos_agent;
  354. F32 relative_x = rel_region_pos.mV[0] * scale;
  355. F32 relative_y = rel_region_pos.mV[1] * scale;
  356. // Background region rectangle
  357. F32 bottom = relative_y;
  358. F32 left = relative_x;
  359. // Variable region size support: scale the tile depending on region
  360. // actual width here.
  361. F32 tile_width = regionp->getWidth() * scale;
  362. F32 top = bottom + tile_width;
  363. F32 right = left + tile_width;
  364. if (regionp == agent_regionp)
  365. {
  366. areg_top = top;
  367. areg_bottom = bottom;
  368. areg_left = left;
  369. areg_right = right;
  370. }
  371. // Draw using texture.
  372. unit0->bind(regionp->getLand().getSTexture());
  373. gGL.begin(LLRender::TRIANGLES);
  374. gGL.texCoord2f(0.f, 1.f);
  375. gGL.vertex2f(left, top);
  376. gGL.texCoord2f(0.f, 0.f);
  377. gGL.vertex2f(left, bottom);
  378. gGL.texCoord2f(1.f, 0.f);
  379. gGL.vertex2f(right, bottom);
  380. gGL.texCoord2f(0.f, 1.f);
  381. gGL.vertex2f(left, top);
  382. gGL.texCoord2f(1.f, 0.f);
  383. gGL.vertex2f(right, bottom);
  384. gGL.texCoord2f(1.f, 1.f);
  385. gGL.vertex2f(right, top);
  386. gGL.end();
  387. static LLCachedControl<bool> draw_water(gSavedSettings,
  388. "MiniMapDrawWater");
  389. if (draw_water)
  390. {
  391. // Draw water
  392. LLViewerTexture* water_tex =
  393. regionp->getLand().getWaterTexture();
  394. if (water_tex)
  395. {
  396. unit0->bind(water_tex);
  397. gGL.begin(LLRender::TRIANGLES);
  398. gGL.texCoord2f(0.f, 1.f);
  399. gGL.vertex2f(left, top);
  400. gGL.texCoord2f(0.f, 0.f);
  401. gGL.vertex2f(left, bottom);
  402. gGL.texCoord2f(1.f, 0.f);
  403. gGL.vertex2f(right, bottom);
  404. gGL.texCoord2f(0.f, 1.f);
  405. gGL.vertex2f(left, top);
  406. gGL.texCoord2f(1.f, 0.f);
  407. gGL.vertex2f(right, bottom);
  408. gGL.texCoord2f(1.f, 1.f);
  409. gGL.vertex2f(right, top);
  410. gGL.end();
  411. }
  412. }
  413. }
  414. LLVector3d pos_center = getPosCenterGlobal();
  415. if (draw_objects)
  416. {
  417. // Redraw object layer periodically
  418. static F32 last_redraw = 0.f;
  419. if (mUpdateObjectImage || gFrameTimeSeconds - last_redraw > 0.5f)
  420. {
  421. last_redraw = gFrameTimeSeconds;
  422. updateObjectImage(pos_center);
  423. }
  424. LLVector3 map_center_agent =
  425. gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
  426. map_center_agent -= cam_pos_agent;
  427. F32 agent_x = map_center_agent.mV[VX] * scale;
  428. F32 agent_y = map_center_agent.mV[VY] * scale;
  429. unit0->bind(mObjectImagep);
  430. const F32 image_half_width = 0.5f * mObjectMapPixels;
  431. const F32 image_half_height = 0.5f * mObjectMapPixels;
  432. gGL.begin(LLRender::TRIANGLES);
  433. gGL.texCoord2f(0.f, 1.f);
  434. gGL.vertex2f(agent_x - image_half_width,
  435. image_half_height + agent_y);
  436. gGL.texCoord2f(0.f, 0.f);
  437. gGL.vertex2f(agent_x - image_half_width,
  438. agent_y - image_half_height);
  439. gGL.texCoord2f(1.f, 0.f);
  440. gGL.vertex2f(image_half_width + agent_x,
  441. agent_y - image_half_height);
  442. gGL.texCoord2f(0.f, 1.f);
  443. gGL.vertex2f(agent_x - image_half_width,
  444. image_half_height + agent_y);
  445. gGL.texCoord2f(1.f, 0.f);
  446. gGL.vertex2f(image_half_width + agent_x,
  447. agent_y - image_half_height);
  448. gGL.texCoord2f(1.f, 1.f);
  449. gGL.vertex2f(image_half_width + agent_x,
  450. image_half_height + agent_y);
  451. gGL.end();
  452. }
  453. static LLCachedControl<bool> show_parcels(gSavedSettings,
  454. "MinimapShowParcelBorders");
  455. static LLCachedControl<bool> show_banned(gSavedSettings,
  456. "MinimapShowBannedParcels");
  457. mHasDrawnParcels = show_parcels;
  458. if (fast_parcels && show_parcels)
  459. {
  460. if (mUpdateParcelImage ||
  461. dist_vec_squared2D(pos_center, mParcelImageCenterGlobal) > 9.f)
  462. {
  463. updateParcelImage(pos_center, map_parcel);
  464. }
  465. LLVector3 map_center_agent =
  466. gAgent.getPosAgentFromGlobal(mParcelImageCenterGlobal);
  467. map_center_agent -= cam_pos_agent;
  468. F32 agent_x = map_center_agent.mV[VX] * scale;
  469. F32 agent_y = map_center_agent.mV[VY] * scale;
  470. unit0->bind(mParcelImagep);
  471. const F32 image_half_width = 0.5f * mObjectMapPixels;
  472. const F32 image_half_height = 0.5f * mObjectMapPixels;
  473. gGL.begin(LLRender::TRIANGLES);
  474. gGL.texCoord2f(0.f, 1.f);
  475. gGL.vertex2f(agent_x - image_half_width,
  476. image_half_height + agent_y);
  477. gGL.texCoord2f(0.f, 0.f);
  478. gGL.vertex2f(agent_x - image_half_width,
  479. agent_y - image_half_height);
  480. gGL.texCoord2f(1.f, 0.f);
  481. gGL.vertex2f(image_half_width + agent_x,
  482. agent_y - image_half_height);
  483. gGL.texCoord2f(0.f, 1.f);
  484. gGL.vertex2f(agent_x - image_half_width,
  485. image_half_height + agent_y);
  486. gGL.texCoord2f(1.f, 0.f);
  487. gGL.vertex2f(image_half_width + agent_x,
  488. agent_y - image_half_height);
  489. gGL.texCoord2f(1.f, 1.f);
  490. gGL.vertex2f(image_half_width + agent_x,
  491. image_half_height + agent_y);
  492. gGL.end();
  493. }
  494. if (fast_parcels && show_banned)
  495. {
  496. const LLColor4 banned_color = LLColor4(map_banned);
  497. for (LLWorld::region_list_t::const_iterator
  498. iter = gWorld.getRegionList().begin(),
  499. end = gWorld.getRegionList().end();
  500. iter != end; ++iter)
  501. {
  502. LLViewerRegion* regionp = *iter;
  503. if (regionp->renderBannedParcels(scale, banned_color.mV))
  504. {
  505. mHasDrawnParcels = true;
  506. }
  507. }
  508. }
  509. if (!fast_parcels && (show_parcels || show_banned))
  510. {
  511. const LLColor4 banned_color = LLColor4(map_banned);
  512. const LLColor4 parcel_color = LLColor4(map_parcel);
  513. for (LLWorld::region_list_t::const_iterator
  514. iter = gWorld.getRegionList().begin(),
  515. end = gWorld.getRegionList().end();
  516. iter != end; ++iter)
  517. {
  518. LLViewerRegion* regionp = *iter;
  519. if (show_parcels)
  520. {
  521. regionp->renderParcelBorders(scale, parcel_color.mV);
  522. }
  523. if (show_banned &&
  524. regionp->renderBannedParcels(scale, banned_color.mV))
  525. {
  526. mHasDrawnParcels = true;
  527. }
  528. }
  529. }
  530. // Draw agent region borders. HB
  531. static LLCachedControl<bool> draw_borders(gSavedSettings,
  532. "MiniMapDrawBorders");
  533. if (draw_borders && areg_top != areg_bottom)
  534. {
  535. gl_rect_2d(areg_left, areg_top, areg_right, areg_bottom,
  536. LLColor4(map_borders), false);
  537. }
  538. gGL.popMatrix();
  539. LLVector3 pos_map;
  540. LLColor4 avatar_color;
  541. // Draw physical objects. HB
  542. if (plot_physical && !mPhysicalObjectsPos.empty())
  543. {
  544. avatar_color = LLColor4(map_phys);
  545. for (objs_pos_vec_t::iterator it = mPhysicalObjectsPos.begin(),
  546. end = mPhysicalObjectsPos.end();
  547. it != end; ++it)
  548. {
  549. const LLVector3d& pos = *it;
  550. pos_map = globalPosToView(pos, sMiniMapRotate);
  551. drawAvatar(avatar_color, pos_map);
  552. }
  553. }
  554. // Draw path-finding characters. HB
  555. if (plot_characters && !mPathfindingCharsPos.empty())
  556. {
  557. avatar_color = LLColor4(map_chars);
  558. for (objs_pos_vec_t::iterator it = mPathfindingCharsPos.begin(),
  559. end = mPathfindingCharsPos.end();
  560. it != end; ++it)
  561. {
  562. const LLVector3d& pos = *it;
  563. pos_map = globalPosToView(pos, sMiniMapRotate);
  564. drawAvatar(avatar_color, pos_map);
  565. }
  566. }
  567. static LLCachedControl<U32> unknwown_alt(gSavedSettings,
  568. "UnknownAvatarAltitude");
  569. // Draw puppets. HB
  570. if (plot_puppets)
  571. {
  572. avatar_color = LLColor4(map_puppets);
  573. for (S32 i = 0, count = LLCharacter::sInstances.size();
  574. i < count; ++i)
  575. {
  576. LLVOAvatar* avatarp = (LLVOAvatar*)LLCharacter::sInstances[i];
  577. if (!avatarp || avatarp->isDead() || avatarp->isOrphaned() ||
  578. !avatarp->isPuppetAvatar() ||
  579. (LLXform*)avatarp != avatarp->getRoot())
  580. {
  581. continue;
  582. }
  583. LLVector3d pos = avatarp->getPositionGlobal();
  584. pos_map = globalPosToView(pos, sMiniMapRotate);
  585. if (pos.mdV[VZ] == (F32)unknwown_alt)
  586. {
  587. pos_map.mV[VZ] = 16000.f;
  588. }
  589. drawAvatar(avatar_color, pos_map);
  590. }
  591. }
  592. // Prepare for "closest avatar to cursor" detection. Note: mouse
  593. // pointer is in local coordinates.
  594. S32 local_mouse_x;
  595. S32 local_mouse_y;
  596. LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
  597. mClosestAgentToCursor.setNull();
  598. F32 closest_dist = F32_MAX;
  599. F32 min_pick_dist = mDotRadius * MIN_PICK_SCALE;
  600. // Draw avatars
  601. uuid_vec_t avatar_ids;
  602. std::vector<LLVector3d> positions;
  603. std::vector<LLColor4> colors;
  604. gWorld.getAvatars(avatar_ids, &positions, &colors);
  605. for (U32 i = 0, count = avatar_ids.size(); i < count; ++i)
  606. {
  607. const LLUUID& av_id = avatar_ids[i];
  608. if (av_id == gAgentID) continue;
  609. const LLVector3d& pos = positions[i];
  610. pos_map = globalPosToView(pos, sMiniMapRotate);
  611. if (pos.mdV[VZ] == (F32)unknwown_alt)
  612. {
  613. pos_map.mV[VZ] = 16000.f;
  614. }
  615. //MK
  616. // Do not show specific colors under @shownames, since it can give
  617. // away an information about the avatars who are around
  618. if (gRLenabled &&
  619. (gRLInterface.mContainsShownames ||
  620. gRLInterface.mContainsShowNearby ||
  621. gRLInterface.mContainsShownametags))
  622. {
  623. avatar_color = LLColor4(map_avatar);
  624. }
  625. else
  626. //mk
  627. {
  628. avatar_color = colors[i];
  629. }
  630. drawAvatar(avatar_color, pos_map);
  631. F32 dist_to_cursor =
  632. dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
  633. LLVector2(local_mouse_x, local_mouse_y));
  634. if (dist_to_cursor < min_pick_dist &&
  635. dist_to_cursor < closest_dist)
  636. {
  637. closest_dist = dist_to_cursor;
  638. mClosestAgentToCursor = av_id;
  639. }
  640. }
  641. // Draw dot for autopilot target
  642. if (gAgentPilot.isActive())
  643. {
  644. drawTracking(gAgentPilot.getAutoPilotTargetGlobal(),
  645. sMiniMapRotate, LLUI::sTrackColor);
  646. }
  647. else
  648. {
  649. LLTracker::ETrackingStatus tracking_status =
  650. gTracker.getTrackingStatus();
  651. if (tracking_status == LLTracker::TRACKING_AVATAR)
  652. {
  653. drawTracking(gAvatarTracker.getGlobalPos(),
  654. sMiniMapRotate, LLUI::sTrackColor);
  655. }
  656. else if (tracking_status == LLTracker::TRACKING_LANDMARK ||
  657. tracking_status == LLTracker::TRACKING_LOCATION)
  658. {
  659. drawTracking(gTracker.getTrackedPositionGlobal(),
  660. sMiniMapRotate, LLUI::sTrackColor);
  661. }
  662. }
  663. // Draw dot for self avatar position
  664. pos_map = globalPosToView(gAgent.getPositionGlobal(), sMiniMapRotate);
  665. LLUIImagePtr you = LLPanelWorldMap::sAvatarYouLargeImage;
  666. S32 dot_width = ll_roundp(mDotRadius * 2.f);
  667. you->draw(ll_round(pos_map.mV[VX] - mDotRadius),
  668. ll_round(pos_map.mV[VY] - mDotRadius),
  669. dot_width, dot_width);
  670. // Draw frustum
  671. F32 horiz_fov = gViewerCamera.getView() * gViewerCamera.getAspect();
  672. F32 far_clip_meters = gViewerCamera.getFar();
  673. F32 far_clip_pixels = far_clip_meters * scale;
  674. F32 half_width_meters = far_clip_meters * tanf(horiz_fov * 0.5f);
  675. F32 half_width_pixels = half_width_meters * scale;
  676. F32 ctr_x = (F32)center_sw_left;
  677. F32 ctr_y = (F32)center_sw_bottom;
  678. unit0->unbind(LLTexUnit::TT_TEXTURE);
  679. static LLCachedControl<LLColor4U> frustum(gColors,
  680. "MiniMapFrustum");
  681. static LLCachedControl<LLColor4U> rot_frustum(gColors,
  682. "MiniMapFrustumRotating");
  683. if (sMiniMapRotate)
  684. {
  685. gGL.color4fv(LLColor4(frustum).mV);
  686. gGL.begin(LLRender::TRIANGLES);
  687. gGL.vertex2f(ctr_x, ctr_y);
  688. gGL.vertex2f(ctr_x - half_width_pixels, ctr_y + far_clip_pixels);
  689. gGL.vertex2f(ctr_x + half_width_pixels, ctr_y + far_clip_pixels);
  690. gGL.end();
  691. }
  692. else
  693. {
  694. gGL.color4fv(LLColor4(rot_frustum).mV);
  695. // If we do not rotate the map, we have to rotate the frustum.
  696. gGL.pushMatrix();
  697. gGL.translatef(ctr_x, ctr_y, 0.f);
  698. gGL.rotatef(atan2f(gViewerCamera.getAtAxis().mV[VX],
  699. gViewerCamera.getAtAxis().mV[VY]) *
  700. RAD_TO_DEG, 0.f, 0.f, -1.f);
  701. gGL.begin(LLRender::TRIANGLES);
  702. gGL.vertex2f(0.f, 0.f);
  703. gGL.vertex2f(-half_width_pixels, far_clip_pixels);
  704. gGL.vertex2f(half_width_pixels, far_clip_pixels);
  705. gGL.end();
  706. gGL.popMatrix();
  707. }
  708. }
  709. gGL.popUIMatrix();
  710. gGL.popMatrix();
  711. // Rotation of 0 means that North is up
  712. setDirectionPos(mEastLabel, rotation);
  713. setDirectionPos(mNorthLabel, rotation + F_PI_BY_TWO);
  714. setDirectionPos(mWestLabel, rotation + F_PI);
  715. setDirectionPos(mSouthLabel, rotation + (F_PI + F_PI_BY_TWO));
  716. constexpr F32 F_PI_BY_FOUR = F_PI_BY_TWO * 0.5f;
  717. setDirectionPos(mNorthEastLabel, rotation + F_PI_BY_FOUR);
  718. setDirectionPos(mNorthWestLabel, rotation + (F_PI_BY_TWO + F_PI_BY_FOUR));
  719. setDirectionPos(mSouthWestLabel, rotation + (F_PI + F_PI_BY_FOUR));
  720. setDirectionPos(mSouthEastLabel,
  721. rotation + (F_PI + F_PI_BY_TWO + F_PI_BY_FOUR));
  722. // Draw plots legend. HB
  723. static LLCachedControl<bool> plots_legend(gSavedSettings,
  724. "MiniMapPlotsLegend");
  725. if (plots_legend && mFontp)
  726. {
  727. static LLCachedControl<LLColor4U> map_friend(gColors, "MapFriend");
  728. constexpr S32 DELTA_Y = 9;
  729. constexpr S32 BORDER_MARGIN = 4;
  730. S32 bottom = BORDER_MARGIN;
  731. mFontp->renderUTF8(mLegendAvatar, 0, BORDER_MARGIN, bottom,
  732. LLColor4(map_avatar), LLFontGL::LEFT,
  733. LLFontGL::BASELINE, LLFontGL::DROP_SHADOW_SOFT);
  734. mFontp->renderUTF8(mLegendFriend, 0,
  735. BORDER_MARGIN + mFriendLegendDeltaX, bottom,
  736. LLColor4(map_friend), LLFontGL::LEFT,
  737. LLFontGL::BASELINE, LLFontGL::DROP_SHADOW_SOFT);
  738. bottom += DELTA_Y;
  739. if (draw_objects)
  740. {
  741. if (plot_characters)
  742. {
  743. mFontp->renderUTF8(mLegendPathFinding, 0, BORDER_MARGIN,
  744. bottom, LLColor4(map_chars), LLFontGL::LEFT,
  745. LLFontGL::BASELINE,
  746. LLFontGL::DROP_SHADOW_SOFT);
  747. bottom += DELTA_Y;
  748. }
  749. if (plot_physical)
  750. {
  751. mFontp->renderUTF8(mLegendPhysical, 0, BORDER_MARGIN, bottom,
  752. LLColor4(map_phys), LLFontGL::LEFT,
  753. LLFontGL::BASELINE,
  754. LLFontGL::DROP_SHADOW_SOFT);
  755. bottom += DELTA_Y;
  756. }
  757. }
  758. if (plot_puppets)
  759. {
  760. mFontp->renderUTF8(mLegendAnimesh, 0, BORDER_MARGIN, bottom,
  761. LLColor4(map_puppets), LLFontGL::LEFT,
  762. LLFontGL::BASELINE, LLFontGL::DROP_SHADOW_SOFT);
  763. }
  764. }
  765. LLView::draw();
  766. }
  767. //virtual
  768. void LLPanelMiniMap::reshape(S32 width, S32 height, bool called_from_parent)
  769. {
  770. LLPanel::reshape(width, height, called_from_parent);
  771. createObjectImage();
  772. updateMinorDirections();
  773. }
  774. LLVector3 LLPanelMiniMap::globalPosToView(const LLVector3d& global_pos,
  775. bool rotated) const
  776. {
  777. LLVector3d relative_pos_global = global_pos -
  778. gAgent.getCameraPositionGlobal();
  779. LLVector3 pos_local(relative_pos_global); // Convert to floats from doubles
  780. pos_local.mV[VX] *= mPixelsPerMeter;
  781. pos_local.mV[VY] *= mPixelsPerMeter;
  782. // Leave Z component in meters
  783. if (rotated)
  784. {
  785. F32 radians = atan2f(gViewerCamera.getAtAxis().mV[VX],
  786. gViewerCamera.getAtAxis().mV[VY]);
  787. LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f));
  788. pos_local.rotVec(rot);
  789. }
  790. pos_local.mV[VX] += getRect().getWidth() / 2 + mCurPanX;
  791. pos_local.mV[VY] += getRect().getHeight() / 2 + mCurPanY;
  792. return pos_local;
  793. }
  794. void LLPanelMiniMap::drawAvatar(const LLColor4& color, const LLVector3& pos)
  795. {
  796. constexpr F32 HEIGHT_THRESHOLD = 7.f;
  797. const F32& x_pixels = pos.mV[VX];
  798. const F32& y_pixels = pos.mV[VY];
  799. const F32& relative_z = pos.mV[VZ];
  800. LLUIImagePtr dot_image = LLPanelWorldMap::sAvatarSmallImage;
  801. // Allow the use of old style avatar dots. HB
  802. static LLCachedControl<bool> use_old_dots(gSavedSettings,
  803. "UseOldTrackingDots");
  804. if (use_old_dots || relative_z == 16000.f)
  805. {
  806. F32 left = x_pixels - mDotRadius;
  807. F32 right = x_pixels + mDotRadius;
  808. F32 center = (left + right) * 0.5f;
  809. F32 top = y_pixels + mDotRadius;
  810. F32 bottom = y_pixels - mDotRadius;
  811. if (relative_z == 16000.f)
  812. {
  813. // Unknown altitude (0m or > 1020m). HB
  814. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  815. gGL.color4fv(color.mV);
  816. LLUI::setLineWidth(1.5f);
  817. gGL.begin(LLRender::LINES);
  818. gGL.vertex2f(left, y_pixels);
  819. gGL.vertex2f(right, y_pixels);
  820. gGL.end();
  821. LLUI::setLineWidth(1.f);
  822. }
  823. else if (relative_z > HEIGHT_THRESHOLD)
  824. {
  825. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  826. gGL.color4fv(color.mV);
  827. LLUI::setLineWidth(1.5f);
  828. gGL.begin(LLRender::LINES);
  829. gGL.vertex2f(left, top);
  830. gGL.vertex2f(right, top);
  831. gGL.vertex2f(center, top);
  832. gGL.vertex2f(center, bottom);
  833. gGL.end();
  834. LLUI::setLineWidth(1.f);
  835. }
  836. else if (relative_z > -HEIGHT_THRESHOLD)
  837. {
  838. dot_image->draw(ll_roundp(x_pixels) - dot_image->getWidth() / 2,
  839. ll_roundp(y_pixels) - dot_image->getHeight() / 2,
  840. color);
  841. }
  842. else
  843. {
  844. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  845. gGL.color4fv(color.mV);
  846. LLUI::setLineWidth(1.5f);
  847. gGL.begin(LLRender::LINES);
  848. gGL.vertex2f(center, top);
  849. gGL.vertex2f(center, bottom);
  850. gGL.vertex2f(left, bottom);
  851. gGL.vertex2f(right, bottom);
  852. gGL.end();
  853. LLUI::setLineWidth(1.f);
  854. }
  855. }
  856. else
  857. {
  858. if (relative_z < -HEIGHT_THRESHOLD)
  859. {
  860. dot_image = LLPanelWorldMap::sAvatarBelowImage;
  861. }
  862. else if (relative_z > HEIGHT_THRESHOLD)
  863. {
  864. dot_image = LLPanelWorldMap::sAvatarAboveImage;
  865. }
  866. S32 dot_width = ll_roundp(mDotRadius * 2.f);
  867. dot_image->draw(ll_roundp(x_pixels - mDotRadius),
  868. ll_roundp(y_pixels - mDotRadius),
  869. dot_width, dot_width, color);
  870. }
  871. }
  872. void LLPanelMiniMap::drawTracking(const LLVector3d& pos_global, bool rotated,
  873. const LLColor4& color, bool draw_arrow)
  874. {
  875. LLVector3 pos_local = globalPosToView(pos_global, rotated);
  876. if (pos_local.mV[VX] < 0.f || pos_local.mV[VY] < 0.f ||
  877. pos_local.mV[VX] >= getRect().getWidth() ||
  878. pos_local.mV[VY] >= getRect().getHeight())
  879. {
  880. if (draw_arrow)
  881. {
  882. S32 x = ll_roundp(pos_local.mV[VX]);
  883. S32 y = ll_roundp(pos_local.mV[VY]);
  884. LLPanelWorldMap::drawTrackingCircle(getRect(), x, y, color, 1, 10);
  885. LLPanelWorldMap::drawTrackingArrow(getRect(), x, y, color);
  886. }
  887. return;
  888. }
  889. const LLUIImagePtr& dot_image = LLPanelWorldMap::sTrackCircleImage;
  890. const F32& x_pixels = pos_local.mV[VX];
  891. const F32& y_pixels = pos_local.mV[VY];
  892. const F32& relative_z = pos_local.mV[VZ];
  893. constexpr F32 HEIGHT_THRESHOLD = 7.f;
  894. if (relative_z >= -HEIGHT_THRESHOLD && relative_z <= HEIGHT_THRESHOLD)
  895. {
  896. S32 x = ll_roundp(x_pixels) - dot_image->getWidth() / 2;
  897. S32 y = ll_roundp(y_pixels) - dot_image->getHeight() / 2;
  898. dot_image->draw(x, y, color);
  899. }
  900. else
  901. {
  902. // Draw V indicator for above or below
  903. // *TODO: Replace this vector drawing with icons
  904. F32 left = x_pixels - mDotRadius;
  905. F32 right = x_pixels + mDotRadius;
  906. F32 center = (left + right) * 0.5f;
  907. F32 top = y_pixels + mDotRadius;
  908. F32 bottom = y_pixels - mDotRadius;
  909. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  910. gGL.color4fv(color.mV);
  911. LLUI::setLineWidth(3.f);
  912. // Y pos of the point of the V
  913. F32 point = relative_z > HEIGHT_THRESHOLD ? top : bottom;
  914. // Y pos of the ends of the V
  915. F32 back = relative_z > HEIGHT_THRESHOLD ? bottom : top;
  916. gGL.begin(LLRender::LINES);
  917. gGL.vertex2f(left, back);
  918. gGL.vertex2f(center, point);
  919. gGL.vertex2f(center, point);
  920. gGL.vertex2f(right, back);
  921. gGL.end();
  922. LLUI::setLineWidth(1.f);
  923. }
  924. }
  925. LLVector3d LLPanelMiniMap::viewPosToGlobal(S32 x, S32 y, bool rotated) const
  926. {
  927. x -= ll_round(getRect().getWidth() / 2 + mCurPanX);
  928. y -= ll_round(getRect().getHeight() / 2 + mCurPanY);
  929. LLVector3 pos_local((F32)x, (F32)y, 0.f);
  930. if (rotated)
  931. {
  932. F32 radians = -atan2f(gViewerCamera.getAtAxis().mV[VX],
  933. gViewerCamera.getAtAxis().mV[VY]);
  934. LLQuaternion rot(radians, LLVector3::z_axis);
  935. pos_local.rotVec(rot);
  936. }
  937. // Unintuitive and hacky... To support variable region size we must make
  938. // the mini-map believe regions got a fixed size of 256m...
  939. pos_local *= REGION_WIDTH_METERS / mScale;
  940. return LLVector3d(pos_local) + gAgent.getCameraPositionGlobal();
  941. }
  942. void LLPanelMiniMap::setDirectionPos(LLTextBox* text_box, F32 rotation)
  943. {
  944. // Rotation is in radians.
  945. // Rotation of 0 means x = 1, y = 0 on the unit circle.
  946. F32 half_height = (F32)((getRect().getHeight() -
  947. text_box->getRect().getHeight()) / 2);
  948. F32 half_width = (F32)((getRect().getWidth() -
  949. text_box->getRect().getWidth()) / 2);
  950. F32 radius = llmin(half_height, half_width);
  951. // Inset by a little to account for position display.
  952. radius -= 8.f;
  953. text_box->setOrigin(ll_round(half_width + radius * cosf(rotation)),
  954. ll_round(half_height + radius * sinf(rotation)));
  955. }
  956. void LLPanelMiniMap::updateMinorDirections()
  957. {
  958. if (!mNorthEastLabel)
  959. {
  960. return;
  961. }
  962. // Hide minor directions if they cover too much of the map
  963. bool show_minors = mNorthEastLabel->getRect().getHeight() <
  964. MAP_MINOR_DIR_THRESHOLD * llmin(getRect().getWidth(),
  965. getRect().getHeight());
  966. mNorthEastLabel->setVisible(show_minors);
  967. mNorthWestLabel->setVisible(show_minors);
  968. mSouthEastLabel->setVisible(show_minors);
  969. mSouthWestLabel->setVisible(show_minors);
  970. }
  971. void LLPanelMiniMap::renderScaledPointGlobal(const LLVector3d& pos,
  972. const LLColor4U& color,
  973. F32 radius_meters)
  974. {
  975. static LLCachedControl<F32> max_radius(gSavedSettings,
  976. "MiniMapPrimMaxRadius");
  977. // Limit the size of megaprims so they do not blot out everything on
  978. // the mini-map. Attempting to draw very large megaprims also causes
  979. // client lag. See DEV-17370 and SNOW-79 for details.
  980. if (radius_meters > (F32)max_radius)
  981. {
  982. radius_meters = max_radius;
  983. }
  984. S32 diameter_pixels = ll_roundp(2 * radius_meters * mObjectMapTPM);
  985. LLVector3 local_pos;
  986. local_pos.set(pos - mObjectImageCenterGlobal);
  987. renderPoint(local_pos, color, diameter_pixels);
  988. }
  989. void LLPanelMiniMap::renderPoint(const LLVector3& pos_local,
  990. const LLColor4U& color,
  991. S32 diameter, S32 relative_height)
  992. {
  993. if (diameter <= 0)
  994. {
  995. return;
  996. }
  997. const S32 image_width = (S32)mObjectImagep->getWidth();
  998. S32 x_offset = ll_round(pos_local.mV[VX] * mObjectMapTPM +
  999. image_width / 2);
  1000. if (x_offset < 0 || x_offset >= image_width)
  1001. {
  1002. return;
  1003. }
  1004. const S32 image_height = (S32)mObjectImagep->getHeight();
  1005. S32 y_offset = ll_round(pos_local.mV[VY] * mObjectMapTPM +
  1006. image_height / 2);
  1007. if (y_offset < 0 || y_offset >= image_height)
  1008. {
  1009. return;
  1010. }
  1011. U8* datap = mObjectRawImagep->getData();
  1012. S32 neg_radius = diameter / 2;
  1013. S32 pos_radius = diameter - neg_radius;
  1014. S32 x, y;
  1015. if (relative_height > 0)
  1016. {
  1017. // Point above agent
  1018. S32 px, py;
  1019. // Vertical line
  1020. px = x_offset;
  1021. for (y = -neg_radius; y < pos_radius; ++y)
  1022. {
  1023. py = y_offset + y;
  1024. if (py >= 0 && py < image_height)
  1025. {
  1026. S32 offset = px + py * image_width;
  1027. ((U32*)datap)[offset] = color.asRGBA();
  1028. }
  1029. }
  1030. // Top line
  1031. py = y_offset + pos_radius - 1;
  1032. for (x = -neg_radius; x < pos_radius; ++x)
  1033. {
  1034. px = x_offset + x;
  1035. if (px >= 0 && px < image_width)
  1036. {
  1037. S32 offset = px + py * image_width;
  1038. ((U32*)datap)[offset] = color.asRGBA();
  1039. }
  1040. }
  1041. }
  1042. else
  1043. {
  1044. // Point level with agent
  1045. for (x = -neg_radius; x < pos_radius; ++x)
  1046. {
  1047. S32 p_x = x_offset + x;
  1048. if (p_x > 0 && p_x < image_width)
  1049. {
  1050. for (y = -neg_radius; y < pos_radius; ++y)
  1051. {
  1052. S32 p_y = y_offset + y;
  1053. if (p_y >= 0 && p_y < image_height)
  1054. {
  1055. S32 offset = p_x + p_y * image_width;
  1056. ((U32*)datap)[offset] = color.asRGBA();
  1057. }
  1058. }
  1059. }
  1060. }
  1061. }
  1062. }
  1063. LLVector3d LLPanelMiniMap::getPosCenterGlobal() const
  1064. {
  1065. // Locate the centre of the object layer, accounting for panning
  1066. LLVector3 center = globalPosToView(gAgent.getCameraPositionGlobal(),
  1067. sMiniMapRotate);
  1068. center.mV[0] -= mCurPanX;
  1069. center.mV[1] -= mCurPanY;
  1070. center.mV[2] = 0.f;
  1071. return viewPosToGlobal(ll_round(center.mV[0]), ll_round(center.mV[1]),
  1072. sMiniMapRotate);
  1073. }
  1074. bool LLPanelMiniMap::createRawImage(LLPointer<LLImageRaw>& rawimagep)
  1075. {
  1076. // Find the size of the side of a square that surrounds the circle that
  1077. // surrounds getRect()... which is, the diagonal of the rect.
  1078. F32 width = getRect().getWidth();
  1079. F32 height = getRect().getHeight();
  1080. S32 square_size = ll_roundp(sqrtf(width * width + height * height));
  1081. // Find the least power of two >= the minimum size.
  1082. constexpr S32 MIN_SIZE = 64;
  1083. constexpr S32 MAX_SIZE = 256;
  1084. S32 img_size = MIN_SIZE;
  1085. while (img_size * 2 < square_size && img_size < MAX_SIZE)
  1086. {
  1087. img_size <<= 1;
  1088. }
  1089. if (rawimagep.isNull() || rawimagep->getWidth() != img_size ||
  1090. rawimagep->getHeight() != img_size)
  1091. {
  1092. rawimagep = new LLImageRaw(img_size, img_size, 4);
  1093. U8* data = rawimagep->getData();
  1094. if (data)
  1095. {
  1096. memset(data, 0, img_size * img_size * 4);
  1097. return true;
  1098. }
  1099. }
  1100. return false;
  1101. }
  1102. void LLPanelMiniMap::createObjectImage()
  1103. {
  1104. if (createRawImage(mObjectRawImagep))
  1105. {
  1106. mObjectImagep =
  1107. LLViewerTextureManager::getLocalTexture(mObjectRawImagep.get(),
  1108. false);
  1109. }
  1110. setScale(mScale);
  1111. mUpdateObjectImage = true;
  1112. }
  1113. void LLPanelMiniMap::createParcelImage()
  1114. {
  1115. if (createRawImage(mParcelRawImagep))
  1116. {
  1117. mParcelImagep =
  1118. LLViewerTextureManager::getLocalTexture(mParcelRawImagep.get(),
  1119. false);
  1120. }
  1121. setScale(mScale);
  1122. mUpdateParcelImage = true;
  1123. }
  1124. void LLPanelMiniMap::updateObjectImage(const LLVector3d& pos_center_global)
  1125. {
  1126. mUpdateObjectImage = false;
  1127. mObjectImageCenterGlobal = pos_center_global;
  1128. // Create the base texture.
  1129. S32 img_width = mObjectImagep->getWidth();
  1130. S32 img_height = mObjectImagep->getHeight();
  1131. U8* default_texture = mObjectRawImagep->getData();
  1132. memset((void*)default_texture, 0,
  1133. img_width * img_height * mObjectImagep->getComponents());
  1134. // Clear the cached positions for pathfinding characters and physical
  1135. // objects since they will be re-filled by the renderObjectsForMap()
  1136. // method. HB
  1137. mPathfindingCharsPos.clear();
  1138. mPhysicalObjectsPos.clear();
  1139. // Draw objects
  1140. gObjectList.renderObjectsForMap(this);
  1141. mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, img_width, img_height);
  1142. }
  1143. void LLPanelMiniMap::updateParcelImage(const LLVector3d& pos_center_global,
  1144. LLColor4U color)
  1145. {
  1146. mUpdateParcelImage = false;
  1147. mParcelImageCenterGlobal = pos_center_global;
  1148. // Make the borders color opaque since the image is already rendered as a
  1149. // semi-transparent overlay on the mini-map... HB
  1150. color.mV[VW] = 255;
  1151. // Create the base texture.
  1152. S32 img_width = mParcelImagep->getWidth();
  1153. S32 img_height = mParcelImagep->getHeight();
  1154. U8* default_texture = mParcelRawImagep->getData();
  1155. memset((void*)default_texture, 0,
  1156. img_width * img_height * mParcelRawImagep->getComponents());
  1157. for (LLWorld::region_list_t::const_iterator
  1158. iter = gWorld.getRegionList().begin(),
  1159. end = gWorld.getRegionList().end();
  1160. iter != end; ++iter)
  1161. {
  1162. renderParcelBorders(*iter, color, img_width, img_height);
  1163. }
  1164. mParcelImagep->setSubImage(mParcelRawImagep, 0, 0, img_width, img_height);
  1165. }
  1166. // Backported from Singularity, itself derived from Catznip's code. HB
  1167. void LLPanelMiniMap::renderParcelBorders(const LLViewerRegion* regionp,
  1168. const LLColor4U& color,
  1169. S32 img_width, S32 img_height)
  1170. {
  1171. LLViewerParcelOverlay* overlayp = regionp->getParcelOverlay();
  1172. if (!overlayp)
  1173. {
  1174. return; // Cannot draw anything at this point !
  1175. }
  1176. LLVector3 local_origin(regionp->getOriginGlobal() -
  1177. mParcelImageCenterGlobal);
  1178. S32 x0 = ll_round(local_origin.mV[VX] * mObjectMapTPM + img_width / 2);
  1179. S32 y0 = ll_round(local_origin.mV[VY] * mObjectMapTPM + img_width / 2);
  1180. U32* tex_data = (U32*)mParcelRawImagep->getData();
  1181. // Draw the North and East region borders
  1182. S32 width = ll_round(regionp->getWidth() * mObjectMapTPM);
  1183. S32 y = y0 + width;
  1184. if (y >= 0 && y < img_height)
  1185. {
  1186. S32 line_offset = y * img_width;
  1187. for (S32 x = llclamp(x0, 0, img_width),
  1188. end = llclamp(x0 + width, 0, img_width);
  1189. x < end; ++x)
  1190. {
  1191. tex_data[line_offset + x] = color.mAll;
  1192. }
  1193. }
  1194. S32 x = x0 + width;
  1195. if (x >= 0 && x < img_width)
  1196. {
  1197. for (S32 y = llclamp(y0, 0, img_height),
  1198. end = llclamp(y0 + width, 0, img_height);
  1199. y < end; ++y)
  1200. {
  1201. tex_data[y * img_width + x] = color.mAll;
  1202. }
  1203. }
  1204. // Render South and West parcel lines
  1205. S32 grids_per_edge = overlayp->getParcelGridsPerEdge();
  1206. width = ll_round(PARCEL_GRID_STEP_METERS * mObjectMapTPM);
  1207. F32 scale = PARCEL_GRID_STEP_METERS * mObjectMapTPM;
  1208. for (S32 row = 0; row < grids_per_edge; ++row)
  1209. {
  1210. S32 pos_y = y0 + ll_round(scale * row);
  1211. S32 line_offset = pos_y * img_width;
  1212. for (S32 col = 0; col < grids_per_edge; ++col)
  1213. {
  1214. S32 pos_x = x0 + ll_round(scale * col);
  1215. S32 overlay = overlayp->parcelLineFlags(row, col);
  1216. if ((overlay & PARCEL_SOUTH_LINE) && pos_y >= 0 &&
  1217. pos_y < img_height)
  1218. {
  1219. for (S32 x = llclamp(pos_x, 0, img_width),
  1220. end = llclamp(pos_x + width, 0, img_width);
  1221. x < end; ++x)
  1222. {
  1223. tex_data[line_offset + x] = color.mAll;
  1224. }
  1225. }
  1226. if ((overlay & PARCEL_WEST_LINE) && pos_x >= 0 &&
  1227. pos_x < img_width)
  1228. {
  1229. for (S32 y = llclamp(pos_y, 0, img_height),
  1230. end = llclamp(pos_y + width, 0, img_height);
  1231. y < end; ++y)
  1232. {
  1233. tex_data[y * img_width + pos_x] = color.mAll;
  1234. }
  1235. }
  1236. }
  1237. }
  1238. }
  1239. //virtual
  1240. bool LLPanelMiniMap::handleToolTip(S32 x, S32 y, std::string& msg,
  1241. LLRect* sticky_rect_screen)
  1242. {
  1243. msg.clear();
  1244. if (gDisconnected || LLApp::isExiting())
  1245. {
  1246. return false;
  1247. }
  1248. LLVector3d pos = viewPosToGlobal(x, y, sMiniMapRotate);
  1249. LLViewerRegion* regionp = gWorld.getRegionFromPosGlobal(pos);
  1250. if (!regionp)
  1251. {
  1252. return LLPanel::handleToolTip(x, y, msg, sticky_rect_screen);
  1253. }
  1254. // Set the sticky_rect
  1255. S32 SLOP = 4;
  1256. localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect_screen->mLeft),
  1257. &(sticky_rect_screen->mBottom));
  1258. sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
  1259. sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
  1260. std::string fullname;
  1261. if (mClosestAgentToCursor.notNull() && gCacheNamep &&
  1262. gCacheNamep->getFullName(mClosestAgentToCursor, fullname))
  1263. {
  1264. //MK
  1265. if (gRLenabled &&
  1266. (gRLInterface.mContainsShownames ||
  1267. gRLInterface.mContainsShowNearby ||
  1268. gRLInterface.mContainsShownametags))
  1269. {
  1270. fullname = gRLInterface.getDummyName(fullname);
  1271. }
  1272. else
  1273. //mk
  1274. if (LLAvatarNameCache::useDisplayNames())
  1275. {
  1276. LLAvatarName avatar_name;
  1277. if (LLAvatarNameCache::get(mClosestAgentToCursor, &avatar_name))
  1278. {
  1279. if (LLAvatarNameCache::useDisplayNames() == 2)
  1280. {
  1281. fullname = avatar_name.mDisplayName;
  1282. }
  1283. else
  1284. {
  1285. fullname = avatar_name.getNames(true);
  1286. }
  1287. }
  1288. }
  1289. msg = fullname + "\n";
  1290. }
  1291. //MK
  1292. if (!gRLenabled || !gRLInterface.mContainsShowloc)
  1293. //mk
  1294. {
  1295. msg += mRegionPrefix + regionp->getName() + "\n";
  1296. // Show parcel name and owner, when appropriate
  1297. static LLCachedControl<bool> show_land_tip(gSavedSettings,
  1298. "ShowLandHoverTip");
  1299. static LLCachedControl<bool> show_poperty(gSavedSettings,
  1300. "ShowPropertyLines");
  1301. if (mHasDrawnParcels || show_land_tip || show_poperty)
  1302. {
  1303. gViewerParcelMgr.setHoverParcel(pos);
  1304. LLParcel* parcelp = gViewerParcelMgr.getHoverParcel();
  1305. if (parcelp)
  1306. {
  1307. fullname = parcelp->getName();
  1308. LLStringUtil::trim(fullname);
  1309. if (!fullname.empty())
  1310. {
  1311. msg += mParcelPrefix + fullname + "\n";
  1312. }
  1313. }
  1314. if (parcelp && parcelp->getOwnerID().notNull() && gCacheNamep &&
  1315. //MK
  1316. (!gRLenabled || !gRLInterface.mContainsShownames) &&
  1317. //mk
  1318. gCacheNamep->getFullName(parcelp->getOwnerID(), fullname))
  1319. {
  1320. if (!fullname.empty()) // Can be empty for group-owned parcels
  1321. {
  1322. msg += mOwnerPrefix + fullname + "\n";
  1323. }
  1324. }
  1325. }
  1326. }
  1327. msg += mMapToolTip;
  1328. return true;
  1329. }
  1330. //virtual
  1331. bool LLPanelMiniMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
  1332. {
  1333. // Note that clicks are reversed from what you would think, i.e. > 0 means
  1334. // zoom out and < 0 means zoom in.
  1335. F32 scale = mScale * powf(MAP_SCALE_ZOOM_FACTOR, -clicks);
  1336. setScale(llclamp(scale, MAP_SCALE_MIN, MAP_SCALE_MAX));
  1337. return true;
  1338. }
  1339. //virtual
  1340. bool LLPanelMiniMap::handleMouseDown(S32 x, S32 y, MASK mask)
  1341. {
  1342. if (!(mask & MASK_SHIFT))
  1343. {
  1344. return false;
  1345. }
  1346. // Start panning
  1347. gFocusMgr.setMouseCapture(this);
  1348. mMouseDownPanX = ll_round(mCurPanX);
  1349. mMouseDownPanY = ll_round(mCurPanY);
  1350. mMouseDownX = x;
  1351. mMouseDownY = y;
  1352. return true;
  1353. }
  1354. //virtual
  1355. bool LLPanelMiniMap::handleMouseUp(S32 x, S32 y, MASK mask)
  1356. {
  1357. if (!hasMouseCapture())
  1358. {
  1359. return false;
  1360. }
  1361. if (mPanning)
  1362. {
  1363. // Restore mouse cursor
  1364. S32 local_x = mMouseDownX + llfloor(mCurPanX - mMouseDownPanX);
  1365. S32 local_y = mMouseDownY + llfloor(mCurPanY - mMouseDownPanY);
  1366. LLRect clip_rect = getRect();
  1367. clip_rect.stretch(-8);
  1368. clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y);
  1369. LLUI::setCursorPositionLocal(this, local_x, local_y);
  1370. // Finish the pan
  1371. mPanning = false;
  1372. mMouseDownX = mMouseDownY =0;
  1373. // Auto-centre
  1374. mTargetPanX = mTargetPanY = 0;
  1375. }
  1376. gViewerWindowp->showCursor();
  1377. gFocusMgr.setMouseCapture(NULL);
  1378. return true;
  1379. }
  1380. //static
  1381. bool LLPanelMiniMap::outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y,
  1382. S32 slop)
  1383. {
  1384. S32 dx = x - start_x;
  1385. S32 dy = y - start_y;
  1386. return dx <= -slop || slop <= dx || dy <= -slop || slop <= dy;
  1387. }
  1388. //virtual
  1389. bool LLPanelMiniMap::handleHover(S32 x, S32 y, MASK mask)
  1390. {
  1391. if (hasMouseCapture())
  1392. {
  1393. if (mPanning ||
  1394. outsideSlop(x, y, mMouseDownX, mMouseDownY, MOUSE_DRAG_SLOP))
  1395. {
  1396. if (!mPanning)
  1397. {
  1398. // just started panning, so hide cursor
  1399. mPanning = true;
  1400. gViewerWindowp->hideCursor();
  1401. }
  1402. F32 delta_x = (F32)gViewerWindowp->getCurrentMouseDX();
  1403. F32 delta_y = (F32)gViewerWindowp->getCurrentMouseDY();
  1404. // Set pan to value at start of drag + offset
  1405. mCurPanX += delta_x;
  1406. mCurPanY += delta_y;
  1407. mTargetPanX = mCurPanX;
  1408. mTargetPanY = mCurPanY;
  1409. gViewerWindowp->moveCursorToCenter();
  1410. }
  1411. // It does not really matter: cursor should be hidden
  1412. gViewerWindowp->setCursor(UI_CURSOR_TOOLPAN);
  1413. }
  1414. else if (mask & MASK_SHIFT)
  1415. {
  1416. // If shift is held, change the cursor to hint that the map can be
  1417. // dragged
  1418. gViewerWindowp->setCursor(UI_CURSOR_TOOLPAN);
  1419. }
  1420. else
  1421. {
  1422. gViewerWindowp->setCursor(UI_CURSOR_CROSS);
  1423. }
  1424. return true;
  1425. }
  1426. //virtual
  1427. bool LLPanelMiniMap::handleDoubleClick(S32 x, S32 y, MASK mask)
  1428. {
  1429. LLVector3d pos_global = viewPosToGlobal(x, y, sMiniMapRotate);
  1430. bool new_target = false;
  1431. if (!gTracker.isTracking() && gFloaterWorldMapp)
  1432. {
  1433. gFloaterWorldMapp->trackLocation(pos_global);
  1434. new_target = true;
  1435. }
  1436. if (mask == MASK_CONTROL
  1437. //MK
  1438. && !(gRLenabled && gRLInterface.contains("tploc")))
  1439. //mk
  1440. {
  1441. gAgent.teleportViaLocationLookAt(pos_global);
  1442. }
  1443. else
  1444. {
  1445. LLFloaterWorldMap::show(NULL, new_target);
  1446. }
  1447. return true;
  1448. }
  1449. //virtual
  1450. bool LLPanelMiniMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
  1451. {
  1452. mClosestAgentAtLastRightClick = mClosestAgentToCursor;
  1453. mPosGlobaltAtLastRightClick = viewPosToGlobal(x, y, sMiniMapRotate);
  1454. LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
  1455. if (menu)
  1456. {
  1457. menu->buildDrawLabels();
  1458. menu->updateParent(gMenuHolderp);
  1459. LLMenuGL::showPopup(this, menu, x, y);
  1460. }
  1461. return true;
  1462. }
  1463. bool LLPanelMiniMap::LLScaleMap::handleEvent(LLPointer<LLEvent>,
  1464. const LLSD& userdata)
  1465. {
  1466. LLPanelMiniMap* self = mPtr;
  1467. S32 level = userdata.asInteger();
  1468. switch (level)
  1469. {
  1470. case 0:
  1471. self->setScale(MAP_SCALE_MIN);
  1472. break;
  1473. case 1:
  1474. self->setScale(MAP_SCALE_MID);
  1475. break;
  1476. case 2:
  1477. self->setScale(MAP_SCALE_MAX);
  1478. break;
  1479. default:
  1480. break;
  1481. }
  1482. return true;
  1483. }
  1484. bool LLPanelMiniMap::LLCenterMap::handleEvent(LLPointer<LLEvent>,
  1485. const LLSD& userdata)
  1486. {
  1487. EMiniMapCenter center = (EMiniMapCenter)userdata.asInteger();
  1488. if (gSavedSettings.getS32("MiniMapCenter") == center)
  1489. {
  1490. gSavedSettings.setS32("MiniMapCenter", MAP_CENTER_NONE);
  1491. }
  1492. else
  1493. {
  1494. gSavedSettings.setS32("MiniMapCenter", userdata.asInteger());
  1495. }
  1496. return true;
  1497. }
  1498. bool LLPanelMiniMap::LLCheckCenterMap::handleEvent(LLPointer<LLEvent>,
  1499. const LLSD& userdata)
  1500. {
  1501. LLPanelMiniMap* self = mPtr;
  1502. EMiniMapCenter center = (EMiniMapCenter)userdata["data"].asInteger();
  1503. bool enabled = gSavedSettings.getS32("MiniMapCenter") == center;
  1504. self->findControl(userdata["control"].asString())->setValue(enabled);
  1505. return true;
  1506. }
  1507. bool LLPanelMiniMap::LLRotateMap::handleEvent(LLPointer<LLEvent>, const LLSD&)
  1508. {
  1509. gSavedSettings.setBool("MiniMapRotate",
  1510. !gSavedSettings.getBool("MiniMapRotate"));
  1511. return true;
  1512. }
  1513. bool LLPanelMiniMap::LLCheckRotateMap::handleEvent(LLPointer<LLEvent>,
  1514. const LLSD& userdata)
  1515. {
  1516. LLPanelMiniMap* self = mPtr;
  1517. bool enabled = gSavedSettings.getBool("MiniMapRotate");
  1518. self->findControl(userdata["control"].asString())->setValue(enabled);
  1519. return true;
  1520. }
  1521. bool LLPanelMiniMap::LLDrawWater::handleEvent(LLPointer<LLEvent>, const LLSD&)
  1522. {
  1523. gSavedSettings.setBool("MiniMapDrawWater",
  1524. !gSavedSettings.getBool("MiniMapDrawWater"));
  1525. return true;
  1526. }
  1527. bool LLPanelMiniMap::LLCheckDrawWater::handleEvent(LLPointer<LLEvent>,
  1528. const LLSD& userdata)
  1529. {
  1530. LLPanelMiniMap* self = mPtr;
  1531. bool enabled = gSavedSettings.getBool("MiniMapDrawWater");
  1532. self->findControl(userdata["control"].asString())->setValue(enabled);
  1533. return true;
  1534. }
  1535. bool LLPanelMiniMap::LLDrawObjects::handleEvent(LLPointer<LLEvent>,
  1536. const LLSD&)
  1537. {
  1538. gSavedSettings.setBool("MiniMapDrawObjects",
  1539. !gSavedSettings.getBool("MiniMapDrawObjects"));
  1540. LLPanelMiniMap* self = mPtr;
  1541. self->mUpdateObjectImage = true;
  1542. return true;
  1543. }
  1544. bool LLPanelMiniMap::LLCheckDrawObjects::handleEvent(LLPointer<LLEvent>,
  1545. const LLSD& userdata)
  1546. {
  1547. LLPanelMiniMap* self = mPtr;
  1548. bool enabled = gSavedSettings.getBool("MiniMapDrawObjects");
  1549. self->findControl(userdata["control"].asString())->setValue(enabled);
  1550. return true;
  1551. }
  1552. bool LLPanelMiniMap::LLPlotPuppets::handleEvent(LLPointer<LLEvent>,
  1553. const LLSD&)
  1554. {
  1555. gSavedSettings.setBool("MiniMapPlotPuppets",
  1556. !gSavedSettings.getBool("MiniMapPlotPuppets"));
  1557. LLPanelMiniMap* self = mPtr;
  1558. self->mUpdateObjectImage = true;
  1559. return true;
  1560. }
  1561. bool LLPanelMiniMap::LLCheckPlotPuppets::handleEvent(LLPointer<LLEvent>,
  1562. const LLSD& userdata)
  1563. {
  1564. LLPanelMiniMap* self = mPtr;
  1565. bool enabled = gSavedSettings.getBool("MiniMapPlotPuppets");
  1566. self->findControl(userdata["control"].asString())->setValue(enabled);
  1567. return true;
  1568. }
  1569. bool LLPanelMiniMap::LLPlotChars::handleEvent(LLPointer<LLEvent>, const LLSD&)
  1570. {
  1571. gSavedSettings.setBool("MiniMapPlotCharacters",
  1572. !gSavedSettings.getBool("MiniMapPlotCharacters"));
  1573. LLPanelMiniMap* self = mPtr;
  1574. self->mUpdateObjectImage = true;
  1575. return true;
  1576. }
  1577. bool LLPanelMiniMap::LLCheckPlotChars::handleEvent(LLPointer<LLEvent>,
  1578. const LLSD& userdata)
  1579. {
  1580. LLPanelMiniMap* self = mPtr;
  1581. bool enabled = gSavedSettings.getBool("MiniMapPlotCharacters") &&
  1582. gSavedSettings.getBool("MiniMapDrawObjects");
  1583. self->findControl(userdata["control"].asString())->setValue(enabled);
  1584. return true;
  1585. }
  1586. bool LLPanelMiniMap::LLEnablePlotChars::handleEvent(LLPointer<LLEvent>,
  1587. const LLSD& userdata)
  1588. {
  1589. LLPanelMiniMap* self = mPtr;
  1590. bool enable = gSavedSettings.getBool("MiniMapDrawObjects");
  1591. self->findControl(userdata["control"].asString())->setValue(enable);
  1592. return true;
  1593. }
  1594. bool LLPanelMiniMap::LLPlotPhysical::handleEvent(LLPointer<LLEvent>,
  1595. const LLSD&)
  1596. {
  1597. gSavedSettings.setBool("MiniMapPlotPhysicalObj",
  1598. !gSavedSettings.getBool("MiniMapPlotPhysicalObj"));
  1599. LLPanelMiniMap* self = mPtr;
  1600. self->mUpdateObjectImage = true;
  1601. return true;
  1602. }
  1603. bool LLPanelMiniMap::LLCheckPlotPhysical::handleEvent(LLPointer<LLEvent>,
  1604. const LLSD& userdata)
  1605. {
  1606. LLPanelMiniMap* self = mPtr;
  1607. bool enabled = gSavedSettings.getBool("MiniMapPlotPhysicalObj") &&
  1608. gSavedSettings.getBool("MiniMapDrawObjects");
  1609. self->findControl(userdata["control"].asString())->setValue(enabled);
  1610. return true;
  1611. }
  1612. bool LLPanelMiniMap::LLEnablePlotPhysical::handleEvent(LLPointer<LLEvent>,
  1613. const LLSD& userdata)
  1614. {
  1615. LLPanelMiniMap* self = mPtr;
  1616. bool enable = gSavedSettings.getBool("MiniMapDrawObjects");
  1617. self->findControl(userdata["control"].asString())->setValue(enable);
  1618. return true;
  1619. }
  1620. bool LLPanelMiniMap::LLDrawBorders::handleEvent(LLPointer<LLEvent>,
  1621. const LLSD&)
  1622. {
  1623. gSavedSettings.setBool("MiniMapDrawBorders",
  1624. !gSavedSettings.getBool("MiniMapDrawBorders"));
  1625. return true;
  1626. }
  1627. bool LLPanelMiniMap::LLCheckDrawBorders::handleEvent(LLPointer<LLEvent>,
  1628. const LLSD& userdata)
  1629. {
  1630. LLPanelMiniMap* self = mPtr;
  1631. bool enabled = gSavedSettings.getBool("MiniMapDrawBorders");
  1632. self->findControl(userdata["control"].asString())->setValue(enabled);
  1633. return true;
  1634. }
  1635. bool LLPanelMiniMap::LLDrawBans::handleEvent(LLPointer<LLEvent>, const LLSD&)
  1636. {
  1637. gSavedSettings.setBool("MinimapShowBannedParcels",
  1638. !gSavedSettings.getBool("MinimapShowBannedParcels"));
  1639. return true;
  1640. }
  1641. bool LLPanelMiniMap::LLCheckDrawBans::handleEvent(LLPointer<LLEvent>,
  1642. const LLSD& userdata)
  1643. {
  1644. LLPanelMiniMap* self = mPtr;
  1645. bool enabled = gSavedSettings.getBool("MinimapShowBannedParcels");
  1646. self->findControl(userdata["control"].asString())->setValue(enabled);
  1647. return true;
  1648. }
  1649. bool LLPanelMiniMap::LLDrawParcels::handleEvent(LLPointer<LLEvent>, const LLSD&)
  1650. {
  1651. gSavedSettings.setBool("MinimapShowParcelBorders",
  1652. !gSavedSettings.getBool("MinimapShowParcelBorders"));
  1653. LLPanelMiniMap* self = mPtr;
  1654. self->mUpdateParcelImage = true;
  1655. return true;
  1656. }
  1657. bool LLPanelMiniMap::LLCheckDrawParcels::handleEvent(LLPointer<LLEvent>,
  1658. const LLSD& userdata)
  1659. {
  1660. LLPanelMiniMap* self = mPtr;
  1661. bool enabled = gSavedSettings.getBool("MinimapShowParcelBorders");
  1662. self->findControl(userdata["control"].asString())->setValue(enabled);
  1663. return true;
  1664. }
  1665. bool LLPanelMiniMap::LLShowParcelInfo::handleEvent(LLPointer<LLEvent>,
  1666. const LLSD&)
  1667. {
  1668. LLPanelMiniMap* self = mPtr;
  1669. if (!self->mPosGlobaltAtLastRightClick.isExactlyZero() &&
  1670. //MK
  1671. (!gRLenabled || !gRLInterface.mContainsShowloc))
  1672. //mk
  1673. {
  1674. gViewerParcelMgr.selectParcelAt(self->mPosGlobaltAtLastRightClick);
  1675. LLFloaterLand::showInstance();
  1676. }
  1677. return true;
  1678. }
  1679. bool LLPanelMiniMap::LLEnableParcelInfo::handleEvent(LLPointer<LLEvent>,
  1680. const LLSD& userdata)
  1681. {
  1682. LLPanelMiniMap* self = mPtr;
  1683. //MK
  1684. if (gRLenabled && gRLInterface.mContainsShowloc)
  1685. {
  1686. self->findControl(userdata["control"].asString())->setValue(false);
  1687. }
  1688. else
  1689. {
  1690. //mk
  1691. bool enabled = self->mHasDrawnParcels;
  1692. self->findControl(userdata["control"].asString())->setValue(enabled);
  1693. //MK
  1694. }
  1695. //mk
  1696. return true;
  1697. }
  1698. bool LLPanelMiniMap::LLRefreshTerrain::handleEvent(LLPointer<LLEvent>,
  1699. const LLSD&)
  1700. {
  1701. gWorld.reloadAllSurfacePatches();
  1702. return true;
  1703. }
  1704. bool LLPanelMiniMap::LLStopTracking::handleEvent(LLPointer<LLEvent>,
  1705. const LLSD&)
  1706. {
  1707. gTracker.stopTracking();
  1708. return true;
  1709. }
  1710. bool LLPanelMiniMap::LLEnableTracking::handleEvent(LLPointer<LLEvent>,
  1711. const LLSD& userdata)
  1712. {
  1713. LLPanelMiniMap* self = mPtr;
  1714. bool enabled = gTracker.isTracking();
  1715. self->findControl(userdata["control"].asString())->setValue(enabled);
  1716. return true;
  1717. }
  1718. bool LLPanelMiniMap::LLShowAgentProfile::handleEvent(LLPointer<LLEvent>,
  1719. const LLSD&)
  1720. {
  1721. LLPanelMiniMap* self = mPtr;
  1722. LLFloaterAvatarInfo::show(self->mClosestAgentAtLastRightClick);
  1723. return true;
  1724. }
  1725. bool LLPanelMiniMap::LLEnableProfile::handleEvent(LLPointer<LLEvent>,
  1726. const LLSD& userdata)
  1727. {
  1728. LLPanelMiniMap* self = mPtr;
  1729. //MK
  1730. if (gRLenabled &&
  1731. (gRLInterface.mContainsShownames ||
  1732. gRLInterface.mContainsShowNearby ||
  1733. gRLInterface.mContainsShownametags))
  1734. {
  1735. self->findControl(userdata["control"].asString())->setValue(false);
  1736. }
  1737. else
  1738. {
  1739. //mk
  1740. bool enabled = self->isAgentUnderCursor();
  1741. self->findControl(userdata["control"].asString())->setValue(enabled);
  1742. //MK
  1743. }
  1744. //mk
  1745. return true;
  1746. }
  1747. bool LLPanelMiniMap::LLDrawLegend::handleEvent(LLPointer<LLEvent>, const LLSD&)
  1748. {
  1749. gSavedSettings.setBool("MiniMapPlotsLegend",
  1750. !gSavedSettings.getBool("MiniMapPlotsLegend"));
  1751. return true;
  1752. }
  1753. bool LLPanelMiniMap::LLCheckDrawLegend::handleEvent(LLPointer<LLEvent>,
  1754. const LLSD& userdata)
  1755. {
  1756. LLPanelMiniMap* self = mPtr;
  1757. bool enabled = gSavedSettings.getBool("MiniMapPlotsLegend");
  1758. self->findControl(userdata["control"].asString())->setValue(enabled);
  1759. return true;
  1760. }