Merge branch 'master' of git://github.com/Shyotl/SingularityViewer

# Conflicts:
#	indra/llmath/lloctree.h
#	indra/newview/llsurface.cpp
This commit is contained in:
Liru Færs
2020-03-01 03:39:30 -05:00
15 changed files with 393 additions and 585 deletions

View File

@@ -537,7 +537,7 @@ public:
OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif #endif
this->notifyAddition(data); LLOctreeNode<T>::notifyAddition(data);
return true; return true;
} }
else else
@@ -593,7 +593,7 @@ public:
OctreeStats::getInstance()->realloc(old_cap,mData.capacity()); OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif #endif
this->notifyAddition(data); LLOctreeNode<T>::notifyAddition(data);
return true; return true;
} }

View File

@@ -1149,6 +1149,7 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
//must be an active volume //must be an active volume
if (!mSpatialBridge) if (!mSpatialBridge)
{ {
// Spatial bridge ctors self-register...
if (mVObjp->isHUDAttachment()) if (mVObjp->isHUDAttachment())
{ {
setSpatialBridge(new LLHUDBridge(this, getRegion())); setSpatialBridge(new LLHUDBridge(this, getRegion()));
@@ -1615,9 +1616,9 @@ void LLSpatialBridge::cleanupReferences()
} }
}*/ }*/
LLDrawable* drawablep = mDrawable; LLPointer<LLDrawable> drawablep = mDrawable;
mDrawable = NULL; mDrawable = nullptr;
drawablep->setSpatialBridge(NULL); drawablep->setSpatialBridge(nullptr);
} }
} }

View File

