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