aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llnetmap.cpp
diff options
context:
space:
mode:
authorMcCabe Maxsted2009-06-09 09:41:04 -0700
committerMcCabe Maxsted2009-06-09 09:41:04 -0700
commite5dbb8e4dc05e664102362685ddca94f37cdf575 (patch)
tree93e695263553adadc423cf7e7d2e4b046adb8a7a /linden/indra/newview/llnetmap.cpp
parentFixed the Resident Chooser showing hair instead of calling cards (diff)
downloadmeta-impy-e5dbb8e4dc05e664102362685ddca94f37cdf575.zip
meta-impy-e5dbb8e4dc05e664102362685ddca94f37cdf575.tar.gz
meta-impy-e5dbb8e4dc05e664102362685ddca94f37cdf575.tar.bz2
meta-impy-e5dbb8e4dc05e664102362685ddca94f37cdf575.tar.xz
Backported 1.23's minimap conversion to XUI
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llnetmap.cpp399
1 files changed, 193 insertions, 206 deletions
diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp
index cedabf7..71eb35b 100644
--- a/linden/indra/newview/llnetmap.cpp
+++ b/linden/indra/newview/llnetmap.cpp
@@ -44,22 +44,20 @@
44#include "llcallingcard.h" 44#include "llcallingcard.h"
45#include "llcolorscheme.h" 45#include "llcolorscheme.h"
46#include "llviewercontrol.h" 46#include "llviewercontrol.h"
47#include "llfloateravatarinfo.h"
47#include "llfloaterworldmap.h" 48#include "llfloaterworldmap.h"
48#include "llfloatermap.h"
49#include "llframetimer.h" 49#include "llframetimer.h"
50#include "lltracker.h" 50#include "lltracker.h"
51#include "llmenugl.h" 51#include "llmenugl.h"
52#include "llstatgraph.h"
53#include "llsurface.h" 52#include "llsurface.h"
54#include "lltextbox.h" 53#include "lltextbox.h"
54#include "lluictrlfactory.h"
55#include "lluuid.h" 55#include "lluuid.h"
56#include "llviewercamera.h" 56#include "llviewercamera.h"
57#include "llviewerimage.h" 57#include "llviewerimage.h"
58#include "llviewerimagelist.h" 58#include "llviewerimagelist.h"
59#include "llviewermenu.h" 59#include "llviewermenu.h"
60#include "llviewerobjectlist.h" 60#include "llviewerobjectlist.h"
61#include "llviewermenu.h"
62#include "llviewerparceloverlay.h"
63#include "llviewerregion.h" 61#include "llviewerregion.h"
64#include "llviewerwindow.h" 62#include "llviewerwindow.h"
65#include "llvoavatar.h" 63#include "llvoavatar.h"
@@ -73,19 +71,14 @@ const F32 MAP_SCALE_MIN = 32;
73const F32 MAP_SCALE_MID = 172; 71const F32 MAP_SCALE_MID = 172;
74const F32 MAP_SCALE_MAX = 512; 72const F32 MAP_SCALE_MAX = 512;
75const F32 MAP_SCALE_INCREMENT = 16; 73const F32 MAP_SCALE_INCREMENT = 16;
74const F32 MAP_MIN_PICK_DIST = 4;
75const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f;
76 76
77const S32 TRACKING_RADIUS = 3; 77const S32 TRACKING_RADIUS = 3;
78 78
79//static 79LLNetMap::LLNetMap(const std::string& name) :
80BOOL LLNetMap::sRotateMap = FALSE; 80 LLPanel(name),
81LLNetMap* LLNetMap::sInstance = NULL; 81 mScale(128.f),
82
83LLNetMap::LLNetMap(
84 const std::string& name,
85 const LLRect& rect,
86 const LLColor4& bg_color )
87 :
88 LLUICtrl(name, rect, FALSE, NULL, NULL), mBackgroundColor( bg_color ),
89 mObjectMapTPM(1.f), 82 mObjectMapTPM(1.f),
90 mObjectMapPixels(255.f), 83 mObjectMapPixels(255.f),
91 mTargetPanX( 0.f ), 84 mTargetPanX( 0.f ),
@@ -94,109 +87,57 @@ LLNetMap::LLNetMap(
94 mCurPanY( 0.f ), 87 mCurPanY( 0.f ),
95 mUpdateNow( FALSE ) 88 mUpdateNow( FALSE )
96{ 89{
97 mPixelsPerMeter = gMiniMapScale / REGION_WIDTH_METERS; 90 mScale = gSavedSettings.getF32("MiniMapScale");
98 91 mPixelsPerMeter = mScale / LLWorld::getInstance()->getRegionWidthInMeters();
99 LLNetMap::sRotateMap = gSavedSettings.getBOOL( "MiniMapRotate" );
100
101 glyph_color_avatar = gColors.getColor("NetMapGlyphColorAvatar");
102 glyph_color_friend = gColors.getColor("NetMapGlyphColorFriend");
103
104 // Surface texture is dynamically generated/updated.
105// createObjectImage();
106 92
107 mObjectImageCenterGlobal = gAgent.getCameraPositionGlobal(); 93 mObjectImageCenterGlobal = gAgent.getCameraPositionGlobal();
108 94
109 // TODO: exteralize hardcoded constants. 95 // Register event listeners for popup menu
110 const S32 DIR_WIDTH = 10; 96 (new LLScaleMap())->registerListener(this, "MiniMap.ZoomLevel");
111 const S32 DIR_HEIGHT = 10; 97 (new LLStopTracking())->registerListener(this, "MiniMap.StopTracking");
112 LLRect major_dir_rect( 0, DIR_HEIGHT, DIR_WIDTH, 0 ); 98 (new LLEnableTracking())->registerListener(this, "MiniMap.EnableTracking");
113 const LLColor4 minor_color( 1.f, 1.f, 1.f, .7f ); 99 (new LLShowAgentProfile())->registerListener(this, "MiniMap.ShowProfile");
114 const LLRect minor_dir_rect( 0, DIR_HEIGHT, DIR_WIDTH * 2, 0 ); 100 (new LLEnableProfile())->registerListener(this, "MiniMap.EnableProfile");
115 101
116 // Note: removing special treatment for north compass point (DEV-10559). -MG 102 LLUICtrlFactory::getInstance()->buildPanel(this, "panel_mini_map.xml");
117 //mTextBoxNorth = new LLTextBox( "N", major_dir_rect ); 103
118 //mTextBoxNorth->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); 104 updateMinorDirections();
119 //addChild( mTextBoxNorth ); 105
120 mTextBoxNorth = new LLTextBox( std::string("N"), major_dir_rect ); 106 LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_mini_map.xml", this);
121 mTextBoxNorth->setColor( minor_color ); 107 if (!menu)
122 addChild( mTextBoxNorth ); 108 {
123 109 menu = new LLMenuGL(LLStringUtil::null);
124 mTextBoxEast = new LLTextBox( std::string("E"), major_dir_rect ); 110 }
125 mTextBoxEast->setColor( minor_color );
126 addChild( mTextBoxEast );
127
128 major_dir_rect.mRight += 1 ;
129 mTextBoxWest = new LLTextBox( std::string("W"), major_dir_rect );
130 mTextBoxWest->setColor( minor_color );
131 addChild( mTextBoxWest );
132 major_dir_rect.mRight -= 1 ;
133
134 mTextBoxSouth = new LLTextBox( std::string("S"), major_dir_rect );
135 mTextBoxSouth->setColor( minor_color );
136 addChild( mTextBoxSouth );
137
138 mTextBoxSouthEast = new LLTextBox( std::string("SE"), minor_dir_rect );
139 mTextBoxSouthEast->setColor( minor_color );
140 addChild( mTextBoxSouthEast );
141
142 mTextBoxNorthEast = new LLTextBox( std::string("NE"), minor_dir_rect );
143 mTextBoxNorthEast->setColor( minor_color );
144 addChild( mTextBoxNorthEast );
145
146 mTextBoxSouthWest = new LLTextBox( std::string("SW"), minor_dir_rect );
147 mTextBoxSouthWest->setColor( minor_color );
148 addChild( mTextBoxSouthWest );
149
150 mTextBoxNorthWest = new LLTextBox( std::string("NW"), minor_dir_rect );
151 mTextBoxNorthWest->setColor( minor_color );
152 addChild( mTextBoxNorthWest );
153
154 // Right-click menu
155 LLMenuGL* menu;
156 menu = new LLMenuGL(std::string("popup"));
157 menu->setCanTearOff(FALSE);
158 menu->append(new LLMenuItemCallGL(std::string("Zoom Close"), handleZoomLevel,
159 NULL, (void*)2) );
160 menu->append(new LLMenuItemCallGL(std::string("Zoom Medium"), handleZoomLevel,
161 NULL, (void*)1) );
162 menu->append(new LLMenuItemCallGL(std::string("Zoom Far"), handleZoomLevel,
163 NULL, (void*)0) );
164 menu->appendSeparator();
165 menu->append(new LLMenuItemCallGL(std::string("Stop Tracking"), &LLTracker::stopTracking,
166 &LLTracker::isTracking, NULL) );
167 menu->setVisible(FALSE); 111 menu->setVisible(FALSE);
168 addChild(menu);
169 mPopupMenuHandle = menu->getHandle(); 112 mPopupMenuHandle = menu->getHandle();
170
171 sInstance = this;
172} 113}
173 114
174LLNetMap::~LLNetMap() 115LLNetMap::~LLNetMap()
175{ 116{
176 sInstance = NULL;
177} 117}
178 118
179void LLNetMap::setScale( F32 scale ) 119void LLNetMap::setScale( F32 scale )
180{ 120{
181 gMiniMapScale = scale; 121 mScale = scale;
182 if (gMiniMapScale == 0.f) 122 if (mScale == 0.f)
183 { 123 {
184 gMiniMapScale = 0.1f; 124 mScale = 0.1f;
185 } 125 }
126 gSavedSettings.setF32("MiniMapScale", mScale);
186 127
187 if (mObjectImagep.notNull()) 128 if (mObjectImagep.notNull())
188 { 129 {
189 F32 half_width = (F32)(getRect().getWidth() / 2); 130 F32 width = (F32)(getRect().getWidth());
190 F32 half_height = (F32)(getRect().getHeight() / 2); 131 F32 height = (F32)(getRect().getHeight());
191 F32 radius = sqrt( half_width * half_width + half_height * half_height ); 132 F32 diameter = sqrt(width * width + height * height);
192 F32 region_widths = (2.f*radius)/gMiniMapScale; 133 F32 region_widths = diameter / mScale;
193 F32 meters = region_widths * LLWorld::getInstance()->getRegionWidthInMeters(); 134 F32 meters = region_widths * LLWorld::getInstance()->getRegionWidthInMeters();
194 F32 num_pixels = (F32)mObjectImagep->getWidth(); 135 F32 num_pixels = (F32)mObjectImagep->getWidth();
195 mObjectMapTPM = num_pixels/meters; 136 mObjectMapTPM = num_pixels / meters;
196 mObjectMapPixels = 2.f*radius; 137 mObjectMapPixels = diameter;
197 } 138 }
198 139
199 mPixelsPerMeter = gMiniMapScale / REGION_WIDTH_METERS; 140 mPixelsPerMeter = mScale / LLWorld::getInstance()->getRegionWidthInMeters();
200 141
201 mUpdateNow = TRUE; 142 mUpdateNow = TRUE;
202} 143}
@@ -218,16 +159,16 @@ void LLNetMap::draw()
218 { 159 {
219 createObjectImage(); 160 createObjectImage();
220 } 161 }
221 162
222 mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); 163 mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f));
223 mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); 164 mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f));
224 165
225 // Prepare a scissor region
226 F32 rotation = 0; 166 F32 rotation = 0;
227 167
168 // Prepare a scissor region
228 { 169 {
229 LLGLEnable scissor(GL_SCISSOR_TEST); 170 LLGLEnable scissor(GL_SCISSOR_TEST);
230 171
231 { 172 {
232 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 173 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
233 LLLocalClipRect clip(getLocalRect()); 174 LLLocalClipRect clip(getLocalRect());
@@ -235,8 +176,11 @@ void LLNetMap::draw()
235 glMatrixMode(GL_MODELVIEW); 176 glMatrixMode(GL_MODELVIEW);
236 177
237 // Draw background rectangle 178 // Draw background rectangle
238 gGL.color4fv( mBackgroundColor.mV ); 179 if(isBackgroundVisible())
239 gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); 180 {
181 gGL.color4fv(isBackgroundOpaque() ? getBackgroundColor().mV : getTransparentColor().mV);
182 gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0);
183 }
240 } 184 }
241 185
242 // region 0,0 is in the middle 186 // region 0,0 is in the middle
@@ -247,7 +191,8 @@ void LLNetMap::draw()
247 191
248 gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); 192 gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f);
249 193
250 if( LLNetMap::sRotateMap ) 194 BOOL rotate_map = gSavedSettings.getBOOL( "MiniMapRotate" );
195 if( rotate_map )
251 { 196 {
252 // rotate subsequent draws to agent rotation 197 // rotate subsequent draws to agent rotation
253 rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); 198 rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
@@ -256,35 +201,30 @@ void LLNetMap::draw()
256 201
257 // figure out where agent is 202 // figure out where agent is
258 S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters()); 203 S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters());
204 LLColor4 this_region_color = gColors.getColor( "NetMapThisRegion" );
205 LLColor4 live_region_color = gColors.getColor( "NetMapLiveRegion" );
206 LLColor4 dead_region_color = gColors.getColor( "NetMapDeadRegion" );
259 207
260 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 208 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
261 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 209 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
262 { 210 {
263 LLViewerRegion* regionp = *iter; 211 LLViewerRegion* regionp = *iter;
264 // Find x and y position relative to camera's center. 212 // Find x and y position relative to camera's center.
265 LLVector3 origin_agent = regionp->getOriginAgent(); 213 LLVector3 origin_agent = regionp->getOriginAgent();
266 LLVector3 rel_region_pos = origin_agent - gAgent.getCameraPositionAgent(); 214 LLVector3 rel_region_pos = origin_agent - gAgent.getCameraPositionAgent();
267 F32 relative_x = (rel_region_pos.mV[0] / region_width) * gMiniMapScale; 215 F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
268 F32 relative_y = (rel_region_pos.mV[1] / region_width) * gMiniMapScale; 216 F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
269 217
270 // background region rectangle 218 // background region rectangle
271 F32 bottom = relative_y; 219 F32 bottom = relative_y;
272 F32 left = relative_x; 220 F32 left = relative_x;
273 F32 top = bottom + gMiniMapScale ; 221 F32 top = bottom + mScale ;
274 F32 right = left + gMiniMapScale ; 222 F32 right = left + mScale ;
275
276 if (regionp == gAgent.getRegion())
277 {
278 gGL.color4f(1.f, 1.f, 1.f, 1.f);
279 }
280 else
281 {
282 gGL.color4f(0.8f, 0.8f, 0.8f, 1.f);
283 }
284 223
224 gGL.color4fv(regionp == gAgent.getRegion() ? this_region_color.mV : live_region_color.mV);
285 if (!regionp->isAlive()) 225 if (!regionp->isAlive())
286 { 226 {
287 gGL.color4f(1.f, 0.5f, 0.5f, 1.f); 227 gGL.color4fv(dead_region_color.mV);
288 } 228 }
289 229
290 230
@@ -350,8 +290,8 @@ void LLNetMap::draw()
350 290
351 LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); 291 LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
352 map_center_agent -= gAgent.getCameraPositionAgent(); 292 map_center_agent -= gAgent.getCameraPositionAgent();
353 map_center_agent.mV[VX] *= gMiniMapScale/region_width; 293 map_center_agent.mV[VX] *= mScale/region_width;
354 map_center_agent.mV[VY] *= gMiniMapScale/region_width; 294 map_center_agent.mV[VY] *= mScale/region_width;
355 295
356 gGL.getTexUnit(0)->bind(mObjectImagep); 296 gGL.getTexUnit(0)->bind(mObjectImagep);
357 F32 image_half_width = 0.5f*mObjectMapPixels; 297 F32 image_half_width = 0.5f*mObjectMapPixels;
@@ -373,81 +313,67 @@ void LLNetMap::draw()
373 LLVector3d pos_global; 313 LLVector3d pos_global;
374 LLVector3 pos_map; 314 LLVector3 pos_map;
375 315
316 // Mouse pointer in local coordinates
317 S32 local_mouse_x;
318 S32 local_mouse_y;
319 LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
320 mClosestAgentToCursor.setNull();
321 F32 closest_dist = F32_MAX;
322
376 // Draw avatars 323 // Draw avatars
377 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 324 LLColor4 avatar_color = gColors.getColor( "MapAvatar" );
378 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 325 LLColor4 friend_color = gColors.getColor( "MapFriend" );
326 std::vector<LLUUID> avatar_ids;
327 std::vector<LLVector3d> positions;
328 LLWorld::getInstance()->getAvatars(&avatar_ids, &positions);
329 for(U32 i=0; i<avatar_ids.size(); i++)
379 { 330 {
380 LLViewerRegion* regionp = *iter;
381 const LLVector3d& origin_global = regionp->getOriginGlobal();
382
383 S32 count = regionp->mMapAvatars.count();
384 S32 i;
385 LLVector3 pos_local;
386 U32 compact_local;
387 U8 bits;
388 // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. 331 // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest.
389 // just be careful to sort the avatar IDs along with the positions. -MG 332 // just be careful to sort the avatar IDs along with the positions. -MG
390 for (i = 0; i < count; i++) 333 pos_map = globalPosToView(positions[i], rotate_map);
391 {
392 compact_local = regionp->mMapAvatars.get(i);
393
394 bits = compact_local & 0xFF;
395 pos_local.mV[VZ] = F32(bits) * 4.f;
396 compact_local >>= 8;
397
398 bits = compact_local & 0xFF;
399 pos_local.mV[VY] = (F32)bits;
400 compact_local >>= 8;
401 334
402 bits = compact_local & 0xFF; 335 LLWorldMapView::drawAvatar(
403 pos_local.mV[VX] = (F32)bits; 336 pos_map.mV[VX], pos_map.mV[VY],
337 is_agent_friend(avatar_ids[i]) ? friend_color : avatar_color,
338 pos_map.mV[VZ]);
404 339
405 pos_global.setVec( pos_local ); 340 F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y));
406 pos_global += origin_global; 341 if(dist_to_cursor < MAP_MIN_PICK_DIST && dist_to_cursor < closest_dist)
407 342 {
408 pos_map = globalPosToView(pos_global); 343 closest_dist = dist_to_cursor;
409 344 mClosestAgentToCursor = avatar_ids[i];
410 BOOL show_as_friend = FALSE;
411 if( i < regionp->mMapAvatarIDs.count())
412 {
413 show_as_friend = is_agent_friend(regionp->mMapAvatarIDs.get(i));
414 }
415 LLWorldMapView::drawAvatar(
416 pos_map.mV[VX], pos_map.mV[VY],
417 show_as_friend ? glyph_color_friend : glyph_color_avatar,
418 pos_map.mV[VZ]);
419 } 345 }
420 } 346 }
421 347
422 // Draw dot for autopilot target 348 // Draw dot for autopilot target
423 if (gAgent.getAutoPilot()) 349 if (gAgent.getAutoPilot())
424 { 350 {
425 drawTracking( gAgent.getAutoPilotTargetGlobal(), gTrackColor ); 351 drawTracking( gAgent.getAutoPilotTargetGlobal(), rotate_map, gTrackColor );
426 } 352 }
427 else 353 else
428 { 354 {
429 LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); 355 LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
430 if ( LLTracker::TRACKING_AVATAR == tracking_status ) 356 if ( LLTracker::TRACKING_AVATAR == tracking_status )
431 { 357 {
432 drawTracking( LLAvatarTracker::instance().getGlobalPos(), gTrackColor ); 358 drawTracking( LLAvatarTracker::instance().getGlobalPos(), rotate_map, gTrackColor );
433 } 359 }
434 else if ( LLTracker::TRACKING_LANDMARK == tracking_status 360 else if ( LLTracker::TRACKING_LANDMARK == tracking_status
435 || LLTracker::TRACKING_LOCATION == tracking_status ) 361 || LLTracker::TRACKING_LOCATION == tracking_status )
436 { 362 {
437 drawTracking( LLTracker::getTrackedPositionGlobal(), gTrackColor ); 363 drawTracking( LLTracker::getTrackedPositionGlobal(), rotate_map, gTrackColor );
438 } 364 }
439 } 365 }
440 366
441 // Draw dot for self avatar position 367 // Draw dot for self avatar position
442 pos_global = gAgent.getPositionGlobal(); 368 pos_global = gAgent.getPositionGlobal();
443 pos_map = globalPosToView(pos_global); 369 pos_map = globalPosToView(pos_global, rotate_map);
444 LLUIImagePtr you = LLWorldMapView::sAvatarYouSmallImage; 370 LLUIImagePtr you = LLWorldMapView::sAvatarYouSmallImage;
445 you->draw( 371 you->draw(
446 llround(pos_map.mV[VX]) - you->getWidth()/2, 372 llround(pos_map.mV[VX]) - you->getWidth()/2,
447 llround(pos_map.mV[VY]) - you->getHeight()/2); 373 llround(pos_map.mV[VY]) - you->getHeight()/2);
448 374
449 // Draw frustum 375 // Draw frustum
450 F32 meters_to_pixels = gMiniMapScale/ LLWorld::getInstance()->getRegionWidthInMeters(); 376 F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters();
451 377
452 F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); 378 F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
453 F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); 379 F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
@@ -462,9 +388,9 @@ void LLNetMap::draw()
462 388
463 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 389 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
464 390
465 if( LLNetMap::sRotateMap ) 391 if( rotate_map )
466 { 392 {
467 gGL.color4fv(gFrustumMapColor.mV); 393 gGL.color4fv(gColors.getColor("NetMapFrustum").mV);
468 394
469 gGL.begin( LLRender::TRIANGLES ); 395 gGL.begin( LLRender::TRIANGLES );
470 gGL.vertex2f( ctr_x, ctr_y ); 396 gGL.vertex2f( ctr_x, ctr_y );
@@ -474,7 +400,7 @@ void LLNetMap::draw()
474 } 400 }
475 else 401 else
476 { 402 {
477 gGL.color4fv(gRotatingFrustumMapColor.mV); 403 gGL.color4fv(gColors.getColor("NetMapFrustumRotating").mV);
478 404
479 // If we don't rotate the map, we have to rotate the frustum. 405 // If we don't rotate the map, we have to rotate the frustum.
480 gGL.pushMatrix(); 406 gGL.pushMatrix();
@@ -490,21 +416,26 @@ void LLNetMap::draw()
490 } 416 }
491 417
492 // Rotation of 0 means that North is up 418 // Rotation of 0 means that North is up
493 setDirectionPos( mTextBoxEast, rotation ); 419 setDirectionPos( getChild<LLTextBox>("e_label"), rotation);
494 setDirectionPos( mTextBoxNorth, rotation + F_PI_BY_TWO ); 420 setDirectionPos( getChild<LLTextBox>("n_label"), rotation + F_PI_BY_TWO);
495 setDirectionPos( mTextBoxWest, rotation + F_PI ); 421 setDirectionPos( getChild<LLTextBox>("w_label"), rotation + F_PI);
496 setDirectionPos( mTextBoxSouth, rotation + F_PI + F_PI_BY_TWO ); 422 setDirectionPos( getChild<LLTextBox>("s_label"), rotation + F_PI + F_PI_BY_TWO);
497 423
498 setDirectionPos( mTextBoxNorthEast, rotation + F_PI_BY_TWO / 2); 424 setDirectionPos( getChild<LLTextBox>("ne_label"), rotation + F_PI_BY_TWO / 2);
499 setDirectionPos( mTextBoxNorthWest, rotation + F_PI_BY_TWO + F_PI_BY_TWO / 2); 425 setDirectionPos( getChild<LLTextBox>("nw_label"), rotation + F_PI_BY_TWO + F_PI_BY_TWO / 2);
500 setDirectionPos( mTextBoxSouthWest, rotation + F_PI + F_PI_BY_TWO / 2); 426 setDirectionPos( getChild<LLTextBox>("sw_label"), rotation + F_PI + F_PI_BY_TWO / 2);
501 setDirectionPos( mTextBoxSouthEast, rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); 427 setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2);
502 428
503 LLUICtrl::draw(); 429 LLView::draw();
504} 430}
505 431
506LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos ) 432void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent)
507{ 433{
434 LLPanel::reshape(width, height, called_from_parent);
435 updateMinorDirections();
436}
437
438LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos, BOOL rotated ){
508 LLVector3d relative_pos_global = global_pos - gAgent.getCameraPositionGlobal(); 439 LLVector3d relative_pos_global = global_pos - gAgent.getCameraPositionGlobal();
509 LLVector3 pos_local; 440 LLVector3 pos_local;
510 pos_local.setVec(relative_pos_global); // convert to floats from doubles 441 pos_local.setVec(relative_pos_global); // convert to floats from doubles
@@ -513,7 +444,7 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
513 pos_local.mV[VY] *= mPixelsPerMeter; 444 pos_local.mV[VY] *= mPixelsPerMeter;
514 // leave Z component in meters 445 // leave Z component in meters
515 446
516 if( LLNetMap::sRotateMap ) 447 if( rotated )
517 { 448 {
518 F32 radians = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); 449 F32 radians = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
519 LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f)); 450 LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f));
@@ -526,10 +457,10 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
526 return pos_local; 457 return pos_local;
527} 458}
528 459
529void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, 460void LLNetMap::drawTracking(const LLVector3d& pos_global, BOOL rotated,
530 BOOL draw_arrow ) 461 const LLColor4& color, BOOL draw_arrow )
531{ 462{
532 LLVector3 pos_local = globalPosToView( pos_global ); 463 LLVector3 pos_local = globalPosToView( pos_global, rotated );
533 if( (pos_local.mV[VX] < 0) || 464 if( (pos_local.mV[VX] < 0) ||
534 (pos_local.mV[VY] < 0) || 465 (pos_local.mV[VY] < 0) ||
535 (pos_local.mV[VX] >= getRect().getWidth()) || 466 (pos_local.mV[VX] >= getRect().getWidth()) ||
@@ -552,22 +483,22 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
552 } 483 }
553} 484}
554 485
555LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) 486LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y, BOOL rotated )
556{ 487{
557 x -= llround(getRect().getWidth() / 2 + mCurPanX); 488 x -= llround(getRect().getWidth() / 2 + mCurPanX);
558 y -= llround(getRect().getHeight() / 2 + mCurPanY); 489 y -= llround(getRect().getHeight() / 2 + mCurPanY);
559 490
560 LLVector3 pos_local( (F32)x, (F32)y, 0 ); 491 LLVector3 pos_local( (F32)x, (F32)y, 0.f );
561 492
562 F32 radians = - atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); 493 F32 radians = - atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
563 494
564 if( LLNetMap::sRotateMap ) 495 if( rotated )
565 { 496 {
566 LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f)); 497 LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f));
567 pos_local.rotVec( rot ); 498 pos_local.rotVec( rot );
568 } 499 }
569 500
570 pos_local *= ( LLWorld::getInstance()->getRegionWidthInMeters() / gMiniMapScale ); 501 pos_local *= ( LLWorld::getInstance()->getRegionWidthInMeters() / mScale );
571 502
572 LLVector3d pos_global; 503 LLVector3d pos_global;
573 pos_global.setVec( pos_local ); 504 pos_global.setVec( pos_local );
@@ -579,7 +510,7 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
579BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) 510BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
580{ 511{
581 // note that clicks are reversed from what you'd think 512 // note that clicks are reversed from what you'd think
582 setScale(llclamp(gMiniMapScale - clicks*MAP_SCALE_INCREMENT, MAP_SCALE_MIN, MAP_SCALE_MAX)); 513 setScale(llclamp(mScale - clicks*MAP_SCALE_INCREMENT, MAP_SCALE_MIN, MAP_SCALE_MAX));
583 return TRUE; 514 return TRUE;
584} 515}
585 516
@@ -590,10 +521,17 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec
590 { 521 {
591 return FALSE; 522 return FALSE;
592 } 523 }
593 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); 524 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y , gSavedSettings.getBOOL( "MiniMapRotate" )) );
594 if( region ) 525 if( region )
595 { 526 {
596 msg.assign( region->getName() ); 527 msg.assign("");
528 std::string fullname;
529 if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname))
530 {
531 msg.append(fullname);
532 msg.append("\n");
533 }
534 msg.append( region->getName() );
597 535
598#ifndef LL_RELEASE_FOR_DOWNLOAD 536#ifndef LL_RELEASE_FOR_DOWNLOAD
599 std::string buffer; 537 std::string buffer;
@@ -618,8 +556,12 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec
618 &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); 556 &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
619 sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; 557 sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
620 sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; 558 sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
559 handled = TRUE;
560 }
561 if(!handled)
562 {
563 return LLPanel::handleToolTip(x, y, msg, sticky_rect_screen);
621 } 564 }
622 handled = TRUE;
623 return handled; 565 return handled;
624} 566}
625 567
@@ -629,19 +571,32 @@ void LLNetMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
629 // Rotation is in radians. 571 // Rotation is in radians.
630 // Rotation of 0 means x = 1, y = 0 on the unit circle. 572 // Rotation of 0 means x = 1, y = 0 on the unit circle.
631 573
632 574 F32 half_height = (F32)( (getRect().getHeight() - text_box->getRect().getHeight()) / 2);
633 F32 map_half_height = (F32)(getRect().getHeight() / 2); 575 F32 half_width = (F32)( (getRect().getWidth() - text_box->getRect().getWidth()) / 2);
634 F32 map_half_width = (F32)(getRect().getWidth() / 2); 576 F32 radius = llmin( half_height, half_width );
635 F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2);
636 F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2);
637 F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width );
638 577
639 // Inset by a little to account for position display. 578 // Inset by a little to account for position display.
640 radius -= 8.f; 579 radius -= 8.f;
641 580
642 text_box->setOrigin( 581 text_box->setOrigin(llround(half_width + radius * cos( rotation )),
643 llround(map_half_width - text_half_width + radius * cos( rotation )), 582 llround(half_height + radius * sin( rotation )));
644 llround(map_half_height - text_half_height + radius * sin( rotation )) ); 583}
584
585void LLNetMap::updateMinorDirections()
586{
587 if (getChild<LLTextBox>("ne_label") == NULL)
588 {
589 return;
590 }
591
592 // Hide minor directions if they cover too much of the map
593 bool show_minors = getChild<LLTextBox>("ne_label")->getRect().getHeight() < MAP_MINOR_DIR_THRESHOLD *
594 llmin(getRect().getWidth(), getRect().getHeight());
595
596 getChild<LLTextBox>("ne_label")->setVisible(show_minors);
597 getChild<LLTextBox>("nw_label")->setVisible(show_minors);
598 getChild<LLTextBox>("sw_label")->setVisible(show_minors);
599 getChild<LLTextBox>("se_label")->setVisible(show_minors);
645} 600}
646 601
647void LLNetMap::renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius_meters ) 602void LLNetMap::renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius_meters )
@@ -746,10 +701,10 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color,
746void LLNetMap::createObjectImage() 701void LLNetMap::createObjectImage()
747{ 702{
748 // Find the size of the side of a square that surrounds the circle that surrounds getRect(). 703 // Find the size of the side of a square that surrounds the circle that surrounds getRect().
749 F32 half_width = (F32)(getRect().getWidth() / 2); 704 // ... which is, the diagonal of the rect.
750 F32 half_height = (F32)(getRect().getHeight() / 2); 705 F32 width = getRect().getWidth();
751 F32 radius = sqrt( half_width * half_width + half_height * half_height ); 706 F32 height = getRect().getHeight();
752 S32 square_size = S32( 2 * radius ); 707 S32 square_size = llround( sqrt(width*width + height*height) );
753 708
754 // Find the least power of two >= the minimum size. 709 // Find the least power of two >= the minimum size.
755 const S32 MIN_SIZE = 32; 710 const S32 MIN_SIZE = 32;
@@ -768,7 +723,7 @@ void LLNetMap::createObjectImage()
768 U8* data = mObjectRawImagep->getData(); 723 U8* data = mObjectRawImagep->getData();
769 memset( data, 0, img_size * img_size * 4 ); 724 memset( data, 0, img_size * img_size * 4 );
770 mObjectImagep = new LLImageGL( mObjectRawImagep, FALSE); 725 mObjectImagep = new LLImageGL( mObjectRawImagep, FALSE);
771 setScale(gMiniMapScale); 726 setScale(mScale);
772 } 727 }
773 mUpdateNow = TRUE; 728 mUpdateNow = TRUE;
774} 729}
@@ -778,7 +733,7 @@ BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask )
778 if (gSavedSettings.getBOOL( "MiniMapTeleport" )) 733 if (gSavedSettings.getBOOL( "MiniMapTeleport" ))
779 { 734 {
780 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); 735 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
781 gAgent.teleportViaLocation( viewPosToGlobal(x,y) ); 736 gAgent.teleportViaLocation( viewPosToGlobal(x,y,gSavedSettings.getBOOL("MiniMapRotate")) );
782 } 737 }
783 else 738 else
784 LLFloaterWorldMap::show(NULL, FALSE); 739 LLFloaterWorldMap::show(NULL, FALSE);
@@ -788,6 +743,7 @@ BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask )
788 743
789BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) 744BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
790{ 745{
746 mClosestAgentAtLastRightClick = mClosestAgentToCursor;
791 LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); 747 LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
792 if (menu) 748 if (menu)
793 { 749 {
@@ -800,22 +756,53 @@ BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
800 756
801 757
802// static 758// static
803void LLNetMap::handleZoomLevel(void* which) 759bool LLNetMap::LLScaleMap::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
804{ 760{
805 intptr_t level = (intptr_t)which; 761 LLNetMap *self = mPtr;
762
763 S32 level = userdata.asInteger();
806 764
807 switch(level) 765 switch(level)
808 { 766 {
809 case 0: 767 case 0:
810 LLNetMap::sInstance->setScale(MAP_SCALE_MIN); 768 self->setScale(MAP_SCALE_MIN);
811 break; 769 break;
812 case 1: 770 case 1:
813 LLNetMap::sInstance->setScale(MAP_SCALE_MID); 771 self->setScale(MAP_SCALE_MID);
814 break; 772 break;
815 case 2: 773 case 2:
816 LLNetMap::sInstance->setScale(MAP_SCALE_MAX); 774 self->setScale(MAP_SCALE_MAX);
817 break; 775 break;
818 default: 776 default:
819 break; 777 break;
820 } 778 }
779
780 return true;
781}
782
783bool LLNetMap::LLStopTracking::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
784{
785 LLTracker::stopTracking(NULL);
786 return true;
787}
788
789bool LLNetMap::LLEnableTracking::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
790{
791 LLNetMap *self = mPtr;
792 self->findControl(userdata["control"].asString())->setValue(LLTracker::isTracking(NULL));
793 return true;
794}
795
796bool LLNetMap::LLShowAgentProfile::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
797{
798 LLNetMap *self = mPtr;
799 LLFloaterAvatarInfo::show(self->mClosestAgentAtLastRightClick);
800 return true;
801}
802
803bool LLNetMap::LLEnableProfile::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
804{
805 LLNetMap *self = mPtr;
806 self->findControl(userdata["control"].asString())->setValue(self->isAgentUnderCursor());
807 return true;
821} 808}