diff options
Diffstat (limited to 'indra/newview/llsurfacepatch.cpp')
-rw-r--r-- | indra/newview/llsurfacepatch.cpp | 285 |
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; } } |