summaryrefslogtreecommitdiff
path: root/indra/newview/llsurfacepatch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llsurfacepatch.cpp')
-rw-r--r--indra/newview/llsurfacepatch.cpp285
1 files changed, 226 insertions, 59 deletions
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 449d3d95c8..9703e2ae27 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -47,11 +47,11 @@ extern U64MicrosecondsImplicit gFrameTime;
extern LLPipeline gPipeline;
LLSurfacePatch::LLSurfacePatch()
-: mHasReceivedData(FALSE),
- mSTexUpdate(FALSE),
- mDirty(FALSE),
- mDirtyZStats(TRUE),
- mHeightsGenerated(FALSE),
+: mHasReceivedData(false),
+ mSTexUpdate(false),
+ mDirty(false),
+ mDirtyZStats(true),
+ mHeightsGenerated(false),
mDataOffset(0),
mDataZ(NULL),
mDataNorm(NULL),
@@ -78,7 +78,7 @@ LLSurfacePatch::LLSurfacePatch()
}
for (i = 0; i < 9; i++)
{
- mNormalsInvalid[i] = TRUE;
+ mNormalsInvalid[i] = true;
}
}
@@ -102,12 +102,12 @@ void LLSurfacePatch::dirty()
LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL;
}
- mDirtyZStats = TRUE;
- mHeightsGenerated = FALSE;
+ mDirtyZStats = true;
+ mHeightsGenerated = false;
if (!mDirty)
{
- mDirty = TRUE;
+ mDirty = true;
mSurfacep->dirtySurfacePatch(this);
}
}
@@ -137,7 +137,7 @@ void LLSurfacePatch::disconnectNeighbor(LLSurface *surfacep)
if (getNeighborPatch(i)->mSurfacep == surfacep)
{
setNeighborPatch(i, NULL);
- mNormalsInvalid[i] = TRUE;
+ mNormalsInvalid[i] = true;
}
}
}
@@ -221,7 +221,9 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3
*vertex = pos_agent-mVObjp->getRegion()->getOriginAgent();
LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent();
- LLVector3 tex_pos = rel_pos * (1.f/surface_stride);
+ // *NOTE: Only PBR terrain uses the UVs right now. Texture terrain just ignores it.
+ // *NOTE: In the future, UVs and horizontal position will no longer have a 1:1 relationship for PBR terrain
+ LLVector3 tex_pos = rel_pos;
tex0->mV[0] = tex_pos.mV[0];
tex0->mV[1] = tex_pos.mV[1];
tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y);
@@ -241,7 +243,8 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3
}
-void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
+template<>
+void LLSurfacePatch::calcNormal</*PBR=*/false>(const U32 x, const U32 y, const U32 stride)
{
U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
U32 surface_stride = mSurfacep->getGridsPerEdge();
@@ -354,6 +357,166 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
*(mDataNorm + surface_stride * y + x) = normal;
}
+template<>
+void LLSurfacePatch::calcNormal</*PBR=*/true>(const U32 x, const U32 y, const U32 stride)
+{
+ llassert(mDataNorm);
+ constexpr U32 index = 0;
+
+ const U32 surface_stride = mSurfacep->getGridsPerEdge();
+ LLVector3& normal_out = *(mDataNorm + surface_stride * y + x);
+ calcNormalFlat(normal_out, x, y, index);
+}
+
+// Calculate the flat normal of a triangle whose least coordinate is specified by the given x,y values.
+// If index = 0, calculate the normal of the first triangle, otherwise calculate the normal of the second.
+void LLSurfacePatch::calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index)
+{
+ llassert(index == 0 || index == 1);
+
+ U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
+ U32 surface_stride = mSurfacep->getGridsPerEdge();
+
+ // Vertex stride is always 1 because we want the flat surface of the current triangle face
+ constexpr U32 stride = 1;
+
+ const F32 mpg = mSurfacep->getMetersPerGrid() * stride;
+
+ S32 poffsets[2][2][2];
+ poffsets[0][0][0] = x;
+ poffsets[0][0][1] = y;
+
+ poffsets[0][1][0] = x;
+ poffsets[0][1][1] = y + stride;
+
+ poffsets[1][0][0] = x + stride;
+ poffsets[1][0][1] = y;
+
+ poffsets[1][1][0] = x + stride;
+ poffsets[1][1][1] = y + stride;
+
+ const LLSurfacePatch *ppatches[2][2];
+
+ // LLVector3 p1, p2, p3, p4;
+
+ ppatches[0][0] = this;
+ ppatches[0][1] = this;
+ ppatches[1][0] = this;
+ ppatches[1][1] = this;
+
+ U32 i, j;
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ if (poffsets[i][j][0] < 0)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(WEST))
+ {
+ poffsets[i][j][0] = 0;
+ }
+ else
+ {
+ poffsets[i][j][0] += patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
+ }
+ }
+ if (poffsets[i][j][1] < 0)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(SOUTH))
+ {
+ poffsets[i][j][1] = 0;
+ }
+ else
+ {
+ poffsets[i][j][1] += patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
+ }
+ }
+ if (poffsets[i][j][0] >= (S32)patch_width)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(EAST))
+ {
+ poffsets[i][j][0] = patch_width - 1;
+ }
+ else
+ {
+ poffsets[i][j][0] -= patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
+ }
+ }
+ if (poffsets[i][j][1] >= (S32)patch_width)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(NORTH))
+ {
+ poffsets[i][j][1] = patch_width - 1;
+ }
+ else
+ {
+ poffsets[i][j][1] -= patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
+ }
+ }
+ }
+ }
+
+ LLVector3 p00(-mpg,-mpg,
+ *(ppatches[0][0]->mDataZ
+ + poffsets[0][0][0]
+ + poffsets[0][0][1]*surface_stride));
+ LLVector3 p01(-mpg,+mpg,
+ *(ppatches[0][1]->mDataZ
+ + poffsets[0][1][0]
+ + poffsets[0][1][1]*surface_stride));
+ LLVector3 p10(+mpg,-mpg,
+ *(ppatches[1][0]->mDataZ
+ + poffsets[1][0][0]
+ + poffsets[1][0][1]*surface_stride));
+ LLVector3 p11(+mpg,+mpg,
+ *(ppatches[1][1]->mDataZ
+ + poffsets[1][1][0]
+ + poffsets[1][1][1]*surface_stride));
+
+ // Triangle index / coordinate convention
+ // for a single surface patch
+ //
+ // p01 p11
+ //
+ // ^ ._____.
+ // | |\ |
+ // | | \ 1 |
+ // | | \ |
+ // | 0 \ |
+ // y |____\|
+ //
+ // p00 x ---> p10
+ //
+ // (z up / out of the screen due to right-handed coordinate system)
+
+ LLVector3 normal;
+ if (index == 0)
+ {
+ LLVector3 c1 = p10 - p00;
+ LLVector3 c2 = p01 - p00;
+
+ normal = c1;
+ normal %= c2;
+ normal.normVec();
+ }
+ else // index == 1
+ {
+ LLVector3 c1 = p11 - p01;
+ LLVector3 c2 = p11 - p10;
+
+ normal = c1;
+ normal %= c2;
+ normal.normVec();
+ }
+
+ llassert(&normal_out);
+ normal_out = normal;
+}
+
const LLVector3 &LLSurfacePatch::getNormal(const U32 x, const U32 y) const
{
U32 surface_stride = mSurfacep->getGridsPerEdge();
@@ -440,17 +603,18 @@ void LLSurfacePatch::updateVerticalStats()
mSurfacep->mMaxZ = llmax(mMaxZ, mSurfacep->mMaxZ);
mSurfacep->mMinZ = llmin(mMinZ, mSurfacep->mMinZ);
- mSurfacep->mHasZData = TRUE;
+ mSurfacep->mHasZData = true;
mSurfacep->getRegion()->calculateCenterGlobal();
if (mVObjp)
{
mVObjp->dirtyPatch();
}
- mDirtyZStats = FALSE;
+ mDirtyZStats = false;
}
+template<bool PBR>
void LLSurfacePatch::updateNormals()
{
if (mSurfacep->mType == 'w')
@@ -460,7 +624,7 @@ void LLSurfacePatch::updateNormals()
U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
U32 grids_per_edge = mSurfacep->getGridsPerEdge();
- BOOL dirty_patch = FALSE;
+ bool dirty_patch = false;
U32 i, j;
// update the east edge
@@ -468,12 +632,12 @@ void LLSurfacePatch::updateNormals()
{
for (j = 0; j <= grids_per_patch_edge; j++)
{
- calcNormal(grids_per_patch_edge, j, 2);
- calcNormal(grids_per_patch_edge - 1, j, 2);
- calcNormal(grids_per_patch_edge - 2, j, 2);
+ calcNormal<PBR>(grids_per_patch_edge, j, 2);
+ calcNormal<PBR>(grids_per_patch_edge - 1, j, 2);
+ calcNormal<PBR>(grids_per_patch_edge - 2, j, 2);
}
- dirty_patch = TRUE;
+ dirty_patch = true;
}
// update the north edge
@@ -481,12 +645,12 @@ void LLSurfacePatch::updateNormals()
{
for (i = 0; i <= grids_per_patch_edge; i++)
{
- calcNormal(i, grids_per_patch_edge, 2);
- calcNormal(i, grids_per_patch_edge - 1, 2);
- calcNormal(i, grids_per_patch_edge - 2, 2);
+ calcNormal<PBR>(i, grids_per_patch_edge, 2);
+ calcNormal<PBR>(i, grids_per_patch_edge - 1, 2);
+ calcNormal<PBR>(i, grids_per_patch_edge - 2, 2);
}
- dirty_patch = TRUE;
+ dirty_patch = true;
}
// update the west edge
@@ -494,10 +658,10 @@ void LLSurfacePatch::updateNormals()
{
for (j = 0; j < grids_per_patch_edge; j++)
{
- calcNormal(0, j, 2);
- calcNormal(1, j, 2);
+ calcNormal<PBR>(0, j, 2);
+ calcNormal<PBR>(1, j, 2);
}
- dirty_patch = TRUE;
+ dirty_patch = true;
}
// update the south edge
@@ -505,10 +669,10 @@ void LLSurfacePatch::updateNormals()
{
for (i = 0; i < grids_per_patch_edge; i++)
{
- calcNormal(i, 0, 2);
- calcNormal(i, 1, 2);
+ calcNormal<PBR>(i, 0, 2);
+ calcNormal<PBR>(i, 1, 2);
}
- dirty_patch = TRUE;
+ dirty_patch = true;
}
// Invalidating the northeast corner is different, because depending on what the adjacent neighbors are,
@@ -582,10 +746,10 @@ void LLSurfacePatch::updateNormals()
// We've got a northeast patch in the same surface.
// The z and normals will be handled by that patch.
}
- calcNormal(grids_per_patch_edge, grids_per_patch_edge, 2);
- calcNormal(grids_per_patch_edge, grids_per_patch_edge - 1, 2);
- calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge, 2);
- calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2);
+ calcNormal<PBR>(grids_per_patch_edge, grids_per_patch_edge, 2);
+ calcNormal<PBR>(grids_per_patch_edge, grids_per_patch_edge - 1, 2);
+ calcNormal<PBR>(grids_per_patch_edge - 1, grids_per_patch_edge, 2);
+ calcNormal<PBR>(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2);
dirty_patch = TRUE;
}
@@ -596,10 +760,10 @@ void LLSurfacePatch::updateNormals()
{
for (i=2; i < grids_per_patch_edge - 2; i++)
{
- calcNormal(i, j, 2);
+ calcNormal<PBR>(i, j, 2);
}
}
- dirty_patch = TRUE;
+ dirty_patch = true;
}
if (dirty_patch)
@@ -609,10 +773,13 @@ void LLSurfacePatch::updateNormals()
for (i = 0; i < 9; i++)
{
- mNormalsInvalid[i] = FALSE;
+ mNormalsInvalid[i] = false;
}
}
+template void LLSurfacePatch::updateNormals</*PBR=*/false>();
+template void LLSurfacePatch::updateNormals</*PBR=*/true>();
+
void LLSurfacePatch::updateEastEdge()
{
U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
@@ -677,7 +844,7 @@ void LLSurfacePatch::updateNorthEdge()
}
-BOOL LLSurfacePatch::updateTexture()
+bool LLSurfacePatch::updateTexture()
{
if (mSTexUpdate) // Update texture as needed
{
@@ -700,11 +867,11 @@ BOOL LLSurfacePatch::updateTexture()
if (comp->generateHeights((F32)origin_region[VX], (F32)origin_region[VY],
patch_size, patch_size))
{
- mHeightsGenerated = TRUE;
+ mHeightsGenerated = true;
}
else
{
- return FALSE;
+ return false;
}
}
@@ -718,11 +885,11 @@ BOOL LLSurfacePatch::updateTexture()
}
}
}
- return FALSE;
+ return false;
}
else
{
- return TRUE;
+ return true;
}
}
@@ -739,10 +906,10 @@ void LLSurfacePatch::updateGL()
updateCompositionStats();
F32 tex_patch_size = meters_per_grid*grids_per_patch_edge;
- if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY],
+ if (comp->generateMinimapTileLand((F32)origin_region[VX], (F32)origin_region[VY],
tex_patch_size, tex_patch_size))
{
- mSTexUpdate = FALSE;
+ mSTexUpdate = false;
// Also generate the water texture
mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY],
@@ -752,13 +919,13 @@ void LLSurfacePatch::updateGL()
void LLSurfacePatch::dirtyZ()
{
- mSTexUpdate = TRUE;
+ mSTexUpdate = true;
// Invalidate all normals in this patch
U32 i;
for (i = 0; i < 9; i++)
{
- mNormalsInvalid[i] = TRUE;
+ mNormalsInvalid[i] = true;
}
// Invalidate normals in this and neighboring patches
@@ -766,12 +933,12 @@ void LLSurfacePatch::dirtyZ()
{
if (getNeighborPatch(i))
{
- getNeighborPatch(i)->mNormalsInvalid[gDirOpposite[i]] = TRUE;
+ getNeighborPatch(i)->mNormalsInvalid[gDirOpposite[i]] = true;
getNeighborPatch(i)->dirty();
if (i < 4)
{
- getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = TRUE;
- getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = TRUE;
+ getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = true;
+ getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = true;
}
}
}
@@ -807,7 +974,7 @@ void LLSurfacePatch::setOriginGlobal(const LLVector3d &origin_global)
mCenterRegion.mV[VX] = origin_region.mV[VX] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid();
mCenterRegion.mV[VY] = origin_region.mV[VY] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid();
- mVisInfo.mbIsVisible = FALSE;
+ mVisInfo.mbIsVisible = false;
mVisInfo.mDistance = 512.0f;
mVisInfo.mRenderLevel = 0;
mVisInfo.mRenderStride = mSurfacep->getGridsPerPatchEdge();
@@ -817,8 +984,8 @@ void LLSurfacePatch::setOriginGlobal(const LLVector3d &origin_global)
void LLSurfacePatch::connectNeighbor(LLSurfacePatch *neighbor_patchp, const U32 direction)
{
llassert(neighbor_patchp);
- mNormalsInvalid[direction] = TRUE;
- neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = TRUE;
+ mNormalsInvalid[direction] = true;
+ neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = true;
setNeighborPatch(direction, neighbor_patchp);
neighbor_patchp->setNeighborPatch(gDirOpposite[direction], this);
@@ -909,11 +1076,11 @@ void LLSurfacePatch::updateVisibility()
}
}
}
- mVisInfo.mbIsVisible = TRUE;
+ mVisInfo.mbIsVisible = true;
}
else
{
- mVisInfo.mbIsVisible = FALSE;
+ mVisInfo.mbIsVisible = false;
}
}
@@ -928,7 +1095,7 @@ LLVector3 LLSurfacePatch::getOriginAgent() const
return gAgent.getPosAgentFromGlobal(mOriginGlobal);
}
-BOOL LLSurfacePatch::getVisible() const
+bool LLSurfacePatch::getVisible() const
{
return mVisInfo.mbIsVisible;
}
@@ -945,10 +1112,10 @@ S32 LLSurfacePatch::getRenderLevel() const
void LLSurfacePatch::setHasReceivedData()
{
- mHasReceivedData = TRUE;
+ mHasReceivedData = true;
}
-BOOL LLSurfacePatch::getHasReceivedData() const
+bool LLSurfacePatch::getHasReceivedData() const
{
return mHasReceivedData;
}
@@ -1013,11 +1180,11 @@ F32 LLSurfacePatch::getMaxComposition() const
void LLSurfacePatch::setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp)
{
mNeighborPatches[direction] = neighborp;
- mNormalsInvalid[direction] = TRUE;
+ mNormalsInvalid[direction] = true;
if (direction < 4)
{
- mNormalsInvalid[gDirAdjacent[direction][0]] = TRUE;
- mNormalsInvalid[gDirAdjacent[direction][1]] = TRUE;
+ mNormalsInvalid[gDirAdjacent[direction][0]] = true;
+ mNormalsInvalid[gDirAdjacent[direction][1]] = true;
}
}