Variable Size Regions! Support for prehash RegionSizeX and large patches. (WIP)

Mostly from Ukando, tweaked a bit to be cleaner, and a little less dramatic.

decode_patch_header now takes a bool optionally, as third argument.
_PREHASH_RegionSizeX is the only used of the two _PREHASH_RegionSize*.
llsurface.cpp: Copy the connectNeighbor for variable size regions almost directly from Ukando
llsurfacepatch.cpp: Patch code from ukando and voodoo.
Changed hardcoded 256 constants and such to width functions in: llglsandbox.cpp, llsurface.cpp, llviewerregion.cpp, llviewerparcelmanager, llviewerparcelmgr.cpp, llvowater.cpp, llworld.cpp
Use region specific width in: llagent.cpp, llglsandbox.cpp, llmanip.cpp, llmanipscale.cpp, llpanelobject.cpp, llviewerbject.cpp, llwind.cpp
Use 256 in llnetmap.cpp in places...
llfloaterregioninfo.cpp: Aurora grid has wacky textures.
Add LLViewerParcelMgr::widthUpdate() for updating mParcelsPerEdge given a region's width. Used in llstartup now.
Add LLWorld::setWidth() for getting a region's size from LLMessageSystem pointers and setting mWidth and mWidthInMeters, accordingly. Called in llviewermessage.cpp as well.
This commit is contained in:
Lirusaito
2013-01-03 05:57:55 -05:00
parent 728056acdb
commit a50f0008b2
27 changed files with 323 additions and 143 deletions

View File

