From da3abb4e2e76880da42ad656d8532d0129979d44 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Thu, 11 Jun 2015 22:00:49 +0100 Subject: [PATCH 1/5] Tweak shroud revealing logic The per-actor visibility now tracks all cells inside the map area (including those outside the currently visible bounds), but the shroud/fog is only cleared if the cell is inside the currently visible bounds. --- OpenRA.Game/Map/Map.cs | 12 ++++++++---- OpenRA.Game/Traits/World/Shroud.cs | 13 +++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index c733e3d90e..acbcedc433 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -870,7 +870,7 @@ namespace OpenRA // it rounds the actual distance up to the next integer so that this call // will return any cells that intersect with the requested range circle. // The returned positions are sorted by distance from the center. - public IEnumerable FindTilesInAnnulus(CPos center, int minRange, int maxRange) + public IEnumerable FindTilesInAnnulus(CPos center, int minRange, int maxRange, bool allowOutsideBounds = false) { if (maxRange < minRange) throw new ArgumentOutOfRangeException("maxRange", "Maximum range is less than the minimum range."); @@ -878,20 +878,24 @@ namespace OpenRA if (maxRange > TilesByDistance.Length) throw new ArgumentOutOfRangeException("maxRange", "The requested range ({0}) exceeds the maximum allowed ({1})".F(maxRange, MaxTilesInCircleRange)); + Func valid = Contains; + if (allowOutsideBounds) + valid = MapTiles.Value.Contains; + for (var i = minRange; i <= maxRange; i++) { foreach (var offset in TilesByDistance[i]) { var t = offset + center; - if (Contains(t)) + if (valid(t)) yield return t; } } } - public IEnumerable FindTilesInCircle(CPos center, int maxRange) + public IEnumerable FindTilesInCircle(CPos center, int maxRange, bool allowOutsideBounds = false) { - return FindTilesInAnnulus(center, 0, maxRange); + return FindTilesInAnnulus(center, 0, maxRange, allowOutsideBounds); } } } diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 3c718ec491..452bea039f 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -112,7 +112,7 @@ namespace OpenRA.Traits var limit = radius.RangeSquared; var pos = map.CenterOfCell(position); - foreach (var cell in map.FindTilesInCircle(position, r)) + foreach (var cell in map.FindTilesInCircle(position, r, true)) if ((map.CenterOfCell(cell) - pos).HorizontalLengthSquared <= limit) yield return cell; } @@ -129,6 +129,11 @@ namespace OpenRA.Traits foreach (var c in visible) { var uv = c.ToMPos(map); + + // Force cells outside the visible bounds invisible + if (!map.Contains(uv)) + continue; + visibleCount[uv]++; explored[uv] = true; } @@ -147,7 +152,11 @@ namespace OpenRA.Traits return; foreach (var c in visible) - visibleCount[c.ToMPos(map)]--; + { + // Cells outside the visible bounds don't increment visibleCount + if (map.Contains(c)) + visibleCount[c.ToMPos(map)]--; + } visibility.Remove(a); Invalidate(visible); From aee951c86f3a12ff1c7e7e71d858c4e9268bba01 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 3 May 2015 19:28:07 +1200 Subject: [PATCH 2/5] Remove region assumptions from fast shroud tests. --- OpenRA.Game/Graphics/Minimap.cs | 4 +- OpenRA.Game/Traits/Player/FrozenActorLayer.cs | 12 +++- OpenRA.Game/Traits/World/Shroud.cs | 56 +++++++++---------- OpenRA.Game/World.cs | 34 +++++++---- .../Traits/Modifiers/FrozenUnderFog.cs | 4 +- .../Traits/World/ResourceLayer.cs | 2 +- OpenRA.Mods.Common/Widgets/RadarWidget.cs | 3 + 7 files changed, 66 insertions(+), 49 deletions(-) diff --git a/OpenRA.Game/Graphics/Minimap.cs b/OpenRA.Game/Graphics/Minimap.cs index b0642a4d91..5b011317aa 100644 --- a/OpenRA.Game/Graphics/Minimap.cs +++ b/OpenRA.Game/Graphics/Minimap.cs @@ -180,8 +180,8 @@ namespace OpenRA.Graphics { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; - var shroudObscured = world.ShroudObscuresTest(map.CellsInsideBounds); - var fogObscured = world.FogObscuresTest(map.CellsInsideBounds); + var shroudObscured = world.ShroudObscuresTest; + var fogObscured = world.FogObscuresTest; foreach (var uv in map.CellsInsideBounds.MapCoords) { var bitmapXy = new int2(uv.U - b.Left, uv.V - b.Top); diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs index 20bbc54487..30c7cb3378 100644 --- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs +++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs @@ -42,12 +42,16 @@ namespace OpenRA.Traits public bool NeedRenderables; public bool IsRendering { get; private set; } - public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion, Shroud shroud) + public FrozenActor(Actor self, MPos[] footprint, Shroud shroud) { actor = self; - isVisibleTest = shroud.IsVisibleTest(footprintRegion); + isVisibleTest = shroud.IsVisibleTest; + + // Consider all cells inside the map area (ignoring the current map bounds) + Footprint = footprint + .Where(m => shroud.Contains(m)) + .ToArray(); - Footprint = footprint; CenterPosition = self.CenterPosition; Bounds = self.Bounds; @@ -80,11 +84,13 @@ namespace OpenRA.Traits // Visible = !Footprint.Any(isVisibleTest); Visible = true; foreach (var uv in Footprint) + { if (isVisibleTest(uv)) { Visible = false; break; } + } if (Visible && !wasVisible) NeedRenderables = true; diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 452bea039f..25e04cb5fb 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -44,10 +44,8 @@ namespace OpenRA.Traits static readonly Func TruthPredicate = _ => true; readonly Func shroudEdgeTest; - readonly Func fastExploredTest; - readonly Func slowExploredTest; - readonly Func fastVisibleTest; - readonly Func slowVisibleTest; + readonly Func isExploredTest; + readonly Func isVisibleTest; public Shroud(Actor self) { @@ -67,10 +65,8 @@ namespace OpenRA.Traits fogVisibilities = Exts.Lazy(() => self.TraitsImplementing().ToArray()); shroudEdgeTest = map.Contains; - fastExploredTest = IsExploredCore; - slowExploredTest = IsExplored; - fastVisibleTest = IsVisibleCore; - slowVisibleTest = IsVisible; + isExploredTest = IsExploredCore; + isVisibleTest = IsVisibleCore; } void Invalidate(IEnumerable changed) @@ -329,18 +325,16 @@ namespace OpenRA.Traits return explored[uv] && (generatedShroudCount[uv] == 0 || visibleCount[uv] > 0); } - public Func IsExploredTest(CellRegion region) + public Func IsExploredTest { - // If the region to test extends outside the map we must use the slow test that checks the map boundary every time. - if (!map.CellsInsideBounds.Contains(region)) - return slowExploredTest; + get + { + // If shroud isn't enabled, then we can see everything inside the map. + if (!ShroudEnabled) + return shroudEdgeTest; - // If shroud isn't enabled, then we can see everything inside the map. - if (!ShroudEnabled) - return shroudEdgeTest; - - // If shroud is enabled, we can use the fast test that just does the core check. - return fastExploredTest; + return isExploredTest; + } } public bool IsExplored(Actor a) @@ -377,18 +371,17 @@ namespace OpenRA.Traits return visibleCount[uv] > 0; } - public Func IsVisibleTest(CellRegion region) + public Func IsVisibleTest { - // If the region to test extends outside the map we must use the slow test that checks the map boundary every time. - if (!map.CellsInsideBounds.Contains(region)) - return slowVisibleTest; + get + { + // If fog isn't enabled, then we can see everything. + if (!FogEnabled) + return TruthPredicate; - // If fog isn't enabled, then we can see everything. - if (!FogEnabled) - return TruthPredicate; - - // If fog is enabled, we can use the fast test that just does the core check. - return fastVisibleTest; + // If fog is enabled, we can use the fast test that just does the core check. + return isVisibleTest; + } } // Actors are hidden under shroud, but not under fog by default @@ -415,5 +408,12 @@ namespace OpenRA.Traits { return fogVisibilities.Value.Any(f => f.HasFogVisibility(self.Owner)); } + + public bool Contains(MPos uv) + { + // Check that uv is inside the map area. There is nothing special + // about explored here: any of the CellLayers would have been suitable. + return explored.Contains(uv); + } } } diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 674d76a3b4..7ec04d1f72 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -73,27 +73,37 @@ namespace OpenRA public bool FogObscures(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(a); } public bool FogObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(p); } public bool FogObscures(WPos pos) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(pos); } + public bool FogObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(uv); } + public bool ShroudObscures(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(a); } public bool ShroudObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(p); } public bool ShroudObscures(WPos pos) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(pos); } public bool ShroudObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(uv); } - public Func FogObscuresTest(CellRegion region) + public Func FogObscuresTest { - var rp = RenderPlayer; - if (rp == null) - return FalsePredicate; - var predicate = rp.Shroud.IsVisibleTest(region); - return uv => !predicate(uv); + get + { + var rp = RenderPlayer; + if (rp == null) + return FalsePredicate; + + var predicate = rp.Shroud.IsVisibleTest; + return uv => !predicate(uv); + } } - public Func ShroudObscuresTest(CellRegion region) + public Func ShroudObscuresTest { - var rp = RenderPlayer; - if (rp == null) - return FalsePredicate; - var predicate = rp.Shroud.IsExploredTest(region); - return uv => !predicate(uv); + get + { + var rp = RenderPlayer; + if (rp == null) + return FalsePredicate; + + var predicate = rp.Shroud.IsExploredTest; + return uv => !predicate(uv); + } } public bool IsReplay diff --git a/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs b/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs index 64fedb9817..154c852257 100644 --- a/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs +++ b/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs @@ -30,7 +30,6 @@ namespace OpenRA.Mods.Common.Traits readonly bool startsRevealed; readonly MPos[] footprint; - readonly CellRegion footprintRegion; readonly Lazy tooltip; readonly Lazy health; @@ -46,7 +45,6 @@ namespace OpenRA.Mods.Common.Traits startsRevealed = info.StartsRevealed && !init.Contains(); var footprintCells = FootprintUtils.Tiles(init.Self).ToList(); footprint = footprintCells.Select(cell => cell.ToMPos(init.World.Map)).ToArray(); - footprintRegion = CellRegion.BoundingRegion(init.World.Map.TileShape, footprintCells); tooltip = Exts.Lazy(() => init.Self.TraitsImplementing().FirstOrDefault()); health = Exts.Lazy(() => init.Self.TraitOrDefault()); @@ -71,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits FrozenActor frozenActor; if (!initialized) { - frozen[player] = frozenActor = new FrozenActor(self, footprint, footprintRegion, player.Shroud); + frozen[player] = frozenActor = new FrozenActor(self, footprint, player.Shroud); frozen[player].NeedRenderables = frozenActor.NeedRenderables = startsRevealed; player.PlayerActor.Trait().Add(frozenActor); isVisible = visible[player] |= startsRevealed; diff --git a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs index 5827cdb329..13198a388d 100644 --- a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits public void Render(WorldRenderer wr) { - var shroudObscured = world.ShroudObscuresTest(wr.Viewport.VisibleCells); + var shroudObscured = world.ShroudObscuresTest; foreach (var uv in wr.Viewport.VisibleCells.MapCoords) { if (shroudObscured(uv)) diff --git a/OpenRA.Mods.Common/Widgets/RadarWidget.cs b/OpenRA.Mods.Common/Widgets/RadarWidget.cs index 1b0d2cd500..cba460d644 100644 --- a/OpenRA.Mods.Common/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/RadarWidget.cs @@ -122,6 +122,9 @@ namespace OpenRA.Mods.Common.Widgets void UpdateShroudCell(CPos cell) { + if (!world.Map.Contains(cell)) + return; + var stride = radarSheet.Size.Width; var uv = cell.ToMPos(world.Map); var dx = shroudSprite.Bounds.Left - world.Map.Bounds.Left; From 2156a234db51cb1fcbd14f98d05b0390e1cebfbf Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 15 Jun 2015 17:57:04 +0100 Subject: [PATCH 3/5] Render shroud outside map bounds. Fixes a regression from #8337. --- OpenRA.Game/Graphics/TerrainRenderer.cs | 2 +- OpenRA.Game/Graphics/TerrainSpriteLayer.cs | 6 +- OpenRA.Game/Graphics/Viewport.cs | 81 ++++++++++++------- .../Traits/World/EditorResourceLayer.cs | 2 +- .../Traits/World/PathfinderDebugOverlay.cs | 2 +- .../Traits/World/ResourceLayer.cs | 2 +- .../Traits/World/ShroudRenderer.cs | 4 +- .../Traits/World/SmudgeLayer.cs | 2 +- .../Traits/World/TerrainGeometryOverlay.cs | 2 +- .../Traits/World/BuildableTerrainLayer.cs | 2 +- 10 files changed, 66 insertions(+), 39 deletions(-) diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index 07bf276e91..a7d62c1f58 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -24,7 +24,7 @@ namespace OpenRA.Graphics theater = wr.Theater; mapTiles = world.Map.MapTiles.Value; - terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, wr.Palette("terrain")); + terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, wr.Palette("terrain"), true); foreach (var cell in world.Map.AllCells) UpdateCell(cell); diff --git a/OpenRA.Game/Graphics/TerrainSpriteLayer.cs b/OpenRA.Game/Graphics/TerrainSpriteLayer.cs index 14d8b1ba4e..bf828bbc36 100644 --- a/OpenRA.Game/Graphics/TerrainSpriteLayer.cs +++ b/OpenRA.Game/Graphics/TerrainSpriteLayer.cs @@ -25,6 +25,7 @@ namespace OpenRA.Graphics readonly Vertex[] vertices; readonly HashSet dirtyRows = new HashSet(); readonly int rowStride; + readonly bool restrictToBounds; readonly WorldRenderer worldRenderer; readonly Map map; @@ -34,9 +35,10 @@ namespace OpenRA.Graphics float paletteIndex; - public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette) + public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette, bool restrictToBounds) { worldRenderer = wr; + this.restrictToBounds = restrictToBounds; this.sheet = sheet; this.blendMode = blendMode; paletteIndex = palette.TextureIndex; @@ -92,7 +94,7 @@ namespace OpenRA.Graphics public void Draw(Viewport viewport) { - var cells = viewport.VisibleCells; + var cells = restrictToBounds ? viewport.VisibleCellsInsideBounds : viewport.AllVisibleCells; // Only draw the rows that are visible. var firstRow = cells.MapCoords.TopLeft.V; diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index cf5b369780..1b5ab1444f 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -53,6 +53,9 @@ namespace OpenRA.Graphics CellRegion cells; bool cellsDirty = true; + CellRegion allCells; + bool allCellsDirty = true; + float zoom = 1f; public float Zoom { @@ -66,6 +69,7 @@ namespace OpenRA.Graphics zoom = value; viewportSize = (1f / zoom * new float2(Game.Renderer.Resolution)).ToInt2(); cellsDirty = true; + allCellsDirty = true; } } @@ -187,6 +191,7 @@ namespace OpenRA.Graphics { CenterLocation = worldRenderer.ScreenPxPosition(pos).Clamp(mapBounds); cellsDirty = true; + allCellsDirty = true; } public void Scroll(float2 delta, bool ignoreBorders) @@ -194,6 +199,7 @@ namespace OpenRA.Graphics // Convert scroll delta from world-px to viewport-px CenterLocation += (1f / Zoom * delta).ToInt2(); cellsDirty = true; + allCellsDirty = true; if (!ignoreBorders) CenterLocation = CenterLocation.Clamp(mapBounds); @@ -207,8 +213,8 @@ namespace OpenRA.Graphics { // Visible rectangle in world coordinates (expanded to the corners of the cells) var map = worldRenderer.World.Map; - var ctl = map.CenterOfCell(VisibleCells.TopLeft) - new WVec(512, 512, 0); - var cbr = map.CenterOfCell(VisibleCells.BottomRight) + new WVec(512, 512, 0); + var ctl = map.CenterOfCell(VisibleCellsInsideBounds.TopLeft) - new WVec(512, 512, 0); + var cbr = map.CenterOfCell(VisibleCellsInsideBounds.BottomRight) + new WVec(512, 512, 0); // Convert to screen coordinates var tl = WorldToViewPx(worldRenderer.ScreenPxPosition(ctl - new WVec(0, 0, ctl.Z))).Clamp(ScreenClip); @@ -220,42 +226,61 @@ namespace OpenRA.Graphics } } - public CellRegion VisibleCells + CellRegion CalculateVisibleCells(bool insideBounds) + { + var map = worldRenderer.World.Map; + var wtl = worldRenderer.Position(TopLeft); + var wbr = worldRenderer.Position(BottomRight); + + // Map editor shows the full map (including the area outside the regular bounds) + Func clamp = map.Clamp; + if (!insideBounds) + clamp = map.MapTiles.Value.Clamp; + + // Due to diamond tile staggering, we need to adjust the top-left bounds outwards by half a cell. + if (map.TileShape == TileShape.Diamond) + wtl -= new WVec(512, 512, 0); + + // Visible rectangle in map coordinates. + var dy = map.TileShape == TileShape.Diamond ? 512 : 1024; + var ctl = new MPos(wtl.X / 1024, wtl.Y / dy); + var cbr = new MPos(wbr.X / 1024, wbr.Y / dy); + + var tl = clamp(ctl).ToCPos(map.TileShape); + + // Also need to account for height of cells in rows below the bottom. + var heightPadding = map.TileShape == TileShape.Diamond ? 3 : 0; + var br = clamp(new MPos(cbr.U, cbr.V + heightPadding + maxGroundHeight / 2 + 1)).ToCPos(map.TileShape); + + return new CellRegion(map.TileShape, tl, br); + } + + public CellRegion VisibleCellsInsideBounds { get { if (cellsDirty) { - var map = worldRenderer.World.Map; - var wtl = worldRenderer.Position(TopLeft); - var wbr = worldRenderer.Position(BottomRight); - - // Map editor shows the full map (including the area outside the regular bounds) - Func clamp = map.Clamp; - if (worldRenderer.World.Type == WorldType.Editor) - clamp = map.MapTiles.Value.Clamp; - - // Due to diamond tile staggering, we need to adjust the top-left bounds outwards by half a cell. - if (map.TileShape == TileShape.Diamond) - wtl -= new WVec(512, 512, 0); - - // Visible rectangle in map coordinates. - var dy = map.TileShape == TileShape.Diamond ? 512 : 1024; - var ctl = new MPos(wtl.X / 1024, wtl.Y / dy); - var cbr = new MPos(wbr.X / 1024, wbr.Y / dy); - - var tl = clamp(ctl).ToCPos(map.TileShape); - - // Also need to account for height of cells in rows below the bottom. - var heightPadding = map.TileShape == TileShape.Diamond ? 3 : 0; - var br = clamp(new MPos(cbr.U, cbr.V + heightPadding + maxGroundHeight / 2 + 1)).ToCPos(map.TileShape); - - cells = new CellRegion(map.TileShape, tl, br); + cells = CalculateVisibleCells(worldRenderer.World.Type != WorldType.Editor); cellsDirty = false; } return cells; } } + + public CellRegion AllVisibleCells + { + get + { + if (allCellsDirty) + { + allCells = CalculateVisibleCells(false); + allCellsDirty = false; + } + + return allCells; + } + } } } \ No newline at end of file diff --git a/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs index f90f549466..2c9a49922e 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs @@ -146,7 +146,7 @@ namespace OpenRA.Mods.Common.Traits Dirty.Clear(); - foreach (var uv in wr.Viewport.VisibleCells.MapCoords) + foreach (var uv in wr.Viewport.VisibleCellsInsideBounds.MapCoords) { var t = Tiles[uv]; if (t.Sprite != null) diff --git a/OpenRA.Mods.Common/Traits/World/PathfinderDebugOverlay.cs b/OpenRA.Mods.Common/Traits/World/PathfinderDebugOverlay.cs index 3fff22448b..102cc53000 100644 --- a/OpenRA.Mods.Common/Traits/World/PathfinderDebugOverlay.cs +++ b/OpenRA.Mods.Common/Traits/World/PathfinderDebugOverlay.cs @@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits var layer = pair.Value; // Only render quads in viewing range: - foreach (var cell in wr.Viewport.VisibleCells) + foreach (var cell in wr.Viewport.VisibleCellsInsideBounds) { if (layer[cell] <= 0) continue; diff --git a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs index 13198a388d..a6d2c9e329 100644 --- a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits public void Render(WorldRenderer wr) { var shroudObscured = world.ShroudObscuresTest; - foreach (var uv in wr.Viewport.VisibleCells.MapCoords) + foreach (var uv in wr.Viewport.VisibleCellsInsideBounds.MapCoords) { if (shroudObscured(uv)) continue; diff --git a/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs b/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs index c08c3a010e..6a32bfdad9 100644 --- a/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs +++ b/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs @@ -189,8 +189,8 @@ namespace OpenRA.Mods.Common.Traits if (fogSprites.Any(s => s.BlendMode != fogBlend)) throw new InvalidDataException("Fog sprites must all use the same blend mode."); - shroudLayer = new TerrainSpriteLayer(w, wr, shroudSheet, shroudBlend, wr.Palette(info.ShroudPalette)); - fogLayer = new TerrainSpriteLayer(w, wr, fogSheet, fogBlend, wr.Palette(info.FogPalette)); + shroudLayer = new TerrainSpriteLayer(w, wr, shroudSheet, shroudBlend, wr.Palette(info.ShroudPalette), false); + fogLayer = new TerrainSpriteLayer(w, wr, fogSheet, fogBlend, wr.Palette(info.FogPalette), false); } Edges GetEdges(MPos uv, Func isVisible) diff --git a/OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs b/OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs index 90b80645b3..0711a7f1c2 100644 --- a/OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs @@ -144,7 +144,7 @@ namespace OpenRA.Mods.Common.Traits foreach (var kv in tiles) { - if (!wr.Viewport.VisibleCells.Contains(kv.Key)) + if (!wr.Viewport.VisibleCellsInsideBounds.Contains(kv.Key)) continue; if (world.ShroudObscures(kv.Key)) diff --git a/OpenRA.Mods.Common/Traits/World/TerrainGeometryOverlay.cs b/OpenRA.Mods.Common/Traits/World/TerrainGeometryOverlay.cs index d6fe424846..391ed0045d 100644 --- a/OpenRA.Mods.Common/Traits/World/TerrainGeometryOverlay.cs +++ b/OpenRA.Mods.Common/Traits/World/TerrainGeometryOverlay.cs @@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits var colors = wr.World.TileSet.HeightDebugColors; var mouseCell = wr.Viewport.ViewToWorld(Viewport.LastMousePos).ToMPos(wr.World.Map); - foreach (var uv in wr.Viewport.VisibleCells.MapCoords) + foreach (var uv in wr.Viewport.VisibleCellsInsideBounds.MapCoords) { var height = (int)map.MapHeight.Value[uv]; var tile = map.MapTiles.Value[uv]; diff --git a/OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs b/OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs index 50ef007822..39f4481a93 100644 --- a/OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs +++ b/OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs @@ -64,7 +64,7 @@ namespace OpenRA.Mods.D2k.Traits foreach (var kv in tiles) { - if (!wr.Viewport.VisibleCells.Contains(kv.Key)) + if (!wr.Viewport.VisibleCellsInsideBounds.Contains(kv.Key)) continue; if (wr.World.ShroudObscures(kv.Key)) From 6738b8b977a92ff9c5737a021ea901131a23df21 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 15 Jun 2015 18:00:50 +0100 Subject: [PATCH 4/5] Undo an invalid optimisation. Fixes a regression from #7746. --- OpenRA.Game/Traits/Player/FrozenActorLayer.cs | 5 +++-- OpenRA.Game/Traits/World/Shroud.cs | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs index 30c7cb3378..b1330efcae 100644 --- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs +++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs @@ -28,7 +28,7 @@ namespace OpenRA.Traits public readonly WPos CenterPosition; public readonly Rectangle Bounds; readonly Actor actor; - readonly Func isVisibleTest; + readonly Shroud shroud; public Player Owner; @@ -45,7 +45,7 @@ namespace OpenRA.Traits public FrozenActor(Actor self, MPos[] footprint, Shroud shroud) { actor = self; - isVisibleTest = shroud.IsVisibleTest; + this.shroud = shroud; // Consider all cells inside the map area (ignoring the current map bounds) Footprint = footprint @@ -79,6 +79,7 @@ namespace OpenRA.Traits void UpdateVisibility() { var wasVisible = Visible; + var isVisibleTest = shroud.IsVisibleTest; // We are doing the following LINQ manually for performance since this is a hot path. // Visible = !Footprint.Any(isVisibleTest); diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 25e04cb5fb..cde61a26aa 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -325,6 +325,11 @@ namespace OpenRA.Traits return explored[uv] && (generatedShroudCount[uv] == 0 || visibleCount[uv] > 0); } + /// + /// Returns a fast exploration lookup that skips the usual validation. + /// The return value should not be cached across ticks, and should not + /// be called with cells outside the map bounds. + /// public Func IsExploredTest { get @@ -371,6 +376,11 @@ namespace OpenRA.Traits return visibleCount[uv] > 0; } + /// + /// Returns a fast visibility lookup that skips the usual validation. + /// The return value should not be cached across ticks, and should not + /// be called with cells outside the map bounds. + /// public Func IsVisibleTest { get From c44afc072224198f5298a4d0a0c804d909d43dc4 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 16 Jun 2015 08:16:49 +0100 Subject: [PATCH 5/5] Remove viewport editor-mode assumptions. --- OpenRA.Game/Graphics/TerrainRenderer.cs | 4 +++- OpenRA.Game/Graphics/Viewport.cs | 2 +- OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index a7d62c1f58..1f6a123159 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -24,7 +24,9 @@ namespace OpenRA.Graphics theater = wr.Theater; mapTiles = world.Map.MapTiles.Value; - terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, wr.Palette("terrain"), true); + terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, + wr.Palette("terrain"), wr.World.Type != WorldType.Editor); + foreach (var cell in world.Map.AllCells) UpdateCell(cell); diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 1b5ab1444f..a155529302 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -261,7 +261,7 @@ namespace OpenRA.Graphics { if (cellsDirty) { - cells = CalculateVisibleCells(worldRenderer.World.Type != WorldType.Editor); + cells = CalculateVisibleCells(false); cellsDirty = false; } diff --git a/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs index 2c9a49922e..5f5f2c2e5c 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs @@ -146,7 +146,7 @@ namespace OpenRA.Mods.Common.Traits Dirty.Clear(); - foreach (var uv in wr.Viewport.VisibleCellsInsideBounds.MapCoords) + foreach (var uv in wr.Viewport.AllVisibleCells.MapCoords) { var t = Tiles[uv]; if (t.Sprite != null)