summaryrefslogtreecommitdiff
path: root/indra/newview/llnetmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llnetmap.cpp')
-rw-r--r--indra/newview/llnetmap.cpp236
1 files changed, 177 insertions, 59 deletions
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index f084002385..1bda7640bd 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -47,6 +47,7 @@
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
#include "llcallingcard.h" // LLAvatarTracker
+#include "llfloaterworldmap.h"
#include "lltracker.h"
#include "llsurface.h"
#include "llviewercamera.h"
@@ -73,6 +74,8 @@ const F32 DOT_SCALE = 0.75f;
const F32 MIN_PICK_SCALE = 2.f;
const S32 MOUSE_DRAG_SLOP = 2; // How far the mouse needs to move before we think it's a drag
+const F64 COARSEUPDATE_MAX_Z = 1020.0f;
+
LLNetMap::LLNetMap (const Params & p)
: LLUICtrl (p),
mBackgroundColor (p.bg_color()),
@@ -91,13 +94,27 @@ LLNetMap::LLNetMap (const Params & p)
mObjectImagep(),
mClosestAgentToCursor(),
mClosestAgentAtLastRightClick(),
- mToolTipMsg()
+ mToolTipMsg(),
+ mPopupMenu(NULL)
{
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
+ setScale(gSavedSettings.getF32("MiniMapScale"));
}
LLNetMap::~LLNetMap()
{
+ gSavedSettings.setF32("MiniMapScale", mScale);
+}
+
+BOOL LLNetMap::postBuild()
+{
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2));
+ registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ return TRUE;
}
void LLNetMap::setScale( F32 scale )
@@ -157,10 +174,10 @@ void LLNetMap::draw()
LLVector3 offset = gGL.getUITranslation();
LLVector3 scale = gGL.getUIScale();
- glLoadIdentity();
+ gGL.loadIdentity();
gGL.loadUIIdentity();
- glScalef(scale.mV[0], scale.mV[1], scale.mV[2]);
+ gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]);
gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
{
@@ -168,7 +185,7 @@ void LLNetMap::draw()
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- glMatrixMode(GL_MODELVIEW);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
// Draw background rectangle
LLColor4 background_color = mBackgroundColor.get();
@@ -189,7 +206,7 @@ void LLNetMap::draw()
{
// rotate subsequent draws to agent rotation
rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
- glRotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f);
+ gGL.rotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f);
}
// figure out where agent is
@@ -285,7 +302,8 @@ void LLNetMap::draw()
}
LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
- map_center_agent -= gAgentCamera.getCameraPositionAgent();
+ LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
+ map_center_agent -= camera_position;
map_center_agent.mV[VX] *= mScale/region_width;
map_center_agent.mV[VY] *= mScale/region_width;
@@ -306,70 +324,77 @@ void LLNetMap::draw()
gGL.popMatrix();
- LLVector3d pos_global;
- LLVector3 pos_map;
-
// Mouse pointer in local coordinates
S32 local_mouse_x;
S32 local_mouse_y;
//localMouse(&local_mouse_x, &local_mouse_y);
LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
mClosestAgentToCursor.setNull();
- F32 closest_dist = F32_MAX;
- F32 min_pick_dist = mDotRadius * MIN_PICK_SCALE;
+ F32 closest_dist_squared = F32_MAX; // value will be overridden in the loop
+ F32 min_pick_dist_squared = (mDotRadius * MIN_PICK_SCALE) * (mDotRadius * MIN_PICK_SCALE);
+
+ LLVector3 pos_map;
+ uuid_vec_t avatar_ids;
+ std::vector<LLVector3d> positions;
+ bool unknown_relative_z;
+
+ LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgentCamera.getCameraPositionGlobal());
// Draw avatars
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ for (U32 i = 0; i < avatar_ids.size(); i++)
{
- LLViewerRegion* regionp = *iter;
- const LLVector3d& origin_global = regionp->getOriginGlobal();
-
- S32 count = regionp->mMapAvatars.count();
- S32 i;
- LLVector3 pos_local;
- U32 compact_local;
- U8 bits;
- // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest.
- // just be careful to sort the avatar IDs along with the positions. -MG
- for (i = 0; i < count; i++)
- {
- compact_local = regionp->mMapAvatars.get(i);
-
- bits = compact_local & 0xFF;
- pos_local.mV[VZ] = F32(bits) * 4.f;
- compact_local >>= 8;
+ pos_map = globalPosToView(positions[i]);
+ LLUUID uuid = avatar_ids[i];
- bits = compact_local & 0xFF;
- pos_local.mV[VY] = (F32)bits;
- compact_local >>= 8;
+ bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL);
- bits = compact_local & 0xFF;
- pos_local.mV[VX] = (F32)bits;
+ LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color;
- pos_global.setVec( pos_local );
- pos_global += origin_global;
+ unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z &&
+ camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z;
- pos_map = globalPosToView(pos_global);
+ LLWorldMapView::drawAvatar(
+ pos_map.mV[VX], pos_map.mV[VY],
+ color,
+ pos_map.mV[VZ], mDotRadius,
+ unknown_relative_z);
- BOOL show_as_friend = FALSE;
- if( i < regionp->mMapAvatarIDs.count())
+ if(uuid.notNull())
+ {
+ bool selected = false;
+ uuid_vec_t::iterator sel_iter = gmSelected.begin();
+ for (; sel_iter != gmSelected.end(); sel_iter++)
{
- show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(regionp->mMapAvatarIDs.get(i)) != NULL);
+ if(*sel_iter == uuid)
+ {
+ selected = true;
+ break;
+ }
}
- LLWorldMapView::drawAvatar(
- pos_map.mV[VX], pos_map.mV[VY],
- show_as_friend ? map_avatar_friend_color : map_avatar_color,
- pos_map.mV[VZ], mDotRadius);
-
- F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
- LLVector2(local_mouse_x,local_mouse_y));
- if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist)
+ if(selected)
{
- closest_dist = dist_to_cursor;
- mClosestAgentToCursor = regionp->mMapAvatarIDs.get(i);
+ if( (pos_map.mV[VX] < 0) ||
+ (pos_map.mV[VY] < 0) ||
+ (pos_map.mV[VX] >= getRect().getWidth()) ||
+ (pos_map.mV[VY] >= getRect().getHeight()) )
+ {
+ S32 x = llround( pos_map.mV[VX] );
+ S32 y = llround( pos_map.mV[VY] );
+ LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10);
+ } else
+ {
+ LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f);
+ }
}
}
+
+ F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
+ LLVector2(local_mouse_x,local_mouse_y));
+ if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared)
+ {
+ closest_dist_squared = dist_to_cursor_squared;
+ mClosestAgentToCursor = uuid;
+ }
}
// Draw dot for autopilot target
@@ -392,7 +417,7 @@ void LLNetMap::draw()
}
// Draw dot for self avatar position
- pos_global = gAgent.getPositionGlobal();
+ LLVector3d pos_global = gAgent.getPositionGlobal();
pos_map = globalPosToView(pos_global);
S32 dot_width = llround(mDotRadius * 2.f);
LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage;
@@ -403,9 +428,9 @@ void LLNetMap::draw()
dot_width,
dot_width);
- F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
+ F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
LLVector2(local_mouse_x,local_mouse_y));
- if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist)
+ if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared)
{
mClosestAgentToCursor = gAgent.getID();
}
@@ -444,7 +469,7 @@ void LLNetMap::draw()
// If we don't rotate the map, we have to rotate the frustum.
gGL.pushMatrix();
gGL.translatef( ctr_x, ctr_y, 0 );
- glRotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
+ gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
gGL.begin( LLRender::TRIANGLES );
gGL.vertex2f( 0, 0 );
gGL.vertex2f( -half_width_pixels, far_clip_pixels );
@@ -466,9 +491,11 @@ void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent)
createObjectImage();
}
-LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
+LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos)
{
- LLVector3d relative_pos_global = global_pos - gAgentCamera.getCameraPositionGlobal();
+ LLVector3d camera_position = gAgentCamera.getCameraPositionGlobal();
+
+ LLVector3d relative_pos_global = global_pos - camera_position;
LLVector3 pos_local;
pos_local.setVec(relative_pos_global); // convert to floats from doubles
@@ -493,7 +520,7 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
BOOL draw_arrow )
{
- LLVector3 pos_local = globalPosToView( pos_global );
+ LLVector3 pos_local = globalPosToView(pos_global);
if( (pos_local.mV[VX] < 0) ||
(pos_local.mV[VY] < 0) ||
(pos_local.mV[VX] >= getRect().getWidth()) ||
@@ -598,7 +625,6 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
args["[REGION]"] = region_name;
std::string msg = mToolTipMsg;
LLStringUtil::format(msg, args);
-
LLToolTipMgr::instance().show(LLToolTip::Params()
.message(msg)
.sticky_rect(sticky_rect));
@@ -791,6 +817,9 @@ BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )
BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )
{
+ if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3)
+ handleClick(x,y,mask);
+
if (hasMouseCapture())
{
if (mPanning)
@@ -819,6 +848,60 @@ BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )
return FALSE;
}
+BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (mPopupMenu)
+ {
+ mPopupMenu->buildDrawLabels();
+ mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
+ mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
+ LLMenuGL::showPopup(this, mPopupMenu, x, y);
+ }
+ return TRUE;
+}
+
+BOOL LLNetMap::handleClick(S32 x, S32 y, MASK mask)
+{
+ // TODO: allow clicking an avatar on minimap to select avatar in the nearby avatar list
+ // if(mClosestAgentToCursor.notNull())
+ // mNearbyList->selectUser(mClosestAgentToCursor);
+ // Needs a registered observer i guess to accomplish this without using
+ // globals to tell the mNearbyList in llpeoplepanel to select the user
+ return TRUE;
+}
+
+BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ LLVector3d pos_global = viewPosToGlobal(x, y);
+
+ bool double_click_teleport = gSavedSettings.getBOOL("DoubleClickTeleport");
+ bool double_click_show_world_map = gSavedSettings.getBOOL("DoubleClickShowWorldMap");
+
+ if (double_click_teleport || double_click_show_world_map)
+ {
+ // If we're not tracking a beacon already, double-click will set one
+ if (!LLTracker::isTracking(NULL))
+ {
+ LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance();
+ if (world_map)
+ {
+ world_map->trackLocation(pos_global);
+ }
+ }
+ }
+
+ if (double_click_teleport)
+ {
+ // If DoubleClickTeleport is on, double clicking the minimap will teleport there
+ gAgent.teleportViaLocationLookAt(pos_global);
+ }
+ else if (double_click_show_world_map)
+ {
+ LLFloaterReg::showInstance("world_map");
+ }
+ return TRUE;
+}
+
// static
bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )
{
@@ -869,3 +952,38 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
return TRUE;
}
+
+void LLNetMap::handleZoom(const LLSD& userdata)
+{
+ std::string level = userdata.asString();
+
+ F32 scale = 0.0f;
+ if (level == std::string("default"))
+ {
+ LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
+ if(pvar)
+ {
+ pvar->resetToDefault();
+ scale = gSavedSettings.getF32("MiniMapScale");
+ }
+ }
+ else if (level == std::string("close"))
+ scale = LLNetMap::MAP_SCALE_MAX;
+ else if (level == std::string("medium"))
+ scale = LLNetMap::MAP_SCALE_MID;
+ else if (level == std::string("far"))
+ scale = LLNetMap::MAP_SCALE_MIN;
+ if (scale != 0.0f)
+ {
+ setScale(scale);
+ }
+}
+
+void LLNetMap::handleStopTracking (const LLSD& userdata)
+{
+ if (mPopupMenu)
+ {
+ mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ LLTracker::stopTracking ((void*)LLTracker::isTracking(NULL));
+ }
+}