diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index c4eaa57c2c2e38677dd6e2985788260268df3bc4..4f8b29e298279f9840e8598b06d55116f0522c42 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -122,6 +122,8 @@ LLViewerParcelMgr::LLViewerParcelMgr() mHoverWestSouth(), mHoverEastNorth(), mTeleportInProgressPosition(), + mCollisionRegionHandle(0), + mCollisionUpdateSignal(nullptr), mRenderCollision(FALSE), mRenderSelection(TRUE), mCollisionBanned(0), @@ -137,10 +139,13 @@ LLViewerParcelMgr::LLViewerParcelMgr() mHoverParcel = new LLParcel(); mCollisionParcel = new LLParcel(); - mParcelsPerEdge = S32( REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS ); + mParcelsPerEdge = S32(8192.f / PARCEL_GRID_STEP_METERS); // 8192 is the maximum region size on Aurora 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); @@ -160,12 +165,24 @@ LLViewerParcelMgr::LLViewerParcelMgr() mAgentParcelOverlay[i] = 0; } + mParcelsPerEdge = S32(REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS); mTeleportInProgress = TRUE; // the initial parcel update is treated like teleport } +void LLViewerParcelMgr::init(F32 region_size) +{ + mParcelsPerEdge = S32(region_size / PARCEL_GRID_STEP_METERS); +} LLViewerParcelMgr::~LLViewerParcelMgr() { + if (mCollisionUpdateSignal) + { + mCollisionUpdateSignal->disconnect_all_slots(); + delete mCollisionUpdateSignal; + mCollisionUpdateSignal = nullptr; + } + mCurrentParcelSelection->setParcel(NULL); mCurrentParcelSelection = NULL; @@ -187,6 +204,9 @@ LLViewerParcelMgr::~LLViewerParcelMgr() delete[] mHighlightSegments; mHighlightSegments = NULL; + delete[] mCollisionBitmap; + mCollisionBitmap = NULL; + delete[] mCollisionSegments; mCollisionSegments = NULL; @@ -899,7 +919,8 @@ void LLViewerParcelMgr::renderParcelCollision() mRenderCollision = FALSE; } - if (mRenderCollision && gSavedSettings.getBOOL("ShowBanLines")) + static LLCachedControl<bool> render_ban_line(gSavedSettings, "ShowBanLines"); + if (mRenderCollision && render_ban_line) { LLViewerRegion* regionp = gAgent.getRegion(); if (regionp) @@ -1490,8 +1511,7 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user) return; } - S32 parcels_per_edge = LLViewerParcelMgr::getInstance()->mParcelsPerEdge; - S32 expected_size = parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS; + S32 expected_size = 1024; if (packed_overlay_size != expected_size) { LL_WARNS() << "Got parcel overlay size " << packed_overlay_size @@ -1558,6 +1578,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use S32 other_clean_time = 0; LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance(); + LLViewerRegion* msg_region = LLWorld::getInstance()->getRegion(msg->getSender()); + if(msg_region) + parcel_mgr.mParcelsPerEdge = S32(msg_region->getWidth() / PARCEL_GRID_STEP_METERS); + else + parcel_mgr.mParcelsPerEdge = S32(gAgent.getRegion()->getWidth() / PARCEL_GRID_STEP_METERS); msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result); msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id); @@ -1853,18 +1878,16 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } - S32 bitmap_size = parcel_mgr.mParcelsPerEdge - * parcel_mgr.mParcelsPerEdge - / 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) { @@ -2691,6 +2714,13 @@ bool LLViewerParcelMgr::getTeleportInProgress() || gAgent.getTeleportState() > LLAgent::TELEPORT_NONE; // For LOCAL, no mTeleportInProgress } +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); +} + // [SL:KB] - Patch: Appearance-TeleportAttachKill | Checked: Catznip-4.0 void LLViewerParcelMgr::onTeleportDone() { diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 0260aabbed0ccaea613db0b7ad83972bbded70d8..e93a80d3ad3aa3c4ca1078f981f155ad4c7e63ab 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -73,7 +73,7 @@ class LLParcelObserver virtual void changed() = 0; }; -class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> +class LLViewerParcelMgr final : public LLSingleton<LLViewerParcelMgr> { LLSINGLETON(LLViewerParcelMgr); ~LLViewerParcelMgr(); @@ -88,6 +88,7 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> typedef boost::signals2::signal<void()> teleport_done_signal_t; // [/SL:KB] + void init(F32 region_size); static void cleanupGlobals(); BOOL selectionEmpty() const; @@ -167,6 +168,13 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> 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; @@ -373,6 +381,9 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> // 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 89124ff207faaf53069556f783ba813668f941fc..922e0df8feb432b1702bddc7db5da26a6a4ea6cb 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -52,15 +52,18 @@ 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 ) ), + mRegionSize(S32(region_width_meters)), mDirty( FALSE ), mTimeSinceLastUpdate(), mOverlayTextureIdx(-1), mVertexCount(0), - mVertexArray(NULL), - mColorArray(NULL) + mVertexArray(nullptr), + mColorArray(nullptr) // mTexCoordArray(NULL), { // Create a texture to hold color information. @@ -81,7 +84,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ { raw[i] = 0; } - //mTexture->setSubImage(mImageRaw, 0, 0, mParcelGridsPerEdge, mParcelGridsPerEdge); + mTexture->setSubImage(mImageRaw, 0, 0, mParcelGridsPerEdge, mParcelGridsPerEdge); // Create storage for ownership information from simulator // and initialize it. @@ -97,6 +100,13 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ LLViewerParcelOverlay::~LLViewerParcelOverlay() { + if (mUpdateSignal) + { + mUpdateSignal->disconnect_all_slots(); + delete mUpdateSignal; + mUpdateSignal = nullptr; + } + delete[] mOwnership; mOwnership = NULL; @@ -426,7 +436,8 @@ void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8 *packed_overlay) { // Unpack the message data into the ownership array S32 size = mParcelGridsPerEdge * mParcelGridsPerEdge; - S32 chunk_size = size / PARCEL_OVERLAY_CHUNKS; + S32 mParcelOverLayChunks = mRegionSize * mRegionSize / (128 * 128); + S32 chunk_size = size / mParcelOverLayChunks; memcpy(mOwnership + chunk*chunk_size, packed_overlay, chunk_size); /*Flawfinder: ignore*/ @@ -870,6 +881,8 @@ void LLViewerParcelOverlay::idleUpdate(bool force_update) { updateOverlayTexture(); updatePropertyLines(); + if (mUpdateSignal) + (*mUpdateSignal)(mRegion); mTimeSinceLastUpdate.reset(); } } @@ -1019,3 +1032,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 e30dbf17b3ee01ce867e4979f2c324e1dc7ab2fc..922548744bf0df2b6be88ab43b0bf5b480a16665 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -41,7 +41,7 @@ class LLVector3; class LLColor4U; class LLVector2; -class LLViewerParcelOverlay : public LLGLUpdate +class LLViewerParcelOverlay final : public LLGLUpdate { public: LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters); @@ -66,6 +66,7 @@ class LLViewerParcelOverlay : public LLGLUpdate BOOL isBuildCameraAllowed(const LLVector3& pos) const; F32 getOwnedRatio() const; + const U8* getOwnership() const { return mOwnership; } // Returns the number of vertices drawn S32 renderPropertyLines(); @@ -81,7 +82,10 @@ class LLViewerParcelOverlay : public LLGLUpdate void setDirty(); void idleUpdate(bool update_now = false); - void updateGL(); + 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 @@ -104,6 +108,7 @@ class LLViewerParcelOverlay : public LLGLUpdate LLViewerRegion* mRegion; S32 mParcelGridsPerEdge; + S32 mRegionSize; LLPointer<LLViewerTexture> mTexture; LLPointer<LLImageRaw> mImageRaw; @@ -121,6 +126,8 @@ class LLViewerParcelOverlay : public LLGLUpdate S32 mVertexCount; F32* mVertexArray; U8* mColorArray; + + static update_signal_t* mUpdateSignal; }; #endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 54fe1cdf23f6dd2060d26e0007823587eaf511bd..60c616e9209833f7ee1bf75a495c7250572b9ad6 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -81,6 +81,7 @@ #include "llcorehttputil.h" #include "llcallstack.h" #include "llsettingsdaycycle.h" +#include "llviewerparcelmgr.h" #ifdef LL_WINDOWS #pragma warning(disable:4355) @@ -590,7 +591,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mImpl->mOriginGlobal, mWidth); - mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters); + mParcelOverlay = new LLViewerParcelOverlay(this, mWidth); + LLViewerParcelMgr::getInstance()->init(mWidth); setOriginGlobal(from_region_handle(handle)); calculateCenterGlobal();