@@ -81,12 +81,12 @@ const S32 WORLD_PATCH_SIZE = 16;
extern LLColor4U MAX_WATER_COLOR;
const U32 LLWorld::mWidth = 256;
U32 LLWorld::mWidth = 256;
// meters/point, therefore mWidth * mScale = meters per edge
const F32 LLWorld::mScale = 1.f;
const F32 LLWorld::mWidthInMeters = mWidth * mScale;
F32 LLWorld::mWidthInMeters = mWidth * mScale;
//
// Functions
@@ -146,6 +146,18 @@ void LLWorld::destroyClass()
}
}
void LLWorld::setRegionWidth(LLMessageSystem* msg)
{
U32 width;
msg->getU32Fast(_PREHASH_SimulatorInfo, _PREHASH_RegionSizeX, width);
setRegionWidth(width);
}
void LLWorld::setRegionWidth(const U32 width)
{
mWidth = width ? width : 256; // Width of 0 is really 256
mWidthInMeters = mWidth * mScale;
}
LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
{
@@ -181,8 +193,8 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
U32 iindex = 0;
U32 jindex = 0;
from_region_handle(region_handle, &iindex, &jindex);
S32 x = (S32)(iindex/mWidth);
S32 y = (S32)(jindex/mWidth);
S32 x = (S32)(iindex/256);
S32 y = (S32)(jindex/256);
llinfos << "Adding new region (" << x << ":" << y << ")" << llendl;
llinfos << "Host: " << host << llendl;
@@ -232,13 +244,40 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
{
adj_x = region_x + width * gDirAxes[dir][0];
adj_y = region_y + width * gDirAxes[dir][1];
to_region_handle(adj_x, adj_y, &adj_handle);
neighborp = getRegionFromHandle(adj_handle);
if (neighborp)
if (mWidth == 256)
{
//llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl;
regionp->connectNeighbor(neighborp, dir);
to_region_handle(adj_x, adj_y, &adj_handle);
neighborp = getRegionFromHandle(adj_handle);
if (neighborp)
{
//llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl;
regionp->connectNeighbor(neighborp, dir);
}
}
else // Unconventional region size
{
LLViewerRegion* last_neighborp = NULL;
if(gDirAxes[dir][0] < 0) adj_x = region_x - WORLD_PATCH_SIZE;
if(gDirAxes[dir][1] < 0) adj_y = region_y - WORLD_PATCH_SIZE;
for (S32 offset = 0; offset < width; offset += WORLD_PATCH_SIZE)
{
to_region_handle(adj_x, adj_y, &adj_handle);
neighborp = getRegionFromHandle(adj_handle);
if (neighborp && last_neighborp != neighborp)
{
regionp->connectNeighbor(neighborp, dir);
last_neighborp = neighborp;
}
if (dir == NORTHEAST || dir == NORTHWEST || dir == SOUTHWEST || dir == SOUTHEAST)
break;
if (dir == NORTH || dir == SOUTH) adj_x += WORLD_PATCH_SIZE;
if (dir == EAST || dir == WEST) adj_y += WORLD_PATCH_SIZE;
}
}
}
@@ -409,11 +448,19 @@ LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVe
LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
{
U32 x, y;
from_region_handle(handle, &x, &y);
for (region_list_t::iterator iter = mRegionList.begin();
iter != mRegionList.end(); ++iter)
{
LLViewerRegion* regionp = *iter;
if (regionp->getHandle() == handle)
U32 checkRegionX, checkRegionY;
F32 checkRegionWidth = regionp->getWidth();
from_region_handle(regionp->getHandle(), &checkRegionX, &checkRegionY);
if (x >= checkRegionX && x < (checkRegionX + checkRegionWidth) &&
y >= checkRegionY && y < (checkRegionY + checkRegionWidth))
{
return regionp;
}
@@ -840,7 +887,7 @@ F32 LLWorld::getLandFarClip() const
void LLWorld::setLandFarClip(const F32 far_clip)
{
static S32 const rwidth = (S32)REGION_WIDTH_U32;
static S32 const rwidth = (S32)getRegionWidthInMeters();
S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;
S32 const n2 = (llceil(far_clip) - 1) / rwidth;
bool need_water_objects_update = n1 != n2;
@@ -915,8 +962,10 @@ void LLWorld::updateWaterObjects()
return;
}
LLViewerRegion const* regionp = gAgent.getRegion();
// Region width in meters.
S32 const rwidth = (S32)REGION_WIDTH_U32;
S32 const rwidth = (S32)regionp->getWidth();
// The distance we might see into the void
// when standing on the edge of a region, in meters.
@@ -933,15 +982,14 @@ void LLWorld::updateWaterObjects()
S32 const range = nsims * rwidth;
// Get South-West corner of current region.
LLViewerRegion const* regionp = gAgent.getRegion();
U32 region_x, region_y;
from_region_handle(regionp->getHandle(), &region_x, &region_y);
// The min. and max. coordinates of the South-West corners of the Hole water objects.
S32 const min_x = (S32)region_x - range;
S32 const min_y = (S32)region_y - range;
S32 const max_x = (S32)region_x + range;
S32 const max_y = (S32)region_y + range;
S32 const max_x = (S32)region_x + rwidth-256 + range;
S32 const max_y = (S32)region_y + rwidth-256 + range;
// Attempt to determine a sensible water height for all the
// Hole Water objects.
@@ -1120,19 +1168,19 @@ void LLWorld::updateWaterObjects()
// the current regions water height.
F32 const box_height = 1024;
F32 const water_center_z = water_height + box_height / 2;
const S32 step = 256;
// Create new Hole water objects within 'range' where there is no region.
for (S32 x = min_x; x <= max_x; x += rwidth)
for (S32 x = min_x; x <= max_x; x += step)
{
for (S32 y = min_y; y <= max_y; y += rwidth)
for (S32 y = min_y; y <= max_y; y += step)
{
U64 region_handle = to_region_handle(x, y);
if (!getRegionFromHandle(region_handle))
{
LLVOWater* waterp = (LLVOWater*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion());
waterp->setUseTexture(FALSE);
waterp->setPositionGlobal(LLVector3d(x + rwidth / 2, y + rwidth / 2, water_center_z));
waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, box_height));
waterp->setPositionGlobal(LLVector3d(x + step / 2, y + step / 2, water_center_z));
waterp->setScale(LLVector3((F32)step, (F32)step, box_height));
gPipeline.createObject(waterp);
mHoleWaterObjects.push_back(waterp);
}
@@ -1140,10 +1188,10 @@ void LLWorld::updateWaterObjects()
}
// Center of the region.
S32 const center_x = region_x + rwidth / 2;
S32 const center_y = region_y + rwidth / 2;
S32 const center_x = region_x + step / 2;
S32 const center_y = region_y + step / 2;
// Width of the area with Hole water objects.
S32 const width = rwidth + 2 * range;
S32 const width = step + 2 * range;
S32 const horizon_extend = 2048 + 512 - range; // Legacy value.
// The overlap is needed to get rid of sky pixels being visible between the
// Edge and Hole water object at greater distances (due to floating point
@@ -1272,6 +1320,8 @@ void process_enable_simulator(LLMessageSystem *msg, void **user_data)
// which simulator should we modify?
LLHost sim(ip_u32, port);
LLWorld::getInstance()->setRegionWidth(msg);
// Viewer trusts the simulator.
msg->enableCircuit(sim, TRUE);
LLWorld::getInstance()->addRegion(handle, sim);