diff options
Diffstat (limited to 'linden/indra/newview/llnetmap.cpp')
-rw-r--r-- | linden/indra/newview/llnetmap.cpp | 263 |
1 files changed, 234 insertions, 29 deletions
diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp index 5a54068..b8bf0cb 100644 --- a/linden/indra/newview/llnetmap.cpp +++ b/linden/indra/newview/llnetmap.cpp | |||
@@ -45,8 +45,10 @@ | |||
45 | #include "llcolorscheme.h" | 45 | #include "llcolorscheme.h" |
46 | #include "llviewercontrol.h" | 46 | #include "llviewercontrol.h" |
47 | #include "llfloateravatarinfo.h" | 47 | #include "llfloateravatarinfo.h" |
48 | #include "llfloatermap.h" | ||
48 | #include "llfloaterworldmap.h" | 49 | #include "llfloaterworldmap.h" |
49 | #include "llframetimer.h" | 50 | #include "llframetimer.h" |
51 | #include "llmutelist.h" | ||
50 | #include "lltracker.h" | 52 | #include "lltracker.h" |
51 | #include "llmenugl.h" | 53 | #include "llmenugl.h" |
52 | #include "llsurface.h" | 54 | #include "llsurface.h" |
@@ -76,6 +78,8 @@ const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f; | |||
76 | const F32 MIN_DOT_RADIUS = 3.5f; | 78 | const F32 MIN_DOT_RADIUS = 3.5f; |
77 | const F32 DOT_SCALE = 0.75f; | 79 | const F32 DOT_SCALE = 0.75f; |
78 | const F32 MIN_PICK_SCALE = 2.f; | 80 | const F32 MIN_PICK_SCALE = 2.f; |
81 | const S32 SLOP = 2; | ||
82 | const S32 TRACKING_RADIUS = 3; | ||
79 | 83 | ||
80 | LLNetMap::LLNetMap(const std::string& name) : | 84 | LLNetMap::LLNetMap(const std::string& name) : |
81 | LLPanel(name), | 85 | LLPanel(name), |
@@ -96,6 +100,11 @@ LLNetMap::LLNetMap(const std::string& name) : | |||
96 | 100 | ||
97 | // Register event listeners for popup menu | 101 | // Register event listeners for popup menu |
98 | (new LLScaleMap())->registerListener(this, "MiniMap.ZoomLevel"); | 102 | (new LLScaleMap())->registerListener(this, "MiniMap.ZoomLevel"); |
103 | (new LLCenterMap())->registerListener(this, "MiniMap.Center"); | ||
104 | (new LLCheckCenterMap())->registerListener(this, "MiniMap.CheckCenter"); | ||
105 | (new LLRotateMap())->registerListener(this, "MiniMap.Rotate"); | ||
106 | (new LLCheckRotateMap())->registerListener(this, "MiniMap.CheckRotate"); | ||
107 | (new LLShowWorldMap())->registerListener(this, "MiniMap.ShowWorldMap"); | ||
99 | (new LLStopTracking())->registerListener(this, "MiniMap.StopTracking"); | 108 | (new LLStopTracking())->registerListener(this, "MiniMap.StopTracking"); |
100 | (new LLEnableTracking())->registerListener(this, "MiniMap.EnableTracking"); | 109 | (new LLEnableTracking())->registerListener(this, "MiniMap.EnableTracking"); |
101 | (new LLShowAgentProfile())->registerListener(this, "MiniMap.ShowProfile"); | 110 | (new LLShowAgentProfile())->registerListener(this, "MiniMap.ShowProfile"); |
@@ -114,6 +123,11 @@ LLNetMap::LLNetMap(const std::string& name) : | |||
114 | mPopupMenuHandle = menu->getHandle(); | 123 | mPopupMenuHandle = menu->getHandle(); |
115 | } | 124 | } |
116 | 125 | ||
126 | BOOL LLNetMap::postBuild() | ||
127 | { | ||
128 | return TRUE; | ||
129 | } | ||
130 | |||
117 | LLNetMap::~LLNetMap() | 131 | LLNetMap::~LLNetMap() |
118 | { | 132 | { |
119 | } | 133 | } |
@@ -163,8 +177,11 @@ void LLNetMap::draw() | |||
163 | createObjectImage(); | 177 | createObjectImage(); |
164 | } | 178 | } |
165 | 179 | ||
166 | mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); | 180 | if (gSavedSettings.getS32( "MiniMapCenter" ) != MAP_CENTER_NONE) |
167 | mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); | 181 | { |
182 | mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); | ||
183 | mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); | ||
184 | } | ||
168 | 185 | ||
169 | F32 rotation = 0; | 186 | F32 rotation = 0; |
170 | 187 | ||
@@ -264,26 +281,24 @@ void LLNetMap::draw() | |||
264 | } | 281 | } |
265 | gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); | 282 | gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); |
266 | } | 283 | } |
267 | |||
268 | |||
269 | LLVector3d old_center = mObjectImageCenterGlobal; | ||
270 | LLVector3d new_center = gAgent.getCameraPositionGlobal(); | ||
271 | |||
272 | new_center.mdV[0] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[0]); | ||
273 | new_center.mdV[1] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[1]); | ||
274 | new_center.mdV[2] = 0.f; | ||
275 | 284 | ||
285 | // Redraw object layer periodically | ||
276 | if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) | 286 | if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) |
277 | { | 287 | { |
278 | mUpdateNow = FALSE; | 288 | mUpdateNow = FALSE; |
279 | mObjectImageCenterGlobal = new_center; | ||
280 | 289 | ||
281 | // Center moved enough. | 290 | // Locate the centre of the object layer, accounting for panning |
291 | LLVector3 new_center = globalPosToView(gAgent.getCameraPositionGlobal(), rotate_map); | ||
292 | new_center.mV[0] -= mCurPanX; | ||
293 | new_center.mV[1] -= mCurPanY; | ||
294 | new_center.mV[2] = 0.f; | ||
295 | mObjectImageCenterGlobal = viewPosToGlobal(llround(new_center.mV[0]), llround(new_center.mV[1]), rotate_map); | ||
296 | |||
282 | // Create the base texture. | 297 | // Create the base texture. |
283 | U8 *default_texture = mObjectRawImagep->getData(); | 298 | U8 *default_texture = mObjectRawImagep->getData(); |
284 | memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); | 299 | memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); |
285 | 300 | ||
286 | // Draw buildings | 301 | // Draw objects |
287 | gObjectList.renderObjectsForMap(*this); | 302 | gObjectList.renderObjectsForMap(*this); |
288 | 303 | ||
289 | mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); | 304 | mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); |
@@ -327,6 +342,10 @@ void LLNetMap::draw() | |||
327 | // Draw avatars | 342 | // Draw avatars |
328 | LLColor4 avatar_color = gColors.getColor( "MapAvatar" ); | 343 | LLColor4 avatar_color = gColors.getColor( "MapAvatar" ); |
329 | LLColor4 friend_color = gColors.getColor( "MapFriend" ); | 344 | LLColor4 friend_color = gColors.getColor( "MapFriend" ); |
345 | LLColor4 muted_color = gColors.getColor( "MapMuted" ); | ||
346 | LLColor4 selected_color = gColors.getColor( "MapSelected" ); | ||
347 | LLColor4 glyph_color; | ||
348 | |||
330 | std::vector<LLUUID> avatar_ids; | 349 | std::vector<LLUUID> avatar_ids; |
331 | std::vector<LLVector3d> positions; | 350 | std::vector<LLVector3d> positions; |
332 | LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); | 351 | LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); |
@@ -335,10 +354,37 @@ void LLNetMap::draw() | |||
335 | // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. | 354 | // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. |
336 | // just be careful to sort the avatar IDs along with the positions. -MG | 355 | // just be careful to sort the avatar IDs along with the positions. -MG |
337 | pos_map = globalPosToView(positions[i], rotate_map); | 356 | pos_map = globalPosToView(positions[i], rotate_map); |
357 | |||
358 | if (LLFloaterMap::getSelected() == avatar_ids[i]) | ||
359 | { | ||
360 | glyph_color = selected_color; | ||
361 | } | ||
362 | // Show them muted even if they're friends | ||
363 | else if (LLMuteList::getInstance()->isMuted(avatar_ids[i])) | ||
364 | { | ||
365 | glyph_color = muted_color; | ||
366 | } | ||
367 | else if (is_agent_friend(avatar_ids[i])) | ||
368 | { | ||
369 | glyph_color = friend_color; | ||
370 | } | ||
371 | else | ||
372 | { | ||
373 | glyph_color = avatar_color; | ||
374 | } | ||
375 | |||
376 | // [RLVa:KB] | ||
377 | if ( rlv_handler_t::isEnabled() && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) ) | ||
378 | { | ||
379 | // User is not allowed to see who it is, or even if it's a friend, | ||
380 | // due to RLV settings. | ||
381 | glyph_color = avatar_color; | ||
382 | } | ||
383 | // [/RLVa:KB] | ||
338 | 384 | ||
339 | LLWorldMapView::drawAvatar( | 385 | LLWorldMapView::drawAvatar( |
340 | pos_map.mV[VX], pos_map.mV[VY], | 386 | pos_map.mV[VX], pos_map.mV[VY], |
341 | is_agent_friend(avatar_ids[i]) ? friend_color : avatar_color, | 387 | glyph_color, |
342 | pos_map.mV[VZ], | 388 | pos_map.mV[VZ], |
343 | mDotRadius); | 389 | mDotRadius); |
344 | 390 | ||
@@ -435,6 +481,8 @@ void LLNetMap::draw() | |||
435 | setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); | 481 | setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); |
436 | 482 | ||
437 | LLView::draw(); | 483 | LLView::draw(); |
484 | |||
485 | LLFloaterMap::updateRadar(); | ||
438 | } | 486 | } |
439 | 487 | ||
440 | void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) | 488 | void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) |
@@ -540,11 +588,39 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec | |||
540 | std::string fullname; | 588 | std::string fullname; |
541 | if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) | 589 | if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) |
542 | { | 590 | { |
543 | msg.append(fullname); | 591 | // [RLVa:KB] |
544 | msg.append("\n"); | 592 | if ( rlv_handler_t::isEnabled() && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) ) |
593 | { | ||
594 | // User is not allowed to see who it is, due to RLV settings. | ||
595 | msg.append(rlv_handler_t::cstrHidden); | ||
596 | } | ||
597 | else | ||
598 | { | ||
599 | msg.append(fullname); | ||
600 | msg.append("\n"); | ||
601 | } | ||
602 | // [/RLVa:KB] | ||
603 | } | ||
604 | |||
605 | // [RLVa:KB] | ||
606 | if (rlv_handler_t::isEnabled() && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
607 | { | ||
608 | // User is not allowed to see where they are, due to RLV settings. | ||
609 | msg.append( rlv_handler_t::cstrHidden ); | ||
610 | } | ||
611 | else | ||
612 | { | ||
613 | msg.append( region->getName() ); | ||
545 | } | 614 | } |
546 | msg.append( region->getName() ); | 615 | // [/RLVa:KB] |
547 | 616 | ||
617 | |||
618 | msg.append("\n"); | ||
619 | gSavedSettings.getBOOL( "MiniMapTeleport" ) ? | ||
620 | msg.append(getString("tooltip_tp")) : msg.append(getString("tooltip_map")); | ||
621 | msg.append("\n"); | ||
622 | msg.append(getString("tooltip_pan")); | ||
623 | |||
548 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 624 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
549 | std::string buffer; | 625 | std::string buffer; |
550 | msg.append("\n"); | 626 | msg.append("\n"); |
@@ -554,13 +630,6 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec | |||
554 | buffer = region->getHost().getString(); | 630 | buffer = region->getHost().getString(); |
555 | msg.append(buffer); | 631 | msg.append(buffer); |
556 | #endif | 632 | #endif |
557 | // *TODO: | ||
558 | // - put this under the control of XUI so it can be translated. | ||
559 | |||
560 | if ( gSavedSettings.getBOOL( "MiniMapTeleport" )) | ||
561 | msg.append("\n(Double-click to teleport)"); | ||
562 | else | ||
563 | msg.append("\n(Double-click to open Map)"); | ||
564 | 633 | ||
565 | S32 SLOP = 4; | 634 | S32 SLOP = 4; |
566 | localPointToScreen( | 635 | localPointToScreen( |
@@ -616,11 +685,7 @@ void LLNetMap::renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U & | |||
616 | LLVector3 local_pos; | 685 | LLVector3 local_pos; |
617 | local_pos.setVec( pos - mObjectImageCenterGlobal ); | 686 | local_pos.setVec( pos - mObjectImageCenterGlobal ); |
618 | 687 | ||
619 | // DEV-17370 - megaprims of size > 4096 cause lag. (go figger.) | 688 | S32 diameter_pixels = llround(2 * radius_meters * mObjectMapTPM); |
620 | const F32 MAX_RADIUS = 256.0f; | ||
621 | F32 radius_clamped = llmin(radius_meters, MAX_RADIUS); | ||
622 | |||
623 | S32 diameter_pixels = llround(2 * radius_clamped * mObjectMapTPM); | ||
624 | renderPoint( local_pos, color, diameter_pixels ); | 689 | renderPoint( local_pos, color, diameter_pixels ); |
625 | } | 690 | } |
626 | 691 | ||
@@ -740,6 +805,98 @@ void LLNetMap::createObjectImage() | |||
740 | mUpdateNow = TRUE; | 805 | mUpdateNow = TRUE; |
741 | } | 806 | } |
742 | 807 | ||
808 | BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask ) | ||
809 | { | ||
810 | if (!(mask & MASK_SHIFT)) return FALSE; | ||
811 | |||
812 | // Start panning | ||
813 | gFocusMgr.setMouseCapture( this ); | ||
814 | |||
815 | mMouseDownPanX = llround(mCurPanX); | ||
816 | mMouseDownPanY = llround(mCurPanY); | ||
817 | mMouseDownX = x; | ||
818 | mMouseDownY = y; | ||
819 | return TRUE; | ||
820 | } | ||
821 | |||
822 | BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask ) | ||
823 | { | ||
824 | if (hasMouseCapture()) | ||
825 | { | ||
826 | if (mPanning) | ||
827 | { | ||
828 | // restore mouse cursor | ||
829 | S32 local_x, local_y; | ||
830 | local_x = mMouseDownX + llfloor(mCurPanX - mMouseDownPanX); | ||
831 | local_y = mMouseDownY + llfloor(mCurPanY - mMouseDownPanY); | ||
832 | LLRect clip_rect = getRect(); | ||
833 | clip_rect.stretch(-8); | ||
834 | clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y); | ||
835 | LLUI::setCursorPositionLocal(this, local_x, local_y); | ||
836 | |||
837 | // finish the pan | ||
838 | mPanning = FALSE; | ||
839 | |||
840 | mMouseDownX = 0; | ||
841 | mMouseDownY = 0; | ||
842 | |||
843 | // auto centre | ||
844 | mTargetPanX = 0; | ||
845 | mTargetPanY = 0; | ||
846 | } | ||
847 | gViewerWindow->showCursor(); | ||
848 | gFocusMgr.setMouseCapture( NULL ); | ||
849 | return TRUE; | ||
850 | } | ||
851 | return FALSE; | ||
852 | } | ||
853 | |||
854 | // static | ||
855 | BOOL LLNetMap::outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y) | ||
856 | { | ||
857 | S32 dx = x - start_x; | ||
858 | S32 dy = y - start_y; | ||
859 | |||
860 | return (dx <= -SLOP || SLOP <= dx || dy <= -SLOP || SLOP <= dy); | ||
861 | } | ||
862 | |||
863 | BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) | ||
864 | { | ||
865 | if (hasMouseCapture()) | ||
866 | { | ||
867 | if (mPanning || outsideSlop(x, y, mMouseDownX, mMouseDownY)) | ||
868 | { | ||
869 | // just started panning, so hide cursor | ||
870 | if (!mPanning) | ||
871 | { | ||
872 | mPanning = TRUE; | ||
873 | gViewerWindow->hideCursor(); | ||
874 | } | ||
875 | |||
876 | F32 delta_x = (F32)(gViewerWindow->getCurrentMouseDX()); | ||
877 | F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY()); | ||
878 | |||
879 | // Set pan to value at start of drag + offset | ||
880 | mCurPanX += delta_x; | ||
881 | mCurPanY += delta_y; | ||
882 | mTargetPanX = mCurPanX; | ||
883 | mTargetPanY = mCurPanY; | ||
884 | |||
885 | gViewerWindow->moveCursorToCenter(); | ||
886 | } | ||
887 | |||
888 | // Doesn't matter, cursor should be hidden | ||
889 | gViewerWindow->setCursor( UI_CURSOR_CROSS ); | ||
890 | return TRUE; | ||
891 | } | ||
892 | else | ||
893 | { | ||
894 | gViewerWindow->setCursor( UI_CURSOR_CROSS ); | ||
895 | lldebugst(LLERR_USER_INPUT) << "hover handled by LLNetMap" << llendl; | ||
896 | return TRUE; | ||
897 | } | ||
898 | } | ||
899 | |||
743 | BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask ) | 900 | BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask ) |
744 | { | 901 | { |
745 | if (gSavedSettings.getBOOL( "MiniMapTeleport" )) | 902 | if (gSavedSettings.getBOOL( "MiniMapTeleport" )) |
@@ -792,6 +949,54 @@ bool LLNetMap::LLScaleMap::handleEvent(LLPointer<LLEvent> event, const LLSD& use | |||
792 | return true; | 949 | return true; |
793 | } | 950 | } |
794 | 951 | ||
952 | bool LLNetMap::LLRotateMap::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
953 | { | ||
954 | BOOL rotate = gSavedSettings.getBOOL("MiniMapRotate"); | ||
955 | gSavedSettings.setBOOL("MiniMapRotate", !rotate); | ||
956 | |||
957 | return true; | ||
958 | } | ||
959 | |||
960 | bool LLNetMap::LLCheckRotateMap::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
961 | { | ||
962 | LLNetMap *self = mPtr; | ||
963 | BOOL enabled = gSavedSettings.getBOOL("MiniMapRotate"); | ||
964 | self->findControl(userdata["control"].asString())->setValue(enabled); | ||
965 | return true; | ||
966 | } | ||
967 | |||
968 | bool LLNetMap::LLCenterMap::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
969 | { | ||
970 | S32 center = userdata.asInteger(); | ||
971 | |||
972 | if (gSavedSettings.getS32("MiniMapCenter") == center) | ||
973 | { | ||
974 | gSavedSettings.setS32("MiniMapCenter", MAP_CENTER_NONE); | ||
975 | } | ||
976 | else | ||
977 | { | ||
978 | gSavedSettings.setS32("MiniMapCenter", userdata.asInteger()); | ||
979 | } | ||
980 | |||
981 | return true; | ||
982 | } | ||
983 | |||
984 | bool LLNetMap::LLCheckCenterMap::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
985 | { | ||
986 | LLNetMap *self = mPtr; | ||
987 | EMiniMapCenter center = (EMiniMapCenter)userdata["data"].asInteger(); | ||
988 | BOOL enabled = (gSavedSettings.getS32("MiniMapCenter") == center); | ||
989 | |||
990 | self->findControl(userdata["control"].asString())->setValue(enabled); | ||
991 | return true; | ||
992 | } | ||
993 | |||
994 | bool LLNetMap::LLShowWorldMap::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
995 | { | ||
996 | LLFloaterWorldMap::show(NULL, FALSE); | ||
997 | return true; | ||
998 | } | ||
999 | |||
795 | bool LLNetMap::LLStopTracking::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 1000 | bool LLNetMap::LLStopTracking::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
796 | { | 1001 | { |
797 | LLTracker::stopTracking(NULL); | 1002 | LLTracker::stopTracking(NULL); |