diff options
-rw-r--r-- | indra/newview/llfloaterobjectweights.cpp | 36 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 4 | ||||
-rw-r--r-- | indra/newview/llviewerparceloverlay.cpp | 59 | ||||
-rw-r--r-- | indra/newview/llviewerparceloverlay.h | 1 | ||||
-rw-r--r-- | indra/newview/llviewerregion.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llviewerregion.h | 1 |
7 files changed, 115 insertions, 5 deletions
diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp index 80a753757e..d39a93991f 100644 --- a/indra/newview/llfloaterobjectweights.cpp +++ b/indra/newview/llfloaterobjectweights.cpp @@ -34,6 +34,15 @@ #include "llselectmgr.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" + +struct LLCrossParcelFunctor : public LLSelectedObjectFunctor +{ + /*virtual*/ bool apply(LLViewerObject* obj) + { + return obj->crossesParcelBounds(); + } +}; /** * Class LLLandImpactsObserver @@ -159,13 +168,30 @@ void LLFloaterObjectWeights::refresh() mSelectedObjects->setText(llformat("%d", link_count)); mSelectedPrims->setText(llformat("%d", prim_count)); - LLViewerObject* selected_object = mObjectSelection->getPrimaryObject(); - if (selected_object) + LLCrossParcelFunctor func; + if (LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true)) { - // Select a parcel at the currently selected object's position. - LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal()); + // Some of the selected objects cross parcel bounds. + // We don't display land impacts in this case. + const std::string text = getString("nothing_selected"); + + mSelectedOnLand->setText(text); + mRezzedOnLand->setText(text); + mRemainingCapacity->setText(text); + mTotalCapacity->setText(text); - toggleLandImpactsLoadingIndicators(true); + toggleLandImpactsLoadingIndicators(false); + } + else + { + LLViewerObject* selected_object = mObjectSelection->getFirstObject(); + if (selected_object) + { + // Select a parcel at the currently selected object's position. + LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal()); + + toggleLandImpactsLoadingIndicators(true); + } } } } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b5fdca632b..34c73ee739 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -628,6 +628,20 @@ void LLViewerObject::constructAndAddReturnable( std::vector<PotentialReturnableO } } +bool LLViewerObject::crossesParcelBounds() +{ + std::vector<LLBBox> boxes; + boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned()); + for (child_list_t::iterator iter = mChildList.begin(); + iter != mChildList.end(); iter++) + { + LLViewerObject* child = *iter; + boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); + } + + return mRegionp && mRegionp->objectsCrossParcel(boxes); +} + BOOL LLViewerObject::setParent(LLViewerObject* parent) { if(mParent != parent) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 1828a64917..f27b825bbe 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -243,6 +243,10 @@ public: void buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); void constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); + // This method returns true if the object crosses + // any parcel bounds in the region. + bool crossesParcelBounds(); + /* // This method will scan through this object, and then query the // selection manager to see if the local agent probably has the diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index eff16b6a6e..e619b89f9b 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -201,6 +201,65 @@ bool LLViewerParcelOverlay::encroachesOnUnowned(const std::vector<LLBBox>& boxes return false; } +bool LLViewerParcelOverlay::encroachesOnNearbyParcel(const std::vector<LLBBox>& boxes) const +{ + // boxes are expected to already be axis aligned + for (U32 i = 0; i < boxes.size(); ++i) + { + LLVector3 min = boxes[i].getMinAgent(); + LLVector3 max = boxes[i].getMaxAgent(); + + // If an object crosses region borders it crosses a parcel + if ( min.mV[VX] < 0 + || min.mV[VY] < 0 + || max.mV[VX] > REGION_WIDTH_METERS + || max.mV[VY] > REGION_WIDTH_METERS) + { + return true; + } + + S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 bottom = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 top = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + + const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; + + for (S32 row = bottom; row <= top; row++) + { + for (S32 col = left; col <= right; col++) + { + // This is not the rightmost column + if (col < GRIDS_PER_EDGE-1) + { + U8 east_overlay = mOwnership[row*GRIDS_PER_EDGE+col+1]; + // If the column to the east of the current one marks + // the other parcel's west edge and the box extends + // to the west it crosses the parcel border. + if ((east_overlay & PARCEL_WEST_LINE) && col < right) + { + return true; + } + } + + // This is not the topmost column + if (row < GRIDS_PER_EDGE-1) + { + U8 north_overlay = mOwnership[(row+1)*GRIDS_PER_EDGE+col]; + // If the row to the north of the current one marks + // the other parcel's south edge and the box extends + // to the south it crosses the parcel border. + if ((north_overlay & PARCEL_SOUTH_LINE) && row < top) + { + return true; + } + } + } + } + } + return false; +} + BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const { S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS); diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 3c6794e7d0..7445d5bf1d 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -61,6 +61,7 @@ public: // bounding boxes which isn't perfect, but is close bool encroachesOwned(const std::vector<LLBBox>& boxes) const; bool encroachesOnUnowned(const std::vector<LLBBox>& boxes) const; + bool encroachesOnNearbyParcel(const std::vector<LLBBox>& boxes) const; BOOL isSoundLocal(const LLVector3& pos) const; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 5be2234ec2..7ebfcc2b5a 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1784,6 +1784,11 @@ bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes return result; } +bool LLViewerRegion::objectsCrossParcel(const std::vector<LLBBox>& boxes) const +{ + return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes); +} + void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ) { mImpl->mLandp->getNeighboringRegions( uniqueRegions ); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b3c19ea58d..c86c30b93c 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -322,6 +322,7 @@ public: bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const; bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const; + bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const; void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); |