diff options
| author | Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> | 2024-09-25 00:03:28 +0200 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-01-05 20:39:43 +0200 |
| commit | 010d5dcd1feb6df845e97924ebb2d7a6d108ac9e (patch) | |
| tree | 9ede77d39073e51842aa7faf3524fc709db598ef /indra/newview/llviewerparceloverlay.cpp | |
| parent | 112f9b9e226049ca1abaecfaa8a6d1b67506e140 (diff) | |
secondlife/viewer#2674 Optimize LLWorld::renderPropertyLines() - use simplified lines
Diffstat (limited to 'indra/newview/llviewerparceloverlay.cpp')
| -rwxr-xr-x | indra/newview/llviewerparceloverlay.cpp | 171 |
1 files changed, 92 insertions, 79 deletions
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index e36ad0e722..6b4bcbe86e 100755 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -63,9 +63,9 @@ LLUIColor LLViewerParcelOverlay::sForSaleColor; LLUIColor LLViewerParcelOverlay::sAuctionColor; LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters) -: mRegion( region ), - mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ), - mDirty( false ), +: mRegion(region), + mParcelGridsPerEdge(S32(region_width_meters / PARCEL_GRID_STEP_METERS)), + mDirty(false), mTimeSinceLastUpdate(), mOverlayTextureIdx(-1) { @@ -467,9 +467,9 @@ void LLViewerParcelOverlay::updatePropertyLines() { for (S32 col = 0; col < GRIDS_PER_EDGE; col++) { - U8 overlay = mOwnership[row*GRIDS_PER_EDGE+col]; + U8 overlay = mOwnership[row * GRIDS_PER_EDGE + col]; S32 colorIndex = overlay & PARCEL_COLOR_MASK; - switch(colorIndex) + switch (colorIndex) { case PARCEL_SELF: case PARCEL_GROUP: @@ -483,11 +483,11 @@ void LLViewerParcelOverlay::updatePropertyLines() const LLColor4U& color = colors[colorIndex]; - F32 left = col*GRID_STEP; - F32 right = left+GRID_STEP; + F32 left = col * GRID_STEP; + F32 right = left + GRID_STEP; - F32 bottom = row*GRID_STEP; - F32 top = bottom+GRID_STEP; + F32 bottom = row * GRID_STEP; + F32 top = bottom + GRID_STEP; // West edge if (overlay & PARCEL_WEST_LINE) @@ -528,99 +528,107 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3 Edge& edge = mEdges.back(); edge.color = color; + // Detailized rendering vertices: + // A B C D E F G + // *-*------*--------*--------*------*-* : 'outside' vertices are placed right on the border + // *------*--------*--------*------* : 'inside' vertices are shifted on LINE_WIDTH inside + + // Simplified rendering vertices: + // A G + // *-----------------------------------* + // *-----------------------------------* + F32 outside_x = start_x; F32 outside_y = start_y; - F32 outside_z = 0.f; - F32 inside_x = start_x + tick_dx; - F32 inside_y = start_y + tick_dy; - F32 inside_z = 0.f; + F32 outside_z = land.resolveHeightRegion(outside_x, outside_y); + F32 inside_x = start_x + tick_dx; + F32 inside_y = start_y + tick_dy; + F32 inside_z = land.resolveHeightRegion(inside_x, inside_y); - auto split = [&](const LLVector3& start, F32 x, F32 y, F32 z, F32 part) + auto move = [&](F32 distance) + { + outside_x += dx * distance; + outside_y += dy * distance; + outside_z = land.resolveHeightRegion(outside_x, outside_y); + inside_x += dx * distance; + inside_y += dy * distance; + inside_z = land.resolveHeightRegion(inside_x, inside_y); + }; + + auto split = [&](U32 lod, const LLVector3& start, F32 x, F32 y, F32 z, F32 part) { F32 new_x = start.mV[VX] + (x - start.mV[VX]) * part; F32 new_y = start.mV[VY] + (y - start.mV[VY]) * part; F32 new_z = start.mV[VZ] + (z - start.mV[VZ]) * part; - edge.vertices.emplace_back(new_x, new_y, new_z); + edge.vertices[lod].emplace_back(new_x, new_y, new_z); }; - auto checkForSplit = [&]() + auto checkForSplit = [&](U32 lod) { - const LLVector3& last_outside = edge.vertices.back(); + const std::vector<LLVector3>& vertices = edge.vertices[lod]; + const LLVector3& last_outside = vertices.back(); F32 z0 = last_outside.mV[VZ]; F32 z1 = outside_z; if ((z0 >= water_z && z1 >= water_z) || (z0 < water_z && z1 < water_z)) return; F32 part = (water_z - z0) / (z1 - z0); - const LLVector3& last_inside = edge.vertices[edge.vertices.size() - 2]; - split(last_inside, inside_x, inside_y, inside_z, part); - split(last_outside, outside_x, outside_y, outside_z, part); + const LLVector3& last_inside = vertices[vertices.size() - 2]; + split(lod, last_inside, inside_x, inside_y, inside_z, part); + split(lod, last_outside, outside_x, outside_y, outside_z, part); }; - // First part, only one vertex - outside_z = land.resolveHeightRegion( outside_x, outside_y ); - - edge.vertices.emplace_back(outside_x, outside_y, outside_z); - - inside_x += dx * LINE_WIDTH; - inside_y += dy * LINE_WIDTH; - - outside_x += dx * LINE_WIDTH; - outside_y += dy * LINE_WIDTH; - - // Then the "actual edge" - inside_z = land.resolveHeightRegion( inside_x, inside_y ); - outside_z = land.resolveHeightRegion( outside_x, outside_y ); + auto pushTwoVertices = [&](U32 lod) + { + if (fabs(inside_z - outside_z) < LINE_WIDTH / 5) + { + edge.vertices[lod].emplace_back(inside_x, inside_y, inside_z); + } + else + { + // Make the line thinner if heights differ too much + LLVector3 out(outside_x, outside_y, outside_z); + LLVector3 in(inside_x, inside_y, inside_z); + LLVector3 dist(in - out); + F32 coef = dist.length() / LINE_WIDTH; + LLVector3 new_in(out + dist / coef); + edge.vertices[lod].push_back(new_in); + } + edge.vertices[lod].emplace_back(outside_x, outside_y, outside_z); + }; - edge.vertices.emplace_back(inside_x, inside_y, inside_z); - edge.vertices.emplace_back(outside_x, outside_y, outside_z); + // Point A simplified (first two vertices) + pushTwoVertices(1); - inside_x += dx * (dx - LINE_WIDTH); - inside_y += dy * (dy - LINE_WIDTH); + // Point A detailized (only one vertex) + edge.vertices[0].emplace_back(outside_x, outside_y, outside_z); - outside_x += dx * (dx - LINE_WIDTH); - outside_y += dy * (dy - LINE_WIDTH); + // Point B (two vertices) + move(LINE_WIDTH); + pushTwoVertices(0); - // Middle part, full width + // Points C, D, E + F32 distance = 1.f - LINE_WIDTH; constexpr S32 GRID_STEP = (S32)PARCEL_GRID_STEP_METERS; - for (S32 i = 1; i < GRID_STEP; i++) + for (U32 i = 1; i < GRID_STEP; ++i) { - inside_z = land.resolveHeightRegion( inside_x, inside_y ); - outside_z = land.resolveHeightRegion( outside_x, outside_y ); - - checkForSplit(); - - edge.vertices.emplace_back(inside_x, inside_y, inside_z); - edge.vertices.emplace_back(outside_x, outside_y, outside_z); - - inside_x += dx; - inside_y += dy; - - outside_x += dx; - outside_y += dy; + move(distance); + checkForSplit(0); + pushTwoVertices(0); + distance = 1.f; } - // Extra buffer for edge - inside_x -= dx * LINE_WIDTH; - inside_y -= dy * LINE_WIDTH; + // Point F (two vertices) + move(1.f - LINE_WIDTH); + checkForSplit(0); + pushTwoVertices(0); - outside_x -= dx * LINE_WIDTH; - outside_y -= dy * LINE_WIDTH; + // Point G simplified (last two vertices) + move(LINE_WIDTH); + checkForSplit(1); + pushTwoVertices(1); - inside_z = land.resolveHeightRegion( inside_x, inside_y ); - outside_z = land.resolveHeightRegion( outside_x, outside_y ); - - checkForSplit(); - - edge.vertices.emplace_back(inside_x, inside_y, inside_z); - edge.vertices.emplace_back(outside_x, outside_y, outside_z); - - outside_x += dx * LINE_WIDTH; - outside_y += dy * LINE_WIDTH; - - // Last edge is not drawn to the edge - outside_z = land.resolveHeightRegion( outside_x, outside_y ); - - edge.vertices.emplace_back(outside_x, outside_y, outside_z); + // Point G detailized (only one vertex) + edge.vertices[0].emplace_back(outside_x, outside_y, outside_z); } void LLViewerParcelOverlay::setDirty() @@ -712,12 +720,15 @@ void LLViewerParcelOverlay::renderPropertyLines() bool render_hidden = LLSelectMgr::sRenderHiddenSelections && LLFloaterReg::instanceVisible("build"); constexpr F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f; + const F32 PROPERTY_LINE_LOD0_DIST_SQUARED = PROPERTY_LINE_CLIP_DIST_SQUARED / 25; for (const Edge& edge : mEdges) { - LLVector3 center = edge.vertices[edge.vertices.size() >> 1]; + const std::vector<LLVector3>& vertices0 = edge.vertices[0]; + LLVector3 center = (vertices0.front() + vertices0.back()) / 2; + F32 dist_squared = dist_vec_squared(center, camera_region); - if (dist_vec_squared2D(center, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED) + if (dist_squared > PROPERTY_LINE_CLIP_DIST_SQUARED) { continue; } @@ -731,11 +742,13 @@ void LLViewerParcelOverlay::renderPropertyLines() continue; } + U32 lod = dist_squared < PROPERTY_LINE_LOD0_DIST_SQUARED ? 0 : 1; + gGL.begin(LLRender::TRIANGLE_STRIP); gGL.color4ubv(edge.color.mV); - for (const LLVector3& vertex : edge.vertices) + for (const LLVector3& vertex : edge.vertices[lod]) { if (render_hidden || camera_z < water_z || vertex.mV[2] >= water_z) { @@ -761,7 +774,7 @@ void LLViewerParcelOverlay::renderPropertyLines() color.mV[VALPHA] /= 4; gGL.color4ubv(color.mV); - for (const LLVector3& vertex : edge.vertices) + for (const LLVector3& vertex : edge.vertices[lod]) { gGL.vertex3fv(vertex.mV); } |
