SH-2170 FIXED Detecting selection of objects that cross parcel bounds added.

In this case the land impacts data is not displayed for such selection.
meow-7.2.2
Seth ProductEngine 2011-08-06 14:28:53 +03:00
parent 1b7b319ae2
commit ef6e51db22
7 changed files with 115 additions and 5 deletions

View File

@ -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");
toggleLandImpactsLoadingIndicators(true);
mSelectedOnLand->setText(text);
mRezzedOnLand->setText(text);
mRemainingCapacity->setText(text);
mTotalCapacity->setText(text);
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);
}
}
}
}

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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 );

View File

@ -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 );