diff --git a/OpenRA.Mods.Common/Traits/World/PathFinderOverlay.cs b/OpenRA.Mods.Common/Traits/World/PathFinderOverlay.cs index dfec513d72..86d24aed76 100644 --- a/OpenRA.Mods.Common/Traits/World/PathFinderOverlay.cs +++ b/OpenRA.Mods.Common/Traits/World/PathFinderOverlay.cs @@ -153,6 +153,12 @@ namespace OpenRA.Mods.Common.Traits if (!Enabled || forActor == null) yield break; + // Cull edges/costs to the visible viewport region to minimise rendering costs. + // But don't cull the target lines or abstract edges. + // These are long lines and so can easily clip into the region even if both ends are off-screen. + // There's not too many of them, so prefer to render them regardless. + var visibleRegion = wr.Viewport.AllVisibleCells; + foreach (var sourceCell in sourceCells) yield return new TargetLineRenderable(new[] { @@ -160,16 +166,16 @@ namespace OpenRA.Mods.Common.Traits self.World.Map.CenterOfSubCell(targetCell ?? sourceCell, SubCell.FullCell), }, info.TargetLineColor, 8, 8); - foreach (var line in RenderEdges(self, abstractEdges1, 8, 6, info.AbstractColor1)) + foreach (var line in RenderEdges(self, abstractEdges1, 8, 6, info.AbstractColor1, null)) yield return line; - foreach (var line in RenderEdges(self, abstractEdges2, 6, 4, info.AbstractColor2)) + foreach (var line in RenderEdges(self, abstractEdges2, 6, 4, info.AbstractColor2, null)) yield return line; - foreach (var line in RenderEdges(self, localEdges1, 5, 3, info.LocalColor1)) + foreach (var line in RenderEdges(self, localEdges1, 5, 3, info.LocalColor1, visibleRegion)) yield return line; - foreach (var line in RenderEdges(self, localEdges2, 4, 2, info.LocalColor2)) + foreach (var line in RenderEdges(self, localEdges2, 4, 2, info.LocalColor2, visibleRegion)) yield return line; if (!info.ShowCosts) @@ -178,34 +184,41 @@ namespace OpenRA.Mods.Common.Traits const int HorizontalOffset = 320; const int VerticalOffset = 512; - foreach (var line in RenderCosts(self, abstractEdges1, new WVec(-HorizontalOffset, -VerticalOffset, 0), font, info.AbstractColor1)) + foreach (var line in RenderCosts(self, abstractEdges1, new WVec(-HorizontalOffset, -VerticalOffset, 0), font, info.AbstractColor1, visibleRegion)) yield return line; - foreach (var line in RenderCosts(self, abstractEdges2, new WVec(-HorizontalOffset, VerticalOffset, 0), font, info.AbstractColor2)) + foreach (var line in RenderCosts(self, abstractEdges2, new WVec(-HorizontalOffset, VerticalOffset, 0), font, info.AbstractColor2, visibleRegion)) yield return line; - foreach (var line in RenderCosts(self, localEdges1, new WVec(HorizontalOffset, -VerticalOffset, 0), font, info.LocalColor1)) + foreach (var line in RenderCosts(self, localEdges1, new WVec(HorizontalOffset, -VerticalOffset, 0), font, info.LocalColor1, visibleRegion)) yield return line; - foreach (var line in RenderCosts(self, localEdges2, new WVec(HorizontalOffset, VerticalOffset, 0), font, info.LocalColor2)) + foreach (var line in RenderCosts(self, localEdges2, new WVec(HorizontalOffset, VerticalOffset, 0), font, info.LocalColor2, visibleRegion)) yield return line; } - static IEnumerable RenderEdges(Actor self, Record edges, int nodeSize, int edgeSize, Color color) + static IEnumerable RenderEdges(Actor self, Record edges, int nodeSize, int edgeSize, Color color, ProjectedCellRegion visibleRegion) { if (edges == null) yield break; var customColor = CustomLayerColor(color); foreach (var (source, destination, _, _) in edges) + { + var srcUv = (PPos)source.ToMPos(self.World.Map); + var dstUv = (PPos)destination.ToMPos(self.World.Map); + if (visibleRegion != null && !visibleRegion.Contains(srcUv) && !visibleRegion.Contains(dstUv)) + continue; + yield return new TargetLineRenderable(new[] { self.World.Map.CenterOfSubCell(source, SubCell.FullCell) + CustomLayerOffset(source), self.World.Map.CenterOfSubCell(destination, SubCell.FullCell) + CustomLayerOffset(destination), }, destination.Layer == 0 ? color : customColor, edgeSize, nodeSize); + } } - static IEnumerable RenderCosts(Actor self, Record edges, WVec textOffset, SpriteFont font, Color color) + static IEnumerable RenderCosts(Actor self, Record edges, WVec textOffset, SpriteFont font, Color color, ProjectedCellRegion visibleRegion) { if (edges == null) yield break; @@ -213,6 +226,10 @@ namespace OpenRA.Mods.Common.Traits var customColor = CustomLayerColor(color); foreach (var (_, destination, costSoFar, estimatedRemainingCost) in edges) { + var dstUv = (PPos)destination.ToMPos(self.World.Map); + if (!visibleRegion.Contains(dstUv)) + continue; + var centerPos = self.World.Map.CenterOfSubCell(destination, SubCell.FullCell) + CustomLayerOffset(destination) + textOffset; yield return new TextAnnotationRenderable(font, centerPos, 0,