From d82dc8bf99133fd7ec248aee41e939bddd08f051 Mon Sep 17 00:00:00 2001 From: Cinder <cinder@sdf.org> Date: Sun, 21 Jan 2018 14:36:23 -0600 Subject: [PATCH] Add minimap parcel lines stuff originally by Kitty Barnett with mods --- indra/newview/llnetmap.cpp | 234 ++++++++++++++++++++++-- indra/newview/llnetmap.h | 21 ++- indra/newview/llviewerparcelmgr.cpp | 26 ++- indra/newview/llviewerparcelmgr.h | 12 +- indra/newview/llviewerparceloverlay.cpp | 11 ++ indra/newview/llviewerparceloverlay.h | 6 + 6 files changed, 286 insertions(+), 24 deletions(-) diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 2796ff4082..c07f4b656b 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -51,6 +51,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" @@ -59,6 +60,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" @@ -91,9 +94,14 @@ LLNetMap::LLNetMap (const Params & p) mCurPan(0.f, 0.f), mStartPan(0.f, 0.f), mMouseDown(0, 0), + mUpdateObjectImage(false), + mUpdateParcelImage(false), mObjectImageCenterGlobal( gAgentCamera.getCameraPositionGlobal() ), mObjectRawImagep(), mObjectImagep(), + mParcelImageCenterGlobal( gAgentCamera.getCameraPositionGlobal() ), + mParcelRawImagep(), + mParcelImagep(), mClosestAgentToCursor(), mClosestAgentAtLastRightClick(), mToolTipMsg(), @@ -112,6 +120,14 @@ LLNetMap::~LLNetMap() menu->die(); mPopupMenuHandle.markDead(); } + if (mParcelMgrConn.connected()) + { + mParcelMgrConn.disconnect(); + } + if (mParcelOverlayConn.connected()) + { + mParcelOverlayConn.disconnect(); + } } BOOL LLNetMap::postBuild() @@ -123,6 +139,10 @@ BOOL LLNetMap::postBuild() LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mPopupMenuHandle = menu->getHandle(); + + mParcelMgrConn = LLViewerParcelMgr::instance().setCollisionUpdateCallback(boost::bind(&LLNetMap::refreshParcelOverlay, this)); + mParcelOverlayConn = LLViewerParcelOverlay::setUpdateCallback(boost::bind(&LLNetMap::refreshParcelOverlay, this)); + return TRUE; } @@ -148,6 +168,8 @@ void LLNetMap::setScale( F32 scale ) mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); gSavedSettings.setF32("MiniMapScale", mScale); + mUpdateObjectImage = true; + mUpdateParcelImage = true; mUpdateNow = true; } @@ -169,11 +191,14 @@ 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 LLUIColor map_line_color = LLUIColorTable::instance().getColor("MapLineColor", LLColor4::red); + static LLUIColor map_parcel_line_color = LLUIColorTable::instance().getColor("MapParcelBoundryLine", LLColor4::white); + static LLCachedControl<bool> use_world_map_image(gSavedSettings, "AlchemyMinimapTile", true); static LLCachedControl<bool> center_to_region(gSavedSettings, "AlchemyMinimapCenterRegion", false); static LLCachedControl<bool> enable_object_render(gSavedSettings, "AlchemyMinimapRenderObjects", true); static LLCachedControl<bool> render_guide_line(gSavedSettings, "AlchemyMinimapGuideLine", false); static LLCachedControl<bool> map_chat_ring(gSavedSettings, "AlchemyMinimapChatRings", false); + static LLCachedControl<bool> minimap_parcel_boundries(gSavedSettings, "AlchemyMinimapParcelBoundries", false); const LLVector3d& globalpos = center_to_region ? curregionp->getCenterGlobal() : gAgentCamera.getCameraPositionGlobal(); const LLVector3& agentpos = center_to_region ? curregionp->getCenterAgent() : gAgentCamera.getCameraPositionAgent(); @@ -182,6 +207,10 @@ void LLNetMap::draw() { createObjectImage(); } + if (mParcelImagep.isNull()) + { + createParcelImage(); + } static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); if (auto_center) @@ -333,11 +362,17 @@ void LLNetMap::draw() // <//alchemy> // Redraw object layer periodically - static LLCachedControl<F32> object_layer_update_time_setting(gSavedSettings, "AlchemyMinimapObjectUpdateInterval", 0.1f); - F32 object_layer_update_time = llclamp((F32)object_layer_update_time_setting, 0.01f, 60.f); - if (mUpdateNow || (map_timer.getElapsedTimeF32() > object_layer_update_time)) // <alchemy/> + LLVector3 pos_center = globalPosToView(gAgentCamera.getCameraPositionGlobal()); + pos_center.mV[VX] -= mCurPan.mV[VX]; + pos_center.mV[VY] -= mCurPan.mV[VY]; + pos_center.mV[VZ] = 0.f; + LLVector3d pos_center_global = viewPosToGlobal(llfloor(pos_center.mV[VX]), llfloor(pos_center.mV[VY])); + + static LLCachedControl<F32> object_layer_update_time_setting(gSavedSettings, "AlchemyMinimapObjectUpdateInterval", 0.1f); + F32 object_layer_update_time = llclamp(object_layer_update_time_setting(), 0.01f, 60.f); + if (mUpdateObjectImage || (map_timer.getElapsedTimeF32() > object_layer_update_time)) // <alchemy/> { - mUpdateNow = false; + mUpdateObjectImage = false; // Locate the centre of the object layer, accounting for panning LLVector3 new_center = globalPosToView(globalpos); @@ -360,7 +395,27 @@ void LLNetMap::draw() map_timer.reset(); } + if (minimap_parcel_boundries + && (mUpdateParcelImage || dist_vec_squared2D(mParcelImageCenterGlobal, pos_center_global) > 9.0f)) + { + mUpdateParcelImage = false; + mParcelImageCenterGlobal = pos_center_global; + + U8* texture_data = mParcelRawImagep->getData(); + memset(texture_data, 0, mParcelImagep->getWidth() * mParcelImagep->getHeight() * mParcelImagep->getComponents()); + + // Process each region + for (LLWorld::region_list_t::const_iterator itr = LLWorld::getInstance()->getRegionList().begin(); + itr != LLWorld::getInstance()->getRegionList().end(); + ++itr) + { + LLViewerRegion* region = *itr; + LLColor4U overlay_color = region->isAlive() ? map_parcel_line_color.get() : LLColor4U(255, 128, 128, 255); + renderPropertyLinesForRegion(region, overlay_color); + } + mParcelImagep->setSubImage(mParcelRawImagep, 0, 0, mParcelImagep->getWidth(), mParcelImagep->getHeight()); + } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); LLVector3 camera_position = agentpos; map_center_agent -= camera_position; @@ -382,6 +437,31 @@ void LLNetMap::draw() gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.end(); + if (minimap_parcel_boundries) + { + map_center_agent = gAgent.getPosAgentFromGlobal(mParcelImageCenterGlobal) - camera_position; + map_center_agent.mV[VX] *= mScale / region_width; + map_center_agent.mV[VY] *= mScale / region_width; + + gGL.color4f(1.f, 1.f, 1.f, 1.f); + gGL.getTexUnit(0)->bind(mParcelImagep); + gGL.begin(LLRender::TRIANGLES); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); + gGL.end(); + } + gGL.popUIMatrix(); // Mouse pointer in local coordinates @@ -582,6 +662,7 @@ void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) { LLUICtrl::reshape(width, height, called_from_parent); createObjectImage(); + createParcelImage(); } LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos) @@ -875,34 +956,151 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color, } } -void LLNetMap::createObjectImage() +void LLNetMap::renderPropertyLinesForRegion(const LLViewerRegion* region, const LLColor4U& overlay_color) +{ + const S32 img_width = mParcelImagep->getWidth(); + const S32 img_height = mParcelImagep->getHeight(); + + const LLVector3 origin_local(region->getOriginGlobal() - mParcelImageCenterGlobal); + const S32 origin_x = ll_round(origin_local.mV[VX] * mObjectMapTPM + img_width / 2); + const S32 origin_y = ll_round(origin_local.mV[VY] * mObjectMapTPM + img_height / 2); + + U32* texture_data = reinterpret_cast<U32*>(mParcelRawImagep->getData()); + + // + // Draw the north and east region borders + // + const F32 real_width(region->getWidth()); + const S32 border_y = origin_y + ll_round(real_width * mObjectMapTPM); + if ( (border_y >= 0) && (border_y < img_height) ) + { + S32 cur_x = llclamp(origin_x, 0, img_width); + S32 end_x = llclamp(origin_x + ll_round(real_width * mObjectMapTPM), 0, img_width - 1); + for (; cur_x <= end_x; cur_x++) + texture_data[border_y * img_width + cur_x] = overlay_color.mAll; + } + const S32 border_x = origin_x + ll_round(real_width * mObjectMapTPM); + if ( (border_x >= 0) && (border_x < img_width) ) + { + S32 cur_y = llclamp(origin_y, 0, img_height); + S32 end_y = llclamp(origin_y + ll_round(real_width * mObjectMapTPM), 0, img_height - 1); + for (; cur_y <= end_y; cur_y++) + texture_data[cur_y * img_width + border_x] = overlay_color.mAll; + } + + // + // Render parcel lines + // + const F32 GRID_STEP = PARCEL_GRID_STEP_METERS; + const S32 GRIDS_PER_EDGE = real_width / GRID_STEP; + + const U8* ownership = region->getParcelOverlay()->getOwnership(); + const U8* collision = (region->getHandle() == LLViewerParcelMgr::instance().getCollisionRegionHandle()) ? LLViewerParcelMgr::instance().getCollisionBitmap() : NULL; + for (S32 idxRow = 0; idxRow < GRIDS_PER_EDGE; idxRow++) + { + for (S32 idxCol = 0; idxCol < GRIDS_PER_EDGE; idxCol++) + { + S32 overlay = ownership[idxRow * GRIDS_PER_EDGE + idxCol]; + S32 idx_collision = idxRow * GRIDS_PER_EDGE + idxCol; + bool for_sale = ((overlay & PARCEL_COLOR_MASK) == PARCEL_FOR_SALE); + bool auction = ((overlay & PARCEL_COLOR_MASK) == PARCEL_AUCTION); + bool collides = (collision) && (collision[idx_collision / 8] & (1 << (idx_collision % 8))); + if ( (!for_sale) && (!collides) && (!auction) && (0 == (overlay & (PARCEL_SOUTH_LINE | PARCEL_WEST_LINE))) ) + continue; + + const S32 pos_x = origin_x + ll_round(idxCol * GRID_STEP * mObjectMapTPM); + const S32 pos_y = origin_y + ll_round(idxRow * GRID_STEP * mObjectMapTPM); + + static LLCachedControl<bool> sShowForSaleParcels(gSavedSettings, "AlchemyMiniMapForSaleParcels", false); + static LLCachedControl<bool> sShowCollisionParcels(gSavedSettings, "AlchemyMiniMapCollisionParcels", false); + if ( ((sShowForSaleParcels) && (for_sale || auction)) || ((sShowCollisionParcels) && (collides)) ) + { + S32 cur_y = llclamp(pos_y, 0, img_height); + S32 end_y = llclamp(pos_y + ll_round(GRID_STEP * mObjectMapTPM), 0, img_height - 1); + for (; cur_y <= end_y; cur_y++) + { + S32 cur_x = llclamp(pos_x, 0, img_width); + S32 end_x = llclamp(pos_x + ll_round(GRID_STEP * mObjectMapTPM), 0, img_width - 1); + for (; cur_x <= end_x; cur_x++) + { + U32 texcolor = LLColor4U(255, 128, 128, 192).mAll; + if (for_sale) + { + texcolor = LLColor4U(255, 255, 128, 192).mAll; + } + else if (auction) + { + texcolor = LLColor4U(128, 0, 255, 102).mAll; + } + + texture_data[cur_y * img_width + cur_x] = texcolor; + } + } + } + if (overlay & PARCEL_SOUTH_LINE) + { + if ( (pos_y >= 0) && (pos_y < img_height) ) + { + S32 cur_x = llclamp(pos_x, 0, img_width); + S32 end_x = llclamp(pos_x + ll_round(GRID_STEP * mObjectMapTPM), 0, img_width - 1); + for (; cur_x <= end_x; cur_x++) + texture_data[pos_y * img_width + cur_x] = overlay_color.mAll; + } + } + if (overlay & PARCEL_WEST_LINE) + { + if ( (pos_x >= 0) && (pos_x < img_width) ) + { + S32 cur_y = llclamp(pos_y, 0, img_height); + S32 end_y = llclamp(pos_y + ll_round(GRID_STEP * mObjectMapTPM), 0, img_height - 1); + for (; cur_y <= end_y; cur_y++) + texture_data[cur_y * img_width + pos_x] = overlay_color.mAll; + } + } + } + } +} + +bool LLNetMap::createImage(LLPointer<LLImageRaw>& rawimagep) const { // Find the size of the side of a square that surrounds the circle that surrounds getRect(). // ... which is, the diagonal of the rect. - F32 width = (F32)getRect().getWidth(); - F32 height = (F32)getRect().getHeight(); + F32 width = getRect().getWidth(); + F32 height = getRect().getHeight(); S32 square_size = ll_round( sqrt(width*width + height*height) ); // Find the least power of two >= the minimum size. const S32 MIN_SIZE = 64; - const S32 MAX_SIZE = 256; + const S32 MAX_SIZE = 512; S32 img_size = MIN_SIZE; while( (img_size*2 < square_size ) && (img_size < MAX_SIZE) ) { img_size <<= 1; } - if( mObjectImagep.isNull() || - (mObjectImagep->getWidth() != img_size) || - (mObjectImagep->getHeight() != img_size) ) + if( rawimagep.isNull() || (rawimagep->getWidth() != img_size) || (rawimagep->getHeight() != img_size) ) { - mObjectRawImagep = new LLImageRaw(img_size, img_size, 4); - U8* data = mObjectRawImagep->getData(); - memset( data, 0, img_size * img_size * 4 ); - mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE); + rawimagep = new LLImageRaw(img_size, img_size, 4); + U8* data = rawimagep->getData(); + memset(data, 0, img_size * img_size * 4); + return true; } - setScale(mScale); - mUpdateNow = true; + return false; +} + +void LLNetMap::createObjectImage() +{ + if (createImage(mObjectRawImagep)) + mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE); + setScale(mScale); + mUpdateObjectImage = true; +} + +void LLNetMap::createParcelImage() +{ + if (createImage(mParcelRawImagep)) + mParcelImagep = LLViewerTextureManager::getLocalTexture( mParcelRawImagep.get(), FALSE); + mUpdateParcelImage = true; } BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask ) @@ -1083,7 +1281,7 @@ void LLNetMap::handleZoom(const LLSD& userdata) } } -void LLNetMap::handleStopTracking (const LLSD& userdata) +void LLNetMap::handleStopTracking(const LLSD& userdata) { auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); if (menu) diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 5471e40dd6..cd1715e601 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -27,7 +27,6 @@ #ifndef LL_LLNETMAP_H #define LL_LLNETMAP_H -#include "llmath.h" #include "lluictrl.h" #include "v3math.h" #include "v3dmath.h" @@ -35,13 +34,12 @@ #include "llpointer.h" #include "llcoord.h" -#include <boost/unordered_map.hpp> - class LLColor4U; class LLImageRaw; class LLViewerTexture; class LLFloaterMap; class LLMenuGL; +class LLViewerRegion; class LLNetMap : public LLUICtrl { @@ -81,12 +79,14 @@ public: /*virtual*/ BOOL handleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask ) override; + void refreshParcelOverlay() { mUpdateParcelImage = true; } + void setScale( F32 scale ); void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius ); private: - const LLVector3d& getObjectImageCenterGlobal() { return mObjectImageCenterGlobal; } + const LLVector3d& getObjectImageCenterGlobal() const { return mObjectImageCenterGlobal; } void renderPoint(const LLVector3 &pos, const LLColor4U &color, S32 diameter, S32 relative_height = 0); @@ -99,12 +99,18 @@ private: BOOL handleToolTipAgent(const LLUUID& avatar_id); static void showAvatarInspector(const LLUUID& avatar_id); + bool createImage(LLPointer<LLImageRaw>& rawimagep) const; void createObjectImage(); + void createParcelImage(); + void renderPropertyLinesForRegion(const LLViewerRegion* pRegion, const LLColor4U& clrOverlay); + static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop); private: bool mUpdateNow; + bool mUpdateObjectImage; + bool mUpdateParcelImage; LLUIColor mBackgroundColor; @@ -124,6 +130,13 @@ private: LLPointer<LLImageRaw> mObjectRawImagep; LLPointer<LLViewerTexture> mObjectImagep; + LLVector3d mParcelImageCenterGlobal; + LLPointer<LLImageRaw> mParcelRawImagep; + LLPointer<LLViewerTexture> mParcelImagep; + + boost::signals2::connection mParcelMgrConn; + boost::signals2::connection mParcelOverlayConn; + LLUUID mClosestAgentToCursor; LLUUID mClosestAgentAtLastRightClick; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index a311d8b880..a4cd0b1f73 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -125,6 +125,8 @@ LLViewerParcelMgr::LLViewerParcelMgr() mRenderSelection(TRUE), mCollisionBanned(0), mCollisionTimer(), + mCollisionRegionHandle(0), + mCollisionUpdateSignal(nullptr), mMediaParcelId(0), mMediaRegionId(0) { @@ -140,6 +142,9 @@ LLViewerParcelMgr::LLViewerParcelMgr() mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; resetSegments(mHighlightSegments); + mCollisionBitmap = new U8[getCollisionBitmapSize()]; + memset(mCollisionBitmap, 0, getCollisionBitmapSize()); + mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; resetSegments(mCollisionSegments); @@ -191,6 +196,9 @@ LLViewerParcelMgr::~LLViewerParcelMgr() delete[] mHighlightSegments; mHighlightSegments = NULL; + delete[] mCollisionBitmap; + mCollisionBitmap = NULL; + delete[] mCollisionSegments; mCollisionSegments = NULL; @@ -226,7 +234,7 @@ void LLViewerParcelMgr::dump() } -LLViewerRegion* LLViewerParcelMgr::getSelectionRegion() +LLViewerRegion* LLViewerParcelMgr::getSelectionRegion() const { return LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); } @@ -1753,13 +1761,22 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use / 8; U8* bitmap = new U8[ bitmap_size ]; msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); + msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, parcel_mgr.mCollisionBitmap, parcel_mgr.getCollisionBitmapSize()); + parcel_mgr.resetSegments(parcel_mgr.mCollisionSegments); parcel_mgr.writeSegmentsFromBitmap( bitmap, parcel_mgr.mCollisionSegments ); + parcel_mgr.writeSegmentsFromBitmap(parcel_mgr.mCollisionBitmap, parcel_mgr.mCollisionSegments); + delete[] bitmap; bitmap = NULL; + LLViewerRegion* pRegion = LLWorld::getInstance()->getRegion(msg->getSender()); + parcel_mgr.mCollisionRegionHandle = (pRegion) ? pRegion->getHandle() : 0; + + if (parcel_mgr.mCollisionUpdateSignal) + (*parcel_mgr.mCollisionUpdateSignal)(pRegion); } else if (sequence_id == HOVERED_PARCEL_SEQ_ID) { @@ -2533,3 +2550,10 @@ void LLViewerParcelMgr::onTeleportFailed() { mTeleportFailedSignal(); } + +boost::signals2::connection LLViewerParcelMgr::setCollisionUpdateCallback(const collision_update_signal_t::slot_type& cb) +{ + if (!mCollisionUpdateSignal) + mCollisionUpdateSignal = new collision_update_signal_t(); + return mCollisionUpdateSignal->connect(cb); +} diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index e14ef06095..98d553f081 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -87,7 +87,7 @@ public: F32 getSelectionWidth() const { return F32(mEastNorth.mdV[VX] - mWestSouth.mdV[VX]); } F32 getSelectionHeight() const { return F32(mEastNorth.mdV[VY] - mWestSouth.mdV[VY]); } BOOL getSelection(LLVector3d &min, LLVector3d &max) { min = mWestSouth; max = mEastNorth; return !selectionEmpty();} - LLViewerRegion* getSelectionRegion(); + LLViewerRegion* getSelectionRegion() const; F32 getDwelling() const { return mSelectedDwell;} void getDisplayInfo(S32* area, S32* claim, S32* rent, BOOL* for_sale, F32* dwell); @@ -163,6 +163,13 @@ public: LLParcel* getCollisionParcel() const; + const U8* getCollisionBitmap() const { return mCollisionBitmap; } + size_t getCollisionBitmapSize() const { return mParcelsPerEdge * mParcelsPerEdge / 8; } + U64 getCollisionRegionHandle() const { return mCollisionRegionHandle; } + + typedef boost::signals2::signal<void (const LLViewerRegion*)> collision_update_signal_t; + boost::signals2::connection setCollisionUpdateCallback(const collision_update_signal_t::slot_type & cb); + // Can this agent build on the parcel he is on? // Used for parcel property icons in nav bar. bool allowAgentBuild() const; @@ -359,6 +366,9 @@ private: // Watch for pending collisions with a parcel you can't access. // If it's coming, draw the parcel's boundaries. LLParcel* mCollisionParcel; + U8* mCollisionBitmap; + U64 mCollisionRegionHandle; + collision_update_signal_t* mCollisionUpdateSignal; U8* mCollisionSegments; BOOL mRenderCollision; BOOL mRenderSelection; diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 98249c8cd6..80107e88fa 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -54,6 +54,8 @@ const U8 OVERLAY_IMG_COMPONENTS = 4; +LLViewerParcelOverlay::update_signal_t* LLViewerParcelOverlay::mUpdateSignal = NULL; + LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters) : mRegion( region ), mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ), @@ -857,6 +859,8 @@ void LLViewerParcelOverlay::idleUpdate(bool force_update) { updateOverlayTexture(); updatePropertyLines(); + if (mUpdateSignal) + (*mUpdateSignal)(mRegion); mTimeSinceLastUpdate.reset(); } } @@ -1006,3 +1010,10 @@ S32 LLViewerParcelOverlay::renderPropertyLines () return drawn; } + +boost::signals2::connection LLViewerParcelOverlay::setUpdateCallback(const update_signal_t::slot_type& cb) +{ + if (!mUpdateSignal) + mUpdateSignal = new update_signal_t(); + return mUpdateSignal->connect(cb); +} diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 7cf08fd926..24c28800d2 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -66,6 +66,7 @@ public: BOOL isBuildCameraAllowed(const LLVector3& pos) const; F32 getOwnedRatio() const; + const U8* getOwnership() const { return mOwnership; } // Returns the number of vertices drawn S32 renderPropertyLines(); @@ -81,6 +82,9 @@ public: void idleUpdate(bool update_now = false); void updateGL() override; + typedef boost::signals2::signal<void (const LLViewerRegion*)> update_signal_t; + static boost::signals2::connection setUpdateCallback(const update_signal_t::slot_type & cb); + private: // This is in parcel rows and columns, not grid rows and columns // Stored in bottom three bits. @@ -120,6 +124,8 @@ private: S32 mVertexCount; F32* mVertexArray; U8* mColorArray; + + static update_signal_t* mUpdateSignal; }; #endif -- GitLab