diff --git a/indra/newview/app_settings/settings_alchemy.xml b/indra/newview/app_settings/settings_alchemy.xml index d464162e281cb28dff627c31e3046296a6568c23..ee2b98f32d9feb9b7237888266278c79a959fdb0 100644 --- a/indra/newview/app_settings/settings_alchemy.xml +++ b/indra/newview/app_settings/settings_alchemy.xml @@ -299,6 +299,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>AlchemyMinimapTile</key> + <map> + <key>Comment</key> + <string>Use world map tile as minimap image</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>AlchemyMotionResetsCamera</key> <map> <key>Comment</key> diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 16dc05910ca134b5a27850d2609fbcee8acda033..f210336a93a3ff09fd7fbc2e94cc6b8551d29b9c 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -48,6 +48,7 @@ #include "llappviewer.h" // for gDisconnected #include "llcallingcard.h" // LLAvatarTracker #include "llfloaterworldmap.h" +#include "llparcel.h" #include "lltracker.h" #include "llsurface.h" #include "llviewercamera.h" @@ -56,6 +57,8 @@ #include "llviewertexturelist.h" #include "llviewermenu.h" #include "llviewerobjectlist.h" +#include "llviewerparcelmgr.h" +#include "llviewerparceloverlay.h" #include "llviewerregion.h" #include "llviewerwindow.h" #include "llworld.h" @@ -77,7 +80,7 @@ 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; +const F64 COARSEUPDATE_MAX_Z = 1020.0; LLNetMap::LLNetMap (const Params & p) : LLUICtrl (p), @@ -167,6 +170,7 @@ void LLNetMap::draw() static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); + static const LLCachedControl<bool> use_world_map_image(gSavedSettings, "AlchemyMinimapTile", true); if (mObjectImagep.isNull()) { createObjectImage(); @@ -234,6 +238,7 @@ void LLNetMap::draw() LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; + const F32 real_width(regionp->getWidth()); // background region rectangle F32 bottom = relative_y; @@ -254,40 +259,76 @@ void LLNetMap::draw() { gGL.color4f(1.f, 0.5f, 0.5f, 1.f); } - - - // Draw using texture. - gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2f(left, top); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2f(left, bottom); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2f(right, bottom); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2f(right, top); - gGL.end(); - - // Draw water - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); + + // <alchemy> + bool render_land_textures = true; + if (use_world_map_image) + { + const LLViewerRegion::tex_matrix_t& tiles(regionp->getWorldMapTiles()); + for (S32 i(0), scaled_width(real_width / region_width), square_width(scaled_width * scaled_width); + i < square_width; ++i) + { + const F32 y(i / scaled_width); + const F32 x(i - y * scaled_width); + const F32 local_left(left + x * mScale); + const F32 local_right(local_left + mScale); + const F32 local_bottom(bottom + y * mScale); + const F32 local_top(local_bottom + mScale); + LLViewerTexture* img = tiles[x * scaled_width + y]; + if (img && img->hasGLTexture()) + { + gGL.getTexUnit(0)->bind(img); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(local_left, local_top); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(local_left, local_bottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(local_right, local_bottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(local_right, local_top); + gGL.end(); + img->setBoostLevel(LLViewerTexture::BOOST_MAP_VISIBLE); + render_land_textures = false; + } + } + } + + if (render_land_textures) { - if (regionp->getLand().getWaterTexture()) + // Draw using texture. + gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(left, top); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(left, bottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(right, bottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(right, top); + gGL.end(); + + // Draw water + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); { - gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2f(left, top); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2f(left, bottom); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2f(right, bottom); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2f(right, top); - gGL.end(); + if (regionp->getLand().getWaterTexture()) + { + gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(left, top); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(left, bottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(right, bottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(right, top); + gGL.end(); + } } + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } // Redraw object layer periodically diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 04725e2f2307d902d807ba2292b0e7c7f5c4dd4e..723affb695ae887c3a9819a01d8519fd0091da7d 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -661,7 +661,10 @@ LLViewerRegion::~LLViewerRegion() saveObjectCache(); delete mImpl; - mImpl = NULL; + mImpl = nullptr; + + for (LLPointer<LLViewerTexture> tile : mWorldMapTiles) + tile->setBoostLevel(LLViewerTexture::BOOST_NONE); } /*virtual*/ @@ -3322,3 +3325,44 @@ U32 LLViewerRegion::getMaxMaterialsPerTransaction() const +std::string LLViewerRegion::getMapServerURL() const +{ + std::string url; + if (mSimulatorFeatures.has("OpenSimExtras") + && mSimulatorFeatures["OpenSimExtras"].has("map-server-url")) + { + url = mSimulatorFeatures["OpenSimExtras"]["map-server-url"].asString(); + } + else + { + url = gSavedSettings.getString("CurrentMapServerURL"); + } + return url; +} + + +const LLViewerRegion::tex_matrix_t& LLViewerRegion::getWorldMapTiles() const +{ + if (mWorldMapTiles.empty()) + { + U32 gridX, gridY; + grid_from_region_handle(mHandle, &gridX, &gridY); + U32 totalX(getWidth() / REGION_WIDTH_U32); + if (!totalX) ++totalX; // If this region is too small, still get an image. + // *TODO: Non-square regions? + //U32 totalY(getLength()/REGION_WIDTH_U32); + //if (!totalY) ++totalY; // If this region is too small, still get an image. + const U32 totalY(totalX); + mWorldMapTiles.reserve(totalX * totalY); + for (U32 x = 0; x != totalX; ++x) + for (U32 y = 0; y != totalY; ++y) + { + const std::string map_url = getMapServerURL().append(llformat("map-1-%d-%d-objects.jpg", gridX + x, gridY + y)); + LLPointer<LLViewerTexture> tex(LLViewerTextureManager::getFetchedTextureFromUrl(map_url, FTT_MAP_TILE, TRUE, + LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + mWorldMapTiles.push_back(tex); + tex->setBoostLevel(LLViewerTexture::BOOST_MAP); + } + } + return mWorldMapTiles; +} diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c79008a7d9c7a4e351d80d6a01b8dbaca2221947..4596f5b01712b17ab0c3acbcbeaf8066ed9da77c 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -53,6 +53,7 @@ const U32 REGION_HANDSHAKE_SUPPORTS_SELF_APPEARANCE = 1U << 2; class LLEventPoll; class LLVLComposition; class LLViewerObject; +class LLViewerTexture; class LLMessageSystem; class LLNetMap; class LLViewerParcelOverlay; @@ -71,7 +72,7 @@ class LLViewerRegionImpl; class LLViewerOctreeGroup; class LLVOCachePartition; -class LLViewerRegion: public LLCapabilityProvider // implements this interface +class LLViewerRegion final : public LLCapabilityProvider // implements this interface { public: //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR @@ -390,6 +391,12 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;} + /// Hypergrid map server url + std::string getMapServerURL() const; + + typedef std::vector<LLPointer<LLViewerTexture> > tex_matrix_t; + const tex_matrix_t& getWorldMapTiles() const; + private: void addToVOCacheTree(LLVOCacheEntry* entry); LLViewerObject* addNewObject(LLVOCacheEntry* entry); @@ -552,6 +559,8 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface LLFrameTimer mMaterialsCapThrottleTimer; LLFrameTimer mRenderInfoRequestTimer; LLFrameTimer mRenderInfoReportTimer; + + mutable tex_matrix_t mWorldMapTiles; }; inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const