@@ -71,7 +71,6 @@ LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
mGridsPerEdge(0), mGridsPerEdge(0),
mOOGridsPerEdge(0.f), mOOGridsPerEdge(0.f),
mPatchesPerEdge(0), mPatchesPerEdge(0),
mNumberOfPatches(0),
mType(type), mType(type),
mDetailTextureScale(0.f), mDetailTextureScale(0.f),
mOriginGlobal(0.0, 0.0, 0.0), mOriginGlobal(0.0, 0.0, 0.0),
@@ -86,9 +85,6 @@ LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
mSurfaceZ = NULL; mSurfaceZ = NULL;
mNorm = NULL; mNorm = NULL;
// Patch data
mPatchList = NULL;
// One of each for each camera // One of each for each camera
mVisiblePatchCount = 0; mVisiblePatchCount = 0;
@@ -119,7 +115,6 @@ LLSurface::~LLSurface()
mGridsPerEdge = 0; mGridsPerEdge = 0;
mGridsPerPatchEdge = 0; mGridsPerPatchEdge = 0;
mPatchesPerEdge = 0; mPatchesPerEdge = 0;
mNumberOfPatches = 0;
destroyPatchData(); destroyPatchData();
LLDrawPoolTerrain *poolp = (LLDrawPoolTerrain*) gPipeline.findPool(LLDrawPool::POOL_TERRAIN, mSTexturep); LLDrawPoolTerrain *poolp = (LLDrawPoolTerrain*) gPipeline.findPool(LLDrawPool::POOL_TERRAIN, mSTexturep);
@@ -168,7 +163,6 @@ void LLSurface::create(const S32 grids_per_edge,
mOOGridsPerEdge = 1.f / mGridsPerEdge; mOOGridsPerEdge = 1.f / mGridsPerEdge;
mGridsPerPatchEdge = grids_per_patch_edge; mGridsPerPatchEdge = grids_per_patch_edge;
mPatchesPerEdge = grids_per_edge / mGridsPerPatchEdge; mPatchesPerEdge = grids_per_edge / mGridsPerPatchEdge;
mNumberOfPatches = mPatchesPerEdge * mPatchesPerEdge;
mMetersPerGrid = width / (F32)grids_per_edge; mMetersPerGrid = width / (F32)grids_per_edge;
mMetersPerEdge = mMetersPerGrid * grids_per_edge; mMetersPerEdge = mMetersPerGrid * grids_per_edge;
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
@@ -310,14 +304,13 @@ void LLSurface::setOriginGlobal(const LLVector3d &origin_global)
{ {
LLVector3d new_origin_global; LLVector3d new_origin_global;
mOriginGlobal = origin_global; mOriginGlobal = origin_global;
LLSurfacePatch *patchp;
S32 i, j; S32 i, j;
// Need to update the southwest corners of the patches // Need to update the southwest corners of the patches
for (j=0; j<mPatchesPerEdge; j++) for (j=0; j<mPatchesPerEdge; j++)
{ {
for (i=0; i<mPatchesPerEdge; i++) for (i=0; i<mPatchesPerEdge; i++)
{ {
patchp = getPatch(i, j); const auto& patchp = getPatch(i, j);
new_origin_global = patchp->getOriginGlobal(); new_origin_global = patchp->getOriginGlobal();
@@ -369,353 +362,122 @@ void LLSurface::getNeighboringRegionsStatus( std::vector<S32>& regions )
} }
} }
void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) void LLSurface::connectNeighbor(LLSurface* neighborp, U32 direction)
{ {
S32 i; // Constraints:
LLSurfacePatch *patchp, *neighbor_patchp; // - Regions width must equal height
// <FS:CR> Aurora Sim // - Region width divisible by mGridsPerPatchEdge (16)
S32 neighborPatchesPerEdge = neighborp->mPatchesPerEdge; // - Region can only neighbor one other per side and coner (8 total, N, S, E, W, NW, NE, SW, SE)
// </FS:CR> Aurora Sim // - Non-power-of-2 regions should work here, but the rest of the viewer code will probably choke on them.
surface_patch_ref patchp, neighbor_patchp;
mNeighbors[direction] = neighborp; mNeighbors[direction] = neighborp;
neighborp->mNeighbors[gDirOpposite[direction]] = this;
// <FS:CR> Aurora Sim const S32 max_idx = mPatchesPerEdge - 1;
S32 ppe[2]; const S32 neighbor_max_idx = neighborp->mPatchesPerEdge - 1;
S32 own_offset[2] = {0, 0};
S32 neighbor_offset[2] = {0, 0};
U32 own_xpos, own_ypos, neighbor_xpos, neighbor_ypos;
ppe[0] = (mPatchesPerEdge < neighborPatchesPerEdge) ? mPatchesPerEdge : neighborPatchesPerEdge; // used for x
ppe[1] = ppe[0]; // used for y
from_region_handle(mRegionp->getHandle(), &own_xpos, &own_ypos);
from_region_handle(neighborp->getRegion()->getHandle(), &neighbor_xpos, &neighbor_ypos);
if(own_ypos >= neighbor_ypos)
{
neighbor_offset[1] = (own_ypos - neighbor_ypos) / mGridsPerPatchEdge;
ppe[1] = llmin(mPatchesPerEdge, neighborPatchesPerEdge-neighbor_offset[1]);
}
else
{
own_offset[1] = (neighbor_ypos - own_ypos) / mGridsPerPatchEdge;
ppe[1] = llmin(mPatchesPerEdge-own_offset[1], neighborPatchesPerEdge);
}
if(own_xpos >= neighbor_xpos)
{
neighbor_offset[0] = (own_xpos - neighbor_xpos) / mGridsPerPatchEdge;
ppe[0] = llmin(mPatchesPerEdge, neighborPatchesPerEdge-neighbor_offset[0]);
}
else
{
own_offset[0] = (neighbor_xpos - own_xpos) / mGridsPerPatchEdge;
ppe[0] = llmin(mPatchesPerEdge-own_offset[0], neighborPatchesPerEdge);
}
// <FS:CR> Aurora Sim
// Connect patches // Connect patches
if (NORTHEAST == direction) if (direction >= 4)
{ {
patchp = getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1); // Corner stitch
// <FS:CR> Aurora Sim S32 patches[4][2] = {
//neighbor_patchp = neighborp->getPatch(0, 0); {max_idx, max_idx}, //NORTHEAST
neighbor_patchp = neighborp->getPatch(neighbor_offset[0], neighbor_offset[1]); {0, max_idx}, //NORTHWEST
// </FS:CR> Aurora Sim {0, 0}, //SOUTHWEST
{max_idx, 0}, //SOUTHEAST
patchp->connectNeighbor(neighbor_patchp, direction); };
neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); const S32* p = patches[direction - 4];
surface_patch_ref patchp = getPatch(p[0], p[1]);
patchp->updateNorthEdge(); // Only update one of north or east. patchp->connectNeighbor(neighborp->getPatch(max_idx - p[0], max_idx - p[1]), direction);
patchp->dirtyZ(); if (NORTHEAST == direction)
} {
else if (NORTHWEST == direction) patchp->updateNorthEdge(); // Only update one of north or east.
if (patchp->dirtyZ())
{
dirtySurfacePatch(patchp);
}
}
}
else
{ {
// <FS:CR> Aurora Sim // Edge stitch
S32 off = mPatchesPerEdge + neighbor_offset[1] - own_offset[1]; // Aurora complicates this logic.
// </FS:CR> Aurora Sim U32 pos[2][2] = { {0,0},{0,0} };
patchp = getPatch(0, mPatchesPerEdge - 1); from_region_handle(mRegionp->getHandle(), &pos[0][0], &pos[0][1]);
// <FS:CR> Aurora Sim from_region_handle(neighborp->getRegion()->getHandle(), &pos[1][0], &pos[1][1]);
//neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, 0); S32 width[2] = { (S32)mRegionp->getWidth(), (S32)neighborp->getRegion()->getWidth() };
neighbor_patchp = neighborp->getPatch(neighbor_offset[0] - 1, off); //neighborPatchesPerEdge - 1 U32 mins[2] = { llmax(pos[0][0], pos[1][0]), llmax(pos[0][1], pos[1][1]) };
if (!neighbor_patchp) U32 maxs[2] = { llmin(pos[0][0] + width[0], pos[1][0] + width[1]), llmin(pos[0][1] + width[0], pos[1][1] + width[1]) };
S32 start[2][2] = {
{S32((mins[0] - pos[0][0]) / mGridsPerPatchEdge) - 1, S32((mins[1] - pos[0][1]) / mGridsPerPatchEdge) - 1},
{S32((mins[0] - pos[1][0]) / neighborp->mGridsPerPatchEdge) - 1,S32((mins[1] - pos[1][1]) / neighborp->mGridsPerPatchEdge) - 1}
};
S32 end[2] = { llmin(S32((maxs[0] - pos[0][0]) / mGridsPerPatchEdge), max_idx), llmin(S32((maxs[1] - pos[0][1]) / mGridsPerPatchEdge), max_idx) };
const U32& neighbor_direction = gDirOpposite[direction];
S32 stride[4][4][2] = {
{{0, 1}, {max_idx, 0}, {neighbor_max_idx, 0}, {NORTHEAST, SOUTHEAST}}, //EAST
{{1, 0}, {0, max_idx}, {0, neighbor_max_idx}, {NORTHEAST, NORTHWEST} }, //NORTH
{{0, 1}, {0, 0}, {0, 0}, {NORTHWEST, SOUTHWEST}}, //WEST
{{1, 0}, {0, 0}, {0, 0}, {SOUTHEAST, SOUTHWEST}} //SOUTH
};
const S32 offs[2][2] = {
{stride[direction][0][0], stride[direction][0][1]},
{stride[neighbor_direction][0][0], stride[neighbor_direction][0][1]}
};
S32 x[2], y[2];
x[0] = stride[direction][1][0] + offs[0][0] * start[0][0];
y[0] = stride[direction][1][1] + offs[0][1] * start[0][1];
x[1] = stride[neighbor_direction][2][0] + offs[1][0] * start[1][0];
y[1] = stride[neighbor_direction][2][1] + offs[1][1] * start[1][1];
for (
x[0] = stride[direction][1][0] + offs[0][0] * start[0][0],
y[0] = stride[direction][1][1] + offs[0][1] * start[0][1],
x[1] = stride[neighbor_direction][2][0] + offs[1][0] * start[1][0],
y[1] = stride[neighbor_direction][2][1] + offs[1][1] * start[1][1];
(!offs[0][0] || x[0] <= end[0]) && (!offs[0][1] || (y[0] <= end[1]));
x[0] += offs[0][0], y[0] += offs[0][1],
x[1] += offs[1][0], y[1] += offs[1][1])
{ {
mNeighbors[direction] = NULL; if (x[0] < 0 || y[0] < 0) {
return; continue;
} }
// </FS:CR> Aurora Sim surface_patch_ref patchp = getPatch(x[0], y[0]);
// diagonal stitch 1
patchp->connectNeighbor(neighbor_patchp, direction); if ((offs[1][0] > 0 && x[1] > 0) || (offs[1][1] > 0 && y[1] > 0))
neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); {
} patchp->connectNeighbor(neighborp->getPatch(x[1] - offs[1][0], y[1] - offs[1][1]), stride[direction][3][1]);
else if (SOUTHWEST == direction) }
{ // edge stitch
patchp = getPatch(0, 0); if (x[1] >= 0 && y[1] >= 0 && x[1] <= neighbor_max_idx && y[1] <= neighbor_max_idx)
// <FS:CR> Aurora Sim {
//neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1); patchp->connectNeighbor(neighborp->getPatch(x[1], y[1]), direction);
neighbor_patchp = neighborp->getPatch(neighbor_offset[0] - 1, neighbor_offset[1] - 1); }
if (!neighbor_patchp) // diagonal stitch 2
{ if (x[1] + offs[1][0] <= neighbor_max_idx && y[1] + offs[1][1] <= neighbor_max_idx)
mNeighbors[direction] = NULL; {
return; patchp->connectNeighbor(neighborp->getPatch(x[1] + offs[1][0], y[1] + offs[1][1]), stride[direction][3][0]);
} }
// </FS:CR> Aurora Sim if (direction == EAST)
{
patchp->connectNeighbor(neighbor_patchp, direction); patchp->updateEastEdge();
neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); if (patchp->dirtyZ())
{
// <FS:CR> Aurora Sim dirtySurfacePatch(patchp);
//neighbor_patchp->updateNorthEdge(); // Only update one of north or east. }
neighbor_patchp->updateEastEdge(); // Only update one of north or east. }
// </FS:CR> Aurora Sim else if (direction == NORTH)
neighbor_patchp->dirtyZ(); {
} patchp->updateNorthEdge();
else if (SOUTHEAST == direction) if (patchp->dirtyZ())
{ {
// <FS:CR> Aurora Sim dirtySurfacePatch(patchp);
S32 off = mPatchesPerEdge + neighbor_offset[0] - own_offset[0]; }
// </FS:CR> Aurora Sim }
patchp = getPatch(mPatchesPerEdge - 1, 0);
// <FS:CR> Aurora Sim
//neighbor_patchp = neighborp->getPatch(0, mPatchesPerEdge - 1);
neighbor_patchp = neighborp->getPatch(off, neighbor_offset[1] - 1); //0
if (!neighbor_patchp)
{
mNeighbors[direction] = NULL;
return;
}
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, direction);
neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
}
else if (EAST == direction)
{
// Do east/west connections, first
// <FS:CR> Aurora Sim
//for (i = 0; i < (S32)mPatchesPerEdge; i++)
for (i = 0; i < ppe[1]; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(mPatchesPerEdge - 1, i);
//neighbor_patchp = neighborp->getPatch(0, i);
patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]);
neighbor_patchp = neighborp->getPatch(0, i + neighbor_offset[1]);
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, direction);
neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
patchp->updateEastEdge();
patchp->dirtyZ();
}
// Now do northeast/southwest connections
// <FS:CR> Aurora Sim
//for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
for (i = 0; i < ppe[1] - 1; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(mPatchesPerEdge - 1, i);
//neighbor_patchp = neighborp->getPatch(0, i+1);
patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]);
neighbor_patchp = neighborp->getPatch(0, i+1 + neighbor_offset[1]);
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
}
// Now do southeast/northwest connections
// <FS:CR> Aurora Sim
//for (i = 1; i < (S32)mPatchesPerEdge; i++)
for (i = 1; i < ppe[1]; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(mPatchesPerEdge - 1, i);
//neighbor_patchp = neighborp->getPatch(0, i-1);
patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]);
neighbor_patchp = neighborp->getPatch(0, i-1 + neighbor_offset[1]);
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
} }
} }
else if (NORTH == direction)
{
// Do north/south connections, first
// <FS:CR> Aurora Sim
//for (i = 0; i < (S32)mPatchesPerEdge; i++)
for (i = 0; i < ppe[0]; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(i, mPatchesPerEdge - 1);
//neighbor_patchp = neighborp->getPatch(i, 0);
patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1);
neighbor_patchp = neighborp->getPatch(i + neighbor_offset[0], 0);
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, direction);
neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
patchp->updateNorthEdge();
patchp->dirtyZ();
}
// Do northeast/southwest connections
// <FS:CR> Aurora Sim
//for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
for (i = 0; i < ppe[0] - 1; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(i, mPatchesPerEdge - 1);
//neighbor_patchp = neighborp->getPatch(i+1, 0);
patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1);
neighbor_patchp = neighborp->getPatch(i+1 + neighbor_offset[0], 0);
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
}
// Do southeast/northwest connections
// <FS:CR> Aurora Sim
//for (i = 1; i < (S32)mPatchesPerEdge; i++)
for (i = 1; i < ppe[0]; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(i, mPatchesPerEdge - 1);
//neighbor_patchp = neighborp->getPatch(i-1, 0);
patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1);
neighbor_patchp = neighborp->getPatch(i-1 + neighbor_offset[0], 0);
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
}
}
else if (WEST == direction)
{
// Do east/west connections, first
// <FS:CR> Aurora Sim
//for (i = 0; i < mPatchesPerEdge; i++)
for (i = 0; i < ppe[1]; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(0, i);
//neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i);
patchp = getPatch(0, i + own_offset[1]);
neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i + neighbor_offset[1]);
if (!neighbor_patchp) continue;
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, direction);
neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
neighbor_patchp->updateEastEdge();
neighbor_patchp->dirtyZ();
}
// Now do northeast/southwest connections
// <FS:CR> Aurora Sim
//for (i = 1; i < mPatchesPerEdge; i++)
for (i = 1; i < ppe[1]; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(0, i);
//neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i - 1);
patchp = getPatch(0, i + own_offset[1]);
neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i - 1 + neighbor_offset[1]);
if (!neighbor_patchp) continue;
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
}
// Now do northwest/southeast connections
// <FS:CR> Aurora Sim
//for (i = 0; i < mPatchesPerEdge - 1; i++)
for (i = 0; i < ppe[1] - 1; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(0, i);
//neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i + 1);
patchp = getPatch(0, i + own_offset[1]);
neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i + 1 + neighbor_offset[1]);
if (!neighbor_patchp) continue;
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
}
}
else if (SOUTH == direction)
{
// Do north/south connections, first
// <FS:CR> Aurora Sim
//for (i = 0; i < mPatchesPerEdge; i++)
for (i = 0; i < ppe[0]; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(i, 0);
//neighbor_patchp = neighborp->getPatch(i, mPatchesPerEdge - 1);
patchp = getPatch(i + own_offset[0], 0);
neighbor_patchp = neighborp->getPatch(i + neighbor_offset[0], neighborPatchesPerEdge - 1);
if (!neighbor_patchp) continue;
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, direction);
neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
neighbor_patchp->updateNorthEdge();
neighbor_patchp->dirtyZ();
}
// Now do northeast/southwest connections
// <FS:CR> Aurora Sim
//for (i = 1; i < mPatchesPerEdge; i++)
for (i = 1; i < ppe[0]; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(i, 0);
//neighbor_patchp = neighborp->getPatch(i - 1, mPatchesPerEdge - 1);
patchp = getPatch(i + own_offset[0], 0);
neighbor_patchp = neighborp->getPatch(i - 1 + neighbor_offset[0], neighborPatchesPerEdge - 1);
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
}
// Now do northeast/southwest connections
// <FS:CR> Aurora Sim
//for (i = 0; i < mPatchesPerEdge - 1; i++)
for (i = 0; i < ppe[0] - 1; i++)
// </FS:CR> Aurora Sim
{
// <FS:CR> Aurora Sim
//patchp = getPatch(i, 0);
//neighbor_patchp = neighborp->getPatch(i + 1, mPatchesPerEdge - 1);
patchp = getPatch(i + own_offset[0], 0);
neighbor_patchp = neighborp->getPatch(i + 1 + neighbor_offset[0], neighborPatchesPerEdge - 1);
// </FS:CR> Aurora Sim
patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
}
}
} }
void LLSurface::disconnectNeighbor(LLSurface *surfacep) void LLSurface::disconnectNeighbor(LLSurface *surfacep)
@@ -730,10 +492,9 @@ void LLSurface::disconnectNeighbor(LLSurface *surfacep)
} }
// Iterate through surface patches, removing any connectivity to removed surface. // Iterate through surface patches, removing any connectivity to removed surface.
if (mPatchList) // Don't crash if removed before for (auto& patchp : mPatchList)
for (i = 0; i < mNumberOfPatches; i++)
{ {
(mPatchList + i)->disconnectNeighbor(surfacep); patchp->disconnectNeighbor(surfacep);
} }
} }
@@ -802,13 +563,9 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent)
LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal()); LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());
LLSurfacePatch *patchp;
mVisiblePatchCount = 0; mVisiblePatchCount = 0;
for (S32 i=0; i<mNumberOfPatches; i++) for (auto& patchp : mPatchList)
{ {
patchp = mPatchList + i;
patchp->updateVisibility(); patchp->updateVisibility();
if (patchp->getVisible()) if (patchp->getVisible())
{ {
@@ -832,19 +589,29 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
// If the Z height data has changed, we need to rebuild our // If the Z height data has changed, we need to rebuild our
// property line vertex arrays. // property line vertex arrays.
if (mDirtyPatchList.size() > 0) if (!mDirtyPatchList.empty())
{ {
getRegion()->dirtyHeights(); getRegion()->dirtyHeights();
} }
// Always call updateNormals() / updateVerticalStats() // Always call updateNormals() / updateVerticalStats()
// every frame to avoid artifacts // every frame to avoid artifacts
for(std::set<LLSurfacePatch *>::iterator iter = mDirtyPatchList.begin(); for (auto& it = mDirtyPatchList.cbegin(); it != mDirtyPatchList.cend();)
iter != mDirtyPatchList.end(); )
{ {
std::set<LLSurfacePatch *>::iterator curiter = iter++; if (it->second.expired())
LLSurfacePatch *patchp = *curiter; {
patchp->updateNormals(); LL_WARNS() << "Expired dirty patch detected. Side " << it->first << LL_ENDL;
}
surface_patch_ref patchp = it->second.lock();
if (!patchp)
{
it = mDirtyPatchList.erase(it);
continue;
}
if (patchp->updateNormals())
{
patchp->getSurface()->dirtySurfacePatch(patchp);
}
patchp->updateVerticalStats(); patchp->updateVerticalStats();
if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time) if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time)
{ {
@@ -852,9 +619,11 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
{ {
did_update = TRUE; did_update = TRUE;
patchp->clearDirty(); patchp->clearDirty();
mDirtyPatchList.erase(curiter); it = mDirtyPatchList.erase(it);
continue;
} }
} }
++it;
} }
return did_update; return did_update;
} }
@@ -865,7 +634,6 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL
LLPatchHeader ph; LLPatchHeader ph;
S32 j, i; S32 j, i;
S32 patch[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE]; S32 patch[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE];
LLSurfacePatch *patchp;
init_patch_decompressor(gopp->patch_size); init_patch_decompressor(gopp->patch_size);
gopp->stride = mGridsPerEdge; gopp->stride = mGridsPerEdge;
@@ -912,8 +680,7 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL
return; return;
} }
patchp = &mPatchList[j*mPatchesPerEdge + i]; const surface_patch_ref& patchp = mPatchList[j * mPatchesPerEdge + i];
decode_patch(bitpack, patch); decode_patch(bitpack, patch);
decompress_patch(patchp->getDataZ(), patch, &ph); decompress_patch(patchp->getDataZ(), patch, &ph);
@@ -921,22 +688,26 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL
// Update edges for neighbors. Need to guarantee that this gets done before we generate vertical stats. // Update edges for neighbors. Need to guarantee that this gets done before we generate vertical stats.
patchp->updateNorthEdge(); patchp->updateNorthEdge();
patchp->updateEastEdge(); patchp->updateEastEdge();
if (patchp->getNeighborPatch(WEST)) LLSurfacePatch* neighborPatch;
if (neighborPatch = patchp->getNeighborPatch(WEST))
{ {
patchp->getNeighborPatch(WEST)->updateEastEdge(); neighborPatch->updateEastEdge();
} }
if (patchp->getNeighborPatch(SOUTHWEST)) if (neighborPatch = patchp->getNeighborPatch(SOUTHWEST))
{ {
patchp->getNeighborPatch(SOUTHWEST)->updateEastEdge(); neighborPatch->updateEastEdge();
patchp->getNeighborPatch(SOUTHWEST)->updateNorthEdge(); neighborPatch->updateNorthEdge();
} }
if (patchp->getNeighborPatch(SOUTH)) if (neighborPatch = patchp->getNeighborPatch(SOUTH))
{ {
patchp->getNeighborPatch(SOUTH)->updateNorthEdge(); neighborPatch->updateNorthEdge();
} }
// Dirty patch statistics, and flag that the patch has data. // Dirty patch statistics, and flag that the patch has data.
patchp->dirtyZ(); if (patchp->dirtyZ())
{
dirtySurfacePatch(patchp);
}
patchp->setHasReceivedData(); patchp->setHasReceivedData();
} }
} }
@@ -1089,8 +860,13 @@ LLVector3 LLSurface::resolveNormalGlobal(const LLVector3d& pos_global) const
} }
LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const const surface_patch_ref& LLSurface::resolvePatchRegion(const F32 x, const F32 y) const
{ {
if (mPatchList.empty()) {
LL_WARNS() << "No patches for current region!" << LL_ENDL;
static surface_patch_ref empty;
return empty;
}
// x and y should be region-local coordinates. // x and y should be region-local coordinates.
// If x and y are outside of the surface, then the returned // If x and y are outside of the surface, then the returned
// index will be for the nearest boundary patch. // index will be for the nearest boundary patch.
@@ -1141,29 +917,24 @@ LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const
// *NOTE: Super paranoia code follows. // *NOTE: Super paranoia code follows.
S32 index = i + j * mPatchesPerEdge; S32 index = i + j * mPatchesPerEdge;
if((index < 0) || (index >= mNumberOfPatches)) if((index < 0) || (index >= mPatchList.size()))
{ {
if(0 == mNumberOfPatches)
{
LL_WARNS() << "No patches for current region!" << LL_ENDL;
return NULL;
}
S32 old_index = index; S32 old_index = index;
index = llclamp(old_index, 0, (mNumberOfPatches - 1)); index = llclamp(old_index, 0, ((S32)mPatchList.size() - 1));
LL_WARNS() << "Clamping out of range patch index " << old_index LL_WARNS() << "Clamping out of range patch index " << old_index
<< " to " << index << LL_ENDL; << " to " << index << LL_ENDL;
} }
return &(mPatchList[index]); return mPatchList[index];
} }
LLSurfacePatch *LLSurface::resolvePatchRegion(const LLVector3 &pos_region) const const surface_patch_ref& LLSurface::resolvePatchRegion(const LLVector3 &pos_region) const
{ {
return resolvePatchRegion(pos_region.mV[VX], pos_region.mV[VY]); return resolvePatchRegion(pos_region.mV[VX], pos_region.mV[VY]);
} }
LLSurfacePatch *LLSurface::resolvePatchGlobal(const LLVector3d &pos_global) const const surface_patch_ref& LLSurface::resolvePatchGlobal(const LLVector3d &pos_global) const
{ {
llassert(mRegionp); llassert(mRegionp);
LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global); LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global);
@@ -1192,37 +963,28 @@ void LLSurface::createPatchData()
// Assumes mGridsPerEdge, mGridsPerPatchEdge, and mPatchesPerEdge have been properly set // Assumes mGridsPerEdge, mGridsPerPatchEdge, and mPatchesPerEdge have been properly set
// TODO -- check for create() called when surface is not empty // TODO -- check for create() called when surface is not empty
S32 i, j; S32 i, j;
LLSurfacePatch *patchp;
// Allocate memory // Allocate memory
mPatchList = new LLSurfacePatch[mNumberOfPatches]; mPatchList.resize(mPatchesPerEdge * mPatchesPerEdge);
for (S32 i = 0; i < mPatchList.size(); ++i)
// One of each for each camera
mVisiblePatchCount = mNumberOfPatches;
for (j=0; j<mPatchesPerEdge; j++)
{ {
for (i=0; i<mPatchesPerEdge; i++) mPatchList[i] = std::make_shared<LLSurfacePatch>(this, i);
{
patchp = getPatch(i, j);
patchp->setSurface(this);
}
} }
// One of each for each camera
mVisiblePatchCount = mPatchList.size();
for (j=0; j<mPatchesPerEdge; j++) for (j=0; j<mPatchesPerEdge; j++)
{ {
for (i=0; i<mPatchesPerEdge; i++) for (i=0; i<mPatchesPerEdge; i++)
{ {
patchp = getPatch(i, j); const auto& patchp = getPatch(i, j);
patchp->mHasReceivedData = FALSE;
patchp->mSTexUpdate = TRUE;
S32 data_offset = i * mGridsPerPatchEdge + j * mGridsPerPatchEdge * mGridsPerEdge; S32 data_offset = i * mGridsPerPatchEdge + j * mGridsPerPatchEdge * mGridsPerEdge;
patchp->setDataZ(mSurfaceZ + data_offset); patchp->setDataZ(mSurfaceZ + data_offset);
patchp->setDataNorm(mNorm + data_offset); patchp->setDataNorm(mNorm + data_offset);
// We make each patch point to its neighbors so we can do resolution checking // We make each patch point to its neighbors so we can do resolution checking
// when butting up different resolutions. Patches that don't have neighbors // when butting up different resolutions. Patches that don't have neighbors
// somewhere will point to NULL on that side. // somewhere will point to NULL on that side.
@@ -1311,9 +1073,7 @@ void LLSurface::createPatchData()
void LLSurface::destroyPatchData() void LLSurface::destroyPatchData()
{ {
// Delete all of the cached patch data for these patches. // Delete all of the cached patch data for these patches.
mPatchList.clear();
delete [] mPatchList;
mPatchList = NULL;
mVisiblePatchCount = 0; mVisiblePatchCount = 0;
} }
@@ -1336,36 +1096,50 @@ U32 LLSurface::getRenderStride(const U32 render_level) const
} }
LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const const surface_patch_ref& LLSurface::getPatch(const S32 x, const S32 y) const
{ {
static surface_patch_ref empty(nullptr);
if ((x < 0) || (x >= mPatchesPerEdge)) if ((x < 0) || (x >= mPatchesPerEdge))
{ {
LL_WARNS() << "Asking for patch out of bounds" << LL_ENDL; LL_WARNS() << "Asking for patch out of bounds" << LL_ENDL;
return NULL; return empty;
} }
if ((y < 0) || (y >= mPatchesPerEdge)) if ((y < 0) || (y >= mPatchesPerEdge))
{ {
LL_WARNS() << "Asking for patch out of bounds" << LL_ENDL; LL_WARNS() << "Asking for patch out of bounds" << LL_ENDL;
return NULL; return empty;
} }
return mPatchList + x + y*mPatchesPerEdge; return mPatchList[x + y*mPatchesPerEdge];
} }
void LLSurface::dirtyAllPatches() void LLSurface::dirtyAllPatches()
{ {
S32 i; for (auto& patchp : mPatchList)
for (i = 0; i < mNumberOfPatches; i++)
{ {
mPatchList[i].dirtyZ(); if (patchp->dirtyZ())
{
dirtySurfacePatch(patchp);
}
} }
} }
void LLSurface::dirtySurfacePatch(LLSurfacePatch *patchp) void LLSurface::dirtySurfacePatch(const surface_patch_ref& patchp)
{ {
if (!patchp)
{
return;
}
// Put surface patch on dirty surface patch list // Put surface patch on dirty surface patch list
mDirtyPatchList.insert(patchp); if (std::find_if(mDirtyPatchList.begin(), mDirtyPatchList.end(),
[&patchp](std::pair<U32, std::weak_ptr<LLSurfacePatch > >& entry) -> bool {
return entry.second.lock().get() == patchp.get();
}) == mDirtyPatchList.end())
{
mDirtyPatchList.push_back(std::make_pair(patchp->getSide(), patchp));
}
} }

View File

@@ -60,9 +60,12 @@ static const S32 ONE_LESS_THAN_NEIGHBOR = -1;
const S32 ABOVE_WATERLINE_ALPHA = 32; // The alpha of water when the land elevation is above the waterline. const S32 ABOVE_WATERLINE_ALPHA = 32; // The alpha of water when the land elevation is above the waterline.
class LLViewerRegion; class LLViewerRegion;
class LLSurfacePatch;
class LLBitPack; class LLBitPack;
class LLGroupHeader; class LLGroupHeader;
class LLSurfacePatch;
typedef std::shared_ptr<LLSurfacePatch> surface_patch_ref;
typedef std::weak_ptr<LLSurfacePatch> surface_patch_weak_ref;
class LLSurface class LLSurface
{ {
@@ -111,9 +114,9 @@ public:
F32 resolveHeightGlobal(const LLVector3d &position_global) const; F32 resolveHeightGlobal(const LLVector3d &position_global) const;
LLVector3 resolveNormalGlobal(const LLVector3d& v) const; // Returns normal to surface LLVector3 resolveNormalGlobal(const LLVector3d& v) const; // Returns normal to surface
LLSurfacePatch *resolvePatchRegion(const F32 x, const F32 y) const; const surface_patch_ref& resolvePatchRegion(const F32 x, const F32 y) const;
LLSurfacePatch *resolvePatchRegion(const LLVector3 &position_region) const; const surface_patch_ref& resolvePatchRegion(const LLVector3 &position_region) const;
LLSurfacePatch *resolvePatchGlobal(const LLVector3d &position_global) const; const surface_patch_ref& resolvePatchGlobal(const LLVector3d &position_global) const;
// Update methods (called during idle, normally) // Update methods (called during idle, normally)
BOOL idleUpdate(F32 max_update_time); BOOL idleUpdate(F32 max_update_time);
@@ -136,7 +139,7 @@ public:
void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters
void dirtySurfacePatch(LLSurfacePatch *patchp); void dirtySurfacePatch(const surface_patch_ref& patchp);
LLVOWater *getWaterObj() { return mWaterObjp; } LLVOWater *getWaterObj() { return mWaterObjp; }
static void setTextureSize(const S32 texture_size); static void setTextureSize(const S32 texture_size);
@@ -155,8 +158,6 @@ public:
F32 mOOGridsPerEdge; // Inverse of grids per edge F32 mOOGridsPerEdge; // Inverse of grids per edge
S32 mPatchesPerEdge; // Number of patches on one side of a region S32 mPatchesPerEdge; // Number of patches on one side of a region
S32 mNumberOfPatches; // Total number of patches
// Each surface points at 8 neighbors (or NULL) // Each surface points at 8 neighbors (or NULL)
// +---+---+---+ // +---+---+---+
@@ -191,11 +192,11 @@ protected:
//F32 updateTexture(LLSurfacePatch *ppatch); //F32 updateTexture(LLSurfacePatch *ppatch);
LLSurfacePatch *getPatch(const S32 x, const S32 y) const; const surface_patch_ref& getPatch(const S32 x, const S32 y) const;
protected: protected:
LLVector3d mOriginGlobal; // In absolute frame LLVector3d mOriginGlobal; // In absolute frame
LLSurfacePatch *mPatchList; // Array of all patches std::vector< surface_patch_ref > mPatchList; // Array of all patches
// Array of grid data, mGridsPerEdge * mGridsPerEdge // Array of grid data, mGridsPerEdge * mGridsPerEdge
F32 *mSurfaceZ; F32 *mSurfaceZ;
@@ -203,7 +204,7 @@ protected:
// Array of grid normals, mGridsPerEdge * mGridsPerEdge // Array of grid normals, mGridsPerEdge * mGridsPerEdge
LLVector3 *mNorm; LLVector3 *mNorm;
std::set<LLSurfacePatch *> mDirtyPatchList; std::vector< std::pair<U32, surface_patch_weak_ref > > mDirtyPatchList;
// The textures should never be directly initialized - use the setter methods! // The textures should never be directly initialized - use the setter methods!

View File

@@ -47,9 +47,9 @@ extern bool gShiftFrame;
extern U64MicrosecondsImplicit gFrameTime; extern U64MicrosecondsImplicit gFrameTime;
extern LLPipeline gPipeline; extern LLPipeline gPipeline;
LLSurfacePatch::LLSurfacePatch() LLSurfacePatch::LLSurfacePatch(LLSurface* surface, U32 side)
: mHasReceivedData(FALSE), : mHasReceivedData(FALSE),
mSTexUpdate(FALSE), mSTexUpdate(TRUE),
mDirty(FALSE), mDirty(FALSE),
mDirtyZStats(TRUE), mDirtyZStats(TRUE),
mHeightsGenerated(FALSE), mHeightsGenerated(FALSE),
@@ -70,17 +70,12 @@ LLSurfacePatch::LLSurfacePatch()
// set to non-zero values by higher classes. // set to non-zero values by higher classes.
mConnectedEdge(NO_EDGE), mConnectedEdge(NO_EDGE),
mLastUpdateTime(0), mLastUpdateTime(0),
mSurfacep(NULL) mSurfacep(NULL),
{ mNeighborPatches{ 0,0,0,0,0,0,0,0 },
S32 i; mNormalsInvalid{ 1,1,1,1,1,1,1,1,1 },
for (i = 0; i < 8; i++) mSide(side)
{ {
setNeighborPatch(i, NULL); setSurface(surface);
}
for (i = 0; i < 9; i++)
{
mNormalsInvalid[i] = TRUE;
}
} }
@@ -90,7 +85,7 @@ LLSurfacePatch::~LLSurfacePatch()
} }
void LLSurfacePatch::dirty() bool LLSurfacePatch::dirty()
{ {
// These are outside of the loop in case we're still waiting for a dirty from the // These are outside of the loop in case we're still waiting for a dirty from the
// texture being updated... // texture being updated...
@@ -109,8 +104,9 @@ void LLSurfacePatch::dirty()
if (!mDirty) if (!mDirty)
{ {
mDirty = TRUE; mDirty = TRUE;
mSurfacep->dirtySurfacePatch(this); return true;
} }
return false;
} }
@@ -133,45 +129,31 @@ void LLSurfacePatch::disconnectNeighbor(LLSurface *surfacep)
U32 i; U32 i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
if (getNeighborPatch(i)) const auto& patch = getNeighborPatch(i);
if (patch)
{ {
if (getNeighborPatch(i)->mSurfacep == surfacep) if (patch->mSurfacep == surfacep)
{ {
if (EAST == i)
{
mConnectedEdge &= EAST_EDGE;
}
else if (NORTH == i)
{
mConnectedEdge &= NORTH_EDGE;
}
else if (WEST == i)
{
mConnectedEdge &= WEST_EDGE;
}
else if (SOUTH == i)
{
mConnectedEdge &= SOUTH_EDGE;
}
setNeighborPatch(i, NULL); setNeighborPatch(i, NULL);
mNormalsInvalid[i] = TRUE;
} }
} }
} }
// Clean up connected edges
if (getNeighborPatch(EAST))
{
if (getNeighborPatch(EAST)->mSurfacep == surfacep)
{
mConnectedEdge &= ~EAST_EDGE;
}
}
if (getNeighborPatch(NORTH))
{
if (getNeighborPatch(NORTH)->mSurfacep == surfacep)
{
mConnectedEdge &= ~NORTH_EDGE;
}
}
if (getNeighborPatch(WEST))
{
if (getNeighborPatch(WEST)->mSurfacep == surfacep)
{
mConnectedEdge &= ~WEST_EDGE;
}
}
if (getNeighborPatch(SOUTH))
{
if (getNeighborPatch(SOUTH)->mSurfacep == surfacep)
{
mConnectedEdge &= ~SOUTH_EDGE;
}
}
} }
LLVector3 LLSurfacePatch::getPointAgent(const U32 x, const U32 y) const LLVector3 LLSurfacePatch::getPointAgent(const U32 x, const U32 y) const
@@ -283,64 +265,65 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
{ {
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
{ {
LLSurfacePatch* patch;
if (poffsets[i][j][0] < 0) if (poffsets[i][j][0] < 0)
{ {
if (!ppatches[i][j]->getNeighborPatch(WEST)) if (patch = ppatches[i][j]->getNeighborPatch(WEST))
{ {
poffsets[i][j][0] = 0; // <FS:CR> Aurora Sim
ppatches[i][j] = patch;
poffsets[i][j][0] += patch_width;
poffsets[i][j][2] = patch->getSurface()->getGridsPerEdge();
// </FS:CR> Aurora Sim
} }
else else
{ {
// <FS:CR> Aurora Sim poffsets[i][j][0] = 0;
ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
poffsets[i][j][0] += patch_width;
poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge();
// </FS:CR> Aurora Sim
} }
} }
if (poffsets[i][j][1] < 0) if (poffsets[i][j][1] < 0)
{ {
if (!ppatches[i][j]->getNeighborPatch(SOUTH)) if (patch = ppatches[i][j]->getNeighborPatch(SOUTH))
{ {
poffsets[i][j][1] = 0; // <FS:CR> Aurora Sim
ppatches[i][j] = patch;
poffsets[i][j][1] += patch_width;
poffsets[i][j][2] = patch->getSurface()->getGridsPerEdge();
// </FS>CR> Aurora Sim
} }
else else
{ {
// <FS:CR> Aurora Sim poffsets[i][j][1] = 0;
ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
poffsets[i][j][1] += patch_width;
poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge();
// </FS>CR> Aurora Sim
} }
} }
if (poffsets[i][j][0] >= (S32)patch_width) if (poffsets[i][j][0] >= (S32)patch_width)
{ {
if (!ppatches[i][j]->getNeighborPatch(EAST)) if (patch = ppatches[i][j]->getNeighborPatch(EAST))
{ {
poffsets[i][j][0] = patch_width - 1; // <FS:CR> Aurora Sim
ppatches[i][j] = patch;
poffsets[i][j][0] -= patch_width;
poffsets[i][j][2] = patch->getSurface()->getGridsPerEdge();
// </FS:CR> Aurora Sim
} }
else else
{ {
// <FS:CR> Aurora Sim poffsets[i][j][0] = patch_width - 1;
ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
poffsets[i][j][0] -= patch_width;
poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge();
// </FS:CR> Aurora Sim
} }
} }
if (poffsets[i][j][1] >= (S32)patch_width) if (poffsets[i][j][1] >= (S32)patch_width)
{ {
if (!ppatches[i][j]->getNeighborPatch(NORTH)) if (patch = ppatches[i][j]->getNeighborPatch(NORTH))
{ {
poffsets[i][j][1] = patch_width - 1; // <FS:CR> Aurora Sim
ppatches[i][j] = patch;
poffsets[i][j][1] -= patch_width;
poffsets[i][j][2] = patch->getSurface()->getGridsPerEdge();
// </FS:CR> Aurora Sim
} }
else else
{ {
// <FS:CR> Aurora Sim poffsets[i][j][1] = patch_width - 1;
ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
poffsets[i][j][1] -= patch_width;
poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge();
// </FS:CR> Aurora Sim
} }
} }
} }
@@ -474,11 +457,11 @@ void LLSurfacePatch::updateVerticalStats()
} }
void LLSurfacePatch::updateNormals() bool LLSurfacePatch::updateNormals()
{ {
if (mSurfacep->mType == 'w') if (mSurfacep->mType == 'w')
{ {
return; return false;
} }
U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
U32 grids_per_edge = mSurfacep->getGridsPerEdge(); U32 grids_per_edge = mSurfacep->getGridsPerEdge();
@@ -515,10 +498,12 @@ void LLSurfacePatch::updateNormals()
// update the west edge // update the west edge
if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST]) if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST])
{ {
LLSurfacePatch* northwest_patchp = getNeighborPatch(NORTHWEST);
LLSurfacePatch* north_patchp = getNeighborPatch(NORTH);
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
if (!getNeighborPatch(NORTH) && getNeighborPatch(NORTHWEST) && getNeighborPatch(NORTHWEST)->getHasReceivedData()) if (!north_patchp && northwest_patchp && northwest_patchp->getHasReceivedData())
{ {
*(mDataZ + grids_per_patch_edge*grids_per_edge) = *(getNeighborPatch(NORTHWEST)->mDataZ + grids_per_patch_edge); *(mDataZ + grids_per_patch_edge*grids_per_edge) = *(northwest_patchp->mDataZ + grids_per_patch_edge);
} }
// </FS:CR> Aurora Sim // </FS:CR> Aurora Sim
@@ -533,10 +518,12 @@ void LLSurfacePatch::updateNormals()
// update the south edge // update the south edge
if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST]) if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST])
{ {
LLSurfacePatch* southeast_patchp = getNeighborPatch(SOUTHEAST);
LLSurfacePatch* east_patchp = getNeighborPatch(EAST);
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
if (!getNeighborPatch(EAST) && getNeighborPatch(SOUTHEAST) && getNeighborPatch(SOUTHEAST)->getHasReceivedData()) if (!east_patchp && southeast_patchp && southeast_patchp->getHasReceivedData())
{ {
*(mDataZ + grids_per_patch_edge) = *(getNeighborPatch(SOUTHEAST)->mDataZ + grids_per_patch_edge * getNeighborPatch(SOUTHEAST)->getSurface()->getGridsPerEdge()); *(mDataZ + grids_per_patch_edge) = *(southeast_patchp->mDataZ + grids_per_patch_edge * southeast_patchp->getSurface()->getGridsPerEdge());
} }
// </FS:CR> Aurora Sim // </FS:CR> Aurora Sim
@@ -552,11 +539,14 @@ void LLSurfacePatch::updateNormals()
// we'll want to do different things. // we'll want to do different things.
if (mNormalsInvalid[NORTHEAST]) if (mNormalsInvalid[NORTHEAST])
{ {
if (!getNeighborPatch(NORTHEAST)) LLSurfacePatch* northeast_patchp = getNeighborPatch(NORTHEAST);
LLSurfacePatch* north_patchp = getNeighborPatch(NORTH);
LLSurfacePatch* east_patchp = getNeighborPatch(EAST);
if (!northeast_patchp)
{ {
if (!getNeighborPatch(NORTH)) if (!north_patchp)
{ {
if (!getNeighborPatch(EAST)) if (!east_patchp)
{ {
// No north or east neighbors. Pull from the diagonal in your own patch. // No north or east neighbors. Pull from the diagonal in your own patch.
*(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
@@ -564,13 +554,13 @@ void LLSurfacePatch::updateNormals()
} }
else else
{ {
if (getNeighborPatch(EAST)->getHasReceivedData()) if (east_patchp->getHasReceivedData())
{ {
// East, but not north. Pull from your east neighbor's northwest point. // East, but not north. Pull from your east neighbor's northwest point.
*(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
//*(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge); //*(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge);
*(getNeighborPatch(EAST)->mDataZ + (getNeighborPatch(EAST)->getSurface()->getGridsPerPatchEdge() - 1)*getNeighborPatch(EAST)->getSurface()->getGridsPerEdge()); *(east_patchp->mDataZ + (east_patchp->getSurface()->getGridsPerPatchEdge() - 1)* east_patchp->getSurface()->getGridsPerEdge());
// </FS:CR> Aurora Sim // </FS:CR> Aurora Sim
} }
else else
@@ -583,7 +573,7 @@ void LLSurfacePatch::updateNormals()
else else
{ {
// We have a north. // We have a north.
if (getNeighborPatch(EAST)) if (east_patchp)
{ {
// North and east neighbors, but not northeast. // North and east neighbors, but not northeast.
// Pull from diagonal in your own patch. // Pull from diagonal in your own patch.
@@ -592,13 +582,13 @@ void LLSurfacePatch::updateNormals()
} }
else else
{ {
if (getNeighborPatch(NORTH)->getHasReceivedData()) if (north_patchp->getHasReceivedData())
{ {
// North, but not east. Pull from your north neighbor's southeast corner. // North, but not east. Pull from your north neighbor's southeast corner.
*(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
//*(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1)); //*(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1));
*(getNeighborPatch(NORTH)->mDataZ + (getNeighborPatch(NORTH)->getSurface()->getGridsPerPatchEdge() - 1)); *(north_patchp->mDataZ + (north_patchp->getSurface()->getGridsPerPatchEdge() - 1));
// </FS:CR> Aurora Sim // </FS:CR> Aurora Sim
} }
else else
@@ -609,25 +599,25 @@ void LLSurfacePatch::updateNormals()
} }
} }
} }
else if (getNeighborPatch(NORTHEAST)->mSurfacep != mSurfacep) else if (northeast_patchp->mSurfacep != mSurfacep)
{ {
if ( if (
(!getNeighborPatch(NORTH) || (getNeighborPatch(NORTH)->mSurfacep != mSurfacep)) (!north_patchp || (north_patchp->mSurfacep != mSurfacep))
&& &&
(!getNeighborPatch(EAST) || (getNeighborPatch(EAST)->mSurfacep != mSurfacep))) (!east_patchp || (east_patchp->mSurfacep != mSurfacep)))
{ {
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
U32 own_xpos, own_ypos, neighbor_xpos, neighbor_ypos; U32 own_xpos, own_ypos, neighbor_xpos, neighbor_ypos;
S32 own_offset = 0, neighbor_offset = 0; S32 own_offset = 0, neighbor_offset = 0;
from_region_handle(mSurfacep->getRegion()->getHandle(), &own_xpos, &own_ypos); from_region_handle(mSurfacep->getRegion()->getHandle(), &own_xpos, &own_ypos);
from_region_handle(getNeighborPatch(NORTHEAST)->mSurfacep->getRegion()->getHandle(), &neighbor_xpos, &neighbor_ypos); from_region_handle(northeast_patchp->mSurfacep->getRegion()->getHandle(), &neighbor_xpos, &neighbor_ypos);
if (own_ypos >= neighbor_ypos) if (own_ypos >= neighbor_ypos)
neighbor_offset = own_ypos - neighbor_ypos; neighbor_offset = own_ypos - neighbor_ypos;
else else
own_offset = neighbor_ypos - own_ypos; own_offset = neighbor_ypos - own_ypos;
*(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
*(getNeighborPatch(NORTHEAST)->mDataZ + (grids_per_edge + neighbor_offset - own_offset - 1) * getNeighborPatch(NORTHEAST)->getSurface()->getGridsPerEdge()); *(northeast_patchp->mDataZ + (grids_per_edge + neighbor_offset - own_offset - 1) * northeast_patchp->getSurface()->getGridsPerEdge());
// </FS:CR> Aurora Sim // </FS:CR> Aurora Sim
} }
} }
@@ -656,15 +646,12 @@ void LLSurfacePatch::updateNormals()
dirty_patch = TRUE; dirty_patch = TRUE;
} }
if (dirty_patch)
{
mSurfacep->dirtySurfacePatch(this);
}
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
{ {
mNormalsInvalid[i] = FALSE; mNormalsInvalid[i] = FALSE;
} }
return dirty_patch;
} }
void LLSurfacePatch::updateEastEdge() void LLSurfacePatch::updateEastEdge()
@@ -719,7 +706,8 @@ void LLSurfacePatch::updateNorthEdge()
U32 i; U32 i;
F32 *south_surface, *north_surface; F32 *south_surface, *north_surface;
if (!getNeighborPatch(NORTH)) LLSurfacePatch* patchp = getNeighborPatch(NORTH);
if (!patchp)
{ {
south_surface = mDataZ + grids_per_patch_edge*grids_per_edge; south_surface = mDataZ + grids_per_patch_edge*grids_per_edge;
north_surface = mDataZ + (grids_per_patch_edge - 1) * grids_per_edge; north_surface = mDataZ + (grids_per_patch_edge - 1) * grids_per_edge;
@@ -727,7 +715,7 @@ void LLSurfacePatch::updateNorthEdge()
else if (mConnectedEdge & NORTH_EDGE) else if (mConnectedEdge & NORTH_EDGE)
{ {
south_surface = mDataZ + grids_per_patch_edge*grids_per_edge; south_surface = mDataZ + grids_per_patch_edge*grids_per_edge;
north_surface = getNeighborPatch(NORTH)->mDataZ; north_surface = patchp->mDataZ;
} }
else else
{ {
@@ -748,10 +736,11 @@ BOOL LLSurfacePatch::updateTexture()
F32 meters_per_grid = getSurface()->getMetersPerGrid(); F32 meters_per_grid = getSurface()->getMetersPerGrid();
F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
if ((!getNeighborPatch(EAST) || getNeighborPatch(EAST)->getHasReceivedData()) LLSurfacePatch* patchp;
&& (!getNeighborPatch(WEST) || getNeighborPatch(WEST)->getHasReceivedData()) if ((!(patchp = getNeighborPatch(EAST)) || patchp->getHasReceivedData())
&& (!getNeighborPatch(SOUTH) || getNeighborPatch(SOUTH)->getHasReceivedData()) && (!(patchp = getNeighborPatch(WEST)) || patchp->getHasReceivedData())
&& (!getNeighborPatch(NORTH) || getNeighborPatch(NORTH)->getHasReceivedData())) && (!(patchp = getNeighborPatch(SOUTH)) || patchp->getHasReceivedData())
&& (!(patchp = getNeighborPatch(NORTH)) || patchp->getHasReceivedData()))
{ {
LLViewerRegion *regionp = getSurface()->getRegion(); LLViewerRegion *regionp = getSurface()->getRegion();
LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal();
@@ -813,7 +802,7 @@ void LLSurfacePatch::updateGL()
} }
} }
void LLSurfacePatch::dirtyZ() bool LLSurfacePatch::dirtyZ()
{ {
mSTexUpdate = TRUE; mSTexUpdate = TRUE;
@@ -827,20 +816,36 @@ void LLSurfacePatch::dirtyZ()
// Invalidate normals in this and neighboring patches // Invalidate normals in this and neighboring patches
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
if (getNeighborPatch(i)) if (mNeighborPatches[i] == nullptr)
{ {
getNeighborPatch(i)->mNormalsInvalid[gDirOpposite[i]] = TRUE; continue;
getNeighborPatch(i)->dirty(); }
if (mNeighborPatches[i]->expired())
{
LL_WARNS() << "Expired neighbor patch detected. Side " << i << LL_ENDL;
delete mNeighborPatches[i];
mNeighborPatches[i] = nullptr;
continue;
}
const surface_patch_ref& patchp = mNeighborPatches[i]->lock();
if (patchp)
{
patchp->mNormalsInvalid[gDirOpposite[i]] = TRUE;
if (patchp->dirty())
{
patchp->getSurface()->dirtySurfacePatch(patchp);
}
if (i < 4) if (i < 4)
{ {
getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = TRUE; patchp->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = TRUE;
getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = TRUE; patchp->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = TRUE;
} }
} }
} }
dirty();
mLastUpdateTime = gFrameTime; mLastUpdateTime = gFrameTime;
return dirty();
} }
@@ -877,35 +882,29 @@ void LLSurfacePatch::setOriginGlobal(const LLVector3d &origin_global)
} }
void LLSurfacePatch::connectNeighbor(LLSurfacePatch *neighbor_patchp, const U32 direction) void LLSurfacePatch::connectNeighbor(const surface_patch_ref& neighbor_patchp, const U32 direction)
{ {
llassert(neighbor_patchp); llassert(neighbor_patchp);
if (!neighbor_patchp) return; if (!neighbor_patchp) return;
mNormalsInvalid[direction] = TRUE; mNormalsInvalid[direction] = TRUE;
neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = TRUE;
setNeighborPatch(direction, neighbor_patchp); setNeighborPatch(direction, neighbor_patchp);
neighbor_patchp->setNeighborPatch(gDirOpposite[direction], this);
if (EAST == direction) if (EAST == direction)
{ {
mConnectedEdge |= EAST_EDGE; mConnectedEdge |= EAST_EDGE;
neighbor_patchp->mConnectedEdge |= WEST_EDGE;
} }
else if (NORTH == direction) else if (NORTH == direction)
{ {
mConnectedEdge |= NORTH_EDGE; mConnectedEdge |= NORTH_EDGE;
neighbor_patchp->mConnectedEdge |= SOUTH_EDGE;
} }
else if (WEST == direction) else if (WEST == direction)
{ {
mConnectedEdge |= WEST_EDGE; mConnectedEdge |= WEST_EDGE;
neighbor_patchp->mConnectedEdge |= EAST_EDGE;
} }
else if (SOUTH == direction) else if (SOUTH == direction)
{ {
mConnectedEdge |= SOUTH_EDGE; mConnectedEdge |= SOUTH_EDGE;
neighbor_patchp->mConnectedEdge |= NORTH_EDGE;
} }
} }
@@ -963,13 +962,14 @@ void LLSurfacePatch::updateVisibility()
if (mVObjp) if (mVObjp)
{ {
mVObjp->dirtyGeom(); mVObjp->dirtyGeom();
if (getNeighborPatch(WEST)) LLSurfacePatch* patchp;
if (patchp = getNeighborPatch(WEST))
{ {
getNeighborPatch(WEST)->mVObjp->dirtyGeom(); patchp->mVObjp->dirtyGeom();
} }
if (getNeighborPatch(SOUTH)) if (patchp = getNeighborPatch(SOUTH))
{ {
getNeighborPatch(SOUTH)->mVObjp->dirtyGeom(); patchp->mVObjp->dirtyGeom();
} }
} }
} }
@@ -1074,9 +1074,21 @@ F32 LLSurfacePatch::getMaxComposition() const
return mMaxComposition; return mMaxComposition;
} }
void LLSurfacePatch::setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp) void LLSurfacePatch::setNeighborPatch(const U32 direction, const surface_patch_ref& neighborp)
{ {
mNeighborPatches[direction] = neighborp; if (!neighborp)
{
delete mNeighborPatches[direction];
mNeighborPatches[direction] = nullptr;
}
else
{
if (mNeighborPatches[direction] == nullptr)
{
mNeighborPatches[direction] = new surface_patch_weak_ref();
}
*mNeighborPatches[direction] = neighborp;
}
mNormalsInvalid[direction] = TRUE; mNormalsInvalid[direction] = TRUE;
if (direction < 4) if (direction < 4)
{ {
@@ -1087,7 +1099,15 @@ void LLSurfacePatch::setNeighborPatch(const U32 direction, LLSurfacePatch *neigh
LLSurfacePatch *LLSurfacePatch::getNeighborPatch(const U32 direction) const LLSurfacePatch *LLSurfacePatch::getNeighborPatch(const U32 direction) const
{ {
return mNeighborPatches[direction]; if (mNeighborPatches[direction] == nullptr)
{
return nullptr;
}
else if (mNeighborPatches[direction]->expired())
{
LL_WARNS() << "Expired neighbor patch detected. Side " << direction << LL_ENDL;
}
return mNeighborPatches[direction]->lock().get();
} }
void LLSurfacePatch::clearVObj() void LLSurfacePatch::clearVObj()

View File

@@ -43,6 +43,10 @@ class LLVector2;
class LLColor4U; class LLColor4U;
class LLAgent; class LLAgent;
class LLSurfacePatch;
typedef std::shared_ptr<LLSurfacePatch> surface_patch_ref;
typedef std::weak_ptr<LLSurfacePatch> surface_patch_weak_ref;
// A patch shouldn't know about its visibility since that really depends on the // A patch shouldn't know about its visibility since that really depends on the
// camera that is looking (or not looking) at it. So, anything about a patch // camera that is looking (or not looking) at it. So, anything about a patch
// that is specific to a camera should be in the class below. // that is specific to a camera should be in the class below.
@@ -64,26 +68,23 @@ public:
class LLSurfacePatch class LLSurfacePatch
{ {
public: public:
LLSurfacePatch(); LLSurfacePatch(LLSurface* surface, U32 side);
~LLSurfacePatch(); ~LLSurfacePatch();
void reset(const U32 id); void connectNeighbor(const surface_patch_ref& neighbor_patchp, const U32 direction);
void connectNeighbor(LLSurfacePatch *neighborp, const U32 direction);
void disconnectNeighbor(LLSurface *surfacep); void disconnectNeighbor(LLSurface *surfacep);
void setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp); void setNeighborPatch(const U32 direction, const surface_patch_ref& neighborp);
LLSurfacePatch *getNeighborPatch(const U32 direction) const; LLSurfacePatch *getNeighborPatch(const U32 direction) const;
void colorPatch(const U8 r, const U8 g, const U8 b);
BOOL updateTexture(); BOOL updateTexture();
void updateVerticalStats(); void updateVerticalStats();
void updateCompositionStats(); void updateCompositionStats();
void updateNormals(); bool updateNormals();
void updateEastEdge(); void updateEastEdge();
void updateNorthEdge(); void updateNorthEdge();
@@ -92,7 +93,7 @@ public:
void updateVisibility(); void updateVisibility();
void updateGL(); void updateGL();
void dirtyZ(); // Dirty the z values of this patch bool dirtyZ(); // Dirty the z values of this patch
void setHasReceivedData(); void setHasReceivedData();
BOOL getHasReceivedData() const; BOOL getHasReceivedData() const;
@@ -139,17 +140,19 @@ public:
void setDataNorm(LLVector3 *data_norm) { mDataNorm = data_norm; } void setDataNorm(LLVector3 *data_norm) { mDataNorm = data_norm; }
F32 *getDataZ() const { return mDataZ; } F32 *getDataZ() const { return mDataZ; }
void dirty(); // Mark this surface patch as dirty... bool dirty(); // Mark this surface patch as dirty...
void clearDirty() { mDirty = FALSE; } void clearDirty() { mDirty = FALSE; }
void clearVObj(); void clearVObj();
U32 getSide() const { return mSide; }
public: public:
BOOL mHasReceivedData; // has the patch EVER received height data? BOOL mHasReceivedData; // has the patch EVER received height data?
BOOL mSTexUpdate; // Does the surface texture need to be updated? BOOL mSTexUpdate; // Does the surface texture need to be updated?
protected: protected:
LLSurfacePatch *mNeighborPatches[8]; // Adjacent patches std::weak_ptr<LLSurfacePatch>* mNeighborPatches[8]; // Adjacent patches
BOOL mNormalsInvalid[9]; // Which normals are invalid BOOL mNormalsInvalid[9]; // Which normals are invalid
BOOL mDirty; BOOL mDirty;
@@ -184,6 +187,8 @@ protected:
// of LLSurface that is "connected" to another LLSurface // of LLSurface that is "connected" to another LLSurface
U64 mLastUpdateTime; // Time patch was last updated U64 mLastUpdateTime; // Time patch was last updated
U32 mSide; // Side relative to parent surface.
LLSurface *mSurfacep; // Pointer to "parent" surface LLSurface *mSurfacep; // Pointer to "parent" surface
}; };

View File

@@ -164,10 +164,10 @@ void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global,
//if(!is_changed) continue; //if(!is_changed) continue;
// Now to update the patch information so it will redraw correctly. // Now to update the patch information so it will redraw correctly.
LLSurfacePatch *patchp= land.resolvePatchRegion(pos_region); auto& patchp = land.resolvePatchRegion(pos_region);
if (patchp) if (patchp && patchp->dirtyZ())
{ {
patchp->dirtyZ(); patchp->getSurface()->dirtySurfacePatch(patchp);
} }
// Also force the property lines to update, normals to recompute, etc. // Also force the property lines to update, normals to recompute, etc.
@@ -305,10 +305,10 @@ void LLToolBrushLand::modifyLandInSelectionGlobal()
//if(!is_changed) continue; //if(!is_changed) continue;
// Now to update the patch information so it will redraw correctly. // Now to update the patch information so it will redraw correctly.
LLSurfacePatch *patchp= land.resolvePatchRegion(min_region); auto& patchp = land.resolvePatchRegion(min_region);
if (patchp) if (patchp && patchp->dirtyZ())
{ {
patchp->dirtyZ(); patchp->getSurface()->dirtySurfacePatch(patchp);
} }
// Also force the property lines to update, normals to recompute, etc. // Also force the property lines to update, normals to recompute, etc.

View File

@@ -575,6 +575,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{ {
LLPointer<LLImageRaw> raw = new LLImageRaw; LLPointer<LLImageRaw> raw = new LLImageRaw;
raw->enableOverSize();
S32 width = gViewerWindow->getWindowDisplayWidth(); S32 width = gViewerWindow->getWindowDisplayWidth();
S32 height = gViewerWindow->getWindowDisplayHeight(); S32 height = gViewerWindow->getWindowDisplayHeight();

View File

@@ -965,6 +965,7 @@ void LLViewerRegion::forceUpdate()
void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction) void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
{ {
mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction); mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);
neighborp->mImpl->mLandp->connectNeighbor(mImpl->mLandp, gDirOpposite[direction]);
#if ENABLE_CLASSIC_CLOUDS #if ENABLE_CLASSIC_CLOUDS
mCloudLayer.connectNeighbor(&(neighborp->mCloudLayer), direction); mCloudLayer.connectNeighbor(&(neighborp->mCloudLayer), direction);
#endif #endif

View File

@@ -81,7 +81,6 @@ LLVOGrass::SpeciesNames LLVOGrass::sSpeciesNames;
LLVOGrass::LLVOGrass(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) LLVOGrass::LLVOGrass(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
: LLAlphaObject(id, pcode, regionp) : LLAlphaObject(id, pcode, regionp)
{ {
mPatch = NULL;
mLastPatchUpdateTime = 0; mLastPatchUpdateTime = 0;
mGrassVel.clearVec(); mGrassVel.clearVec();
mGrassBend.clearVec(); mGrassBend.clearVec();
@@ -331,7 +330,8 @@ void LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
return; return;
} }
if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) const auto& patch = mPatch.lock();
if (patch && (mLastPatchUpdateTime != patch->getLastUpdateTime()))
{ {
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
} }
@@ -507,9 +507,10 @@ void LLVOGrass::getGeometry(S32 idx,
return ; return ;
} }
mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); const auto& patch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
if (mPatch) if (patch)
mLastPatchUpdateTime = mPatch->getLastUpdateTime(); mLastPatchUpdateTime = patch->getLastUpdateTime();
mPatch = patch;
LLVector3 position; LLVector3 position;
// Create random blades of grass with gaussian distribution // Create random blades of grass with gaussian distribution

View File

@@ -108,7 +108,7 @@ public:
F32 mBladeSizeX; F32 mBladeSizeX;
F32 mBladeSizeY; F32 mBladeSizeY;
LLSurfacePatch *mPatch; // Stores the land patch where the grass is centered std::weak_ptr<LLSurfacePatch> mPatch; // Stores the land patch where the grass is centered
U64 mLastPatchUpdateTime; U64 mLastPatchUpdateTime;

View File

@@ -267,18 +267,19 @@ BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
length = patch_width / render_stride; length = patch_width / render_stride;
if (mPatchp->getNeighborPatch(NORTH)) LLSurfacePatch* neighborPatch;
if (neighborPatch = mPatchp->getNeighborPatch(NORTH))
{ {
north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride(); north_stride = neighborPatch->getRenderStride();
} }
else else
{ {
north_stride = render_stride; north_stride = render_stride;
} }
if (mPatchp->getNeighborPatch(EAST)) if (neighborPatch = mPatchp->getNeighborPatch(EAST))
{ {
east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride(); east_stride = neighborPatch->getRenderStride();
} }
else else
{ {

View File

@@ -5569,15 +5569,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
else else
{ {
if( type == LLDrawPool::POOL_FULLBRIGHT || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK)
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
}
//Annoying exception to the rule. getPoolTypeFromTE will return POOL_ALPHA_MASK for legacy bumpmaps, but there is no POOL_ALPHA_MASK in deferred. //Annoying exception to the rule. getPoolTypeFromTE will return POOL_ALPHA_MASK for legacy bumpmaps, but there is no POOL_ALPHA_MASK in deferred.
else if(type == LLDrawPool::POOL_MATERIALS || (type == LLDrawPool::POOL_ALPHA_MASK && mat)) if (type == LLDrawPool::POOL_MATERIALS || ((type == LLDrawPool::POOL_ALPHA_MASK || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) && mat))
{ {
pool->addRiggedFace(facep, mat->getShaderMask()); pool->addRiggedFace(facep, mat->getShaderMask());
} }
else if (type == LLDrawPool::POOL_FULLBRIGHT || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK)
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
}
else if (type == LLDrawPool::POOL_BUMP && te->getBumpmap()) else if (type == LLDrawPool::POOL_BUMP && te->getBumpmap())
{ {
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
@@ -5674,7 +5674,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
type = LLDrawPool::POOL_FULLBRIGHT; type = LLDrawPool::POOL_FULLBRIGHT;
} }
} }
else if(force_simple && type != LLDrawPool::POOL_FULLBRIGHT && type != LLDrawPool::POOL_ALPHA_MASK && type != LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) else if(force_simple && type != LLDrawPool::POOL_FULLBRIGHT && (!LLPipeline::sRenderDeferred && (type != LLDrawPool::POOL_ALPHA_MASK && type != LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK)))
{ {
type = LLDrawPool::POOL_SIMPLE; type = LLDrawPool::POOL_SIMPLE;
} }

View File

@@ -673,7 +673,7 @@ LLSurfacePatch * LLWorld::resolveLandPatchGlobal(const LLVector3d &pos_global)
return NULL; return NULL;
} }
return regionp->getLand().resolvePatchGlobal(pos_global); return regionp->getLand().resolvePatchGlobal(pos_global).get();
} }

View File

@@ -2667,6 +2667,9 @@ void LLPipeline::clearRebuildGroups()
iter != mGroupQ2.end(); ++iter) iter != mGroupQ2.end(); ++iter)
{ {
LLSpatialGroup* group = *iter; LLSpatialGroup* group = *iter;
if (group == nullptr) {
LL_WARNS() << "Null spatial group in Pipeline::mGroupQ2." << LL_ENDL;
}
// If the group contains HUD objects, save the group // If the group contains HUD objects, save the group
if (group->isHUDGroup()) if (group->isHUDGroup())