Remove region assumptions from fast shroud tests.

This commit is contained in:
Paul Chote
2015-05-03 19:28:07 +12:00
parent da3abb4e2e
commit aee951c86f
7 changed files with 66 additions and 49 deletions

View File

@@ -180,8 +180,8 @@ namespace OpenRA.Graphics
{ {
var colors = (int*)bitmapData.Scan0; var colors = (int*)bitmapData.Scan0;
var stride = bitmapData.Stride / 4; var stride = bitmapData.Stride / 4;
var shroudObscured = world.ShroudObscuresTest(map.CellsInsideBounds); var shroudObscured = world.ShroudObscuresTest;
var fogObscured = world.FogObscuresTest(map.CellsInsideBounds); var fogObscured = world.FogObscuresTest;
foreach (var uv in map.CellsInsideBounds.MapCoords) foreach (var uv in map.CellsInsideBounds.MapCoords)
{ {
var bitmapXy = new int2(uv.U - b.Left, uv.V - b.Top); var bitmapXy = new int2(uv.U - b.Left, uv.V - b.Top);

View File

@@ -42,12 +42,16 @@ namespace OpenRA.Traits
public bool NeedRenderables; public bool NeedRenderables;
public bool IsRendering { get; private set; } 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; 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; CenterPosition = self.CenterPosition;
Bounds = self.Bounds; Bounds = self.Bounds;
@@ -80,11 +84,13 @@ namespace OpenRA.Traits
// Visible = !Footprint.Any(isVisibleTest); // Visible = !Footprint.Any(isVisibleTest);
Visible = true; Visible = true;
foreach (var uv in Footprint) foreach (var uv in Footprint)
{
if (isVisibleTest(uv)) if (isVisibleTest(uv))
{ {
Visible = false; Visible = false;
break; break;
} }
}
if (Visible && !wasVisible) if (Visible && !wasVisible)
NeedRenderables = true; NeedRenderables = true;

View File

@@ -44,10 +44,8 @@ namespace OpenRA.Traits
static readonly Func<MPos, bool> TruthPredicate = _ => true; static readonly Func<MPos, bool> TruthPredicate = _ => true;
readonly Func<MPos, bool> shroudEdgeTest; readonly Func<MPos, bool> shroudEdgeTest;
readonly Func<MPos, bool> fastExploredTest; readonly Func<MPos, bool> isExploredTest;
readonly Func<MPos, bool> slowExploredTest; readonly Func<MPos, bool> isVisibleTest;
readonly Func<MPos, bool> fastVisibleTest;
readonly Func<MPos, bool> slowVisibleTest;
public Shroud(Actor self) public Shroud(Actor self)
{ {
@@ -67,10 +65,8 @@ namespace OpenRA.Traits
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray()); fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
shroudEdgeTest = map.Contains; shroudEdgeTest = map.Contains;
fastExploredTest = IsExploredCore; isExploredTest = IsExploredCore;
slowExploredTest = IsExplored; isVisibleTest = IsVisibleCore;
fastVisibleTest = IsVisibleCore;
slowVisibleTest = IsVisible;
} }
void Invalidate(IEnumerable<CPos> changed) void Invalidate(IEnumerable<CPos> changed)
@@ -329,18 +325,16 @@ namespace OpenRA.Traits
return explored[uv] && (generatedShroudCount[uv] == 0 || visibleCount[uv] > 0); return explored[uv] && (generatedShroudCount[uv] == 0 || visibleCount[uv] > 0);
} }
public Func<MPos, bool> IsExploredTest(CellRegion region) public Func<MPos, bool> IsExploredTest
{
get
{ {
// 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;
// If shroud isn't enabled, then we can see everything inside the map. // If shroud isn't enabled, then we can see everything inside the map.
if (!ShroudEnabled) if (!ShroudEnabled)
return shroudEdgeTest; return shroudEdgeTest;
// If shroud is enabled, we can use the fast test that just does the core check. return isExploredTest;
return fastExploredTest; }
} }
public bool IsExplored(Actor a) public bool IsExplored(Actor a)
@@ -377,18 +371,17 @@ namespace OpenRA.Traits
return visibleCount[uv] > 0; return visibleCount[uv] > 0;
} }
public Func<MPos, bool> IsVisibleTest(CellRegion region) public Func<MPos, bool> IsVisibleTest
{
get
{ {
// 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;
// If fog isn't enabled, then we can see everything. // If fog isn't enabled, then we can see everything.
if (!FogEnabled) if (!FogEnabled)
return TruthPredicate; return TruthPredicate;
// If fog is enabled, we can use the fast test that just does the core check. // If fog is enabled, we can use the fast test that just does the core check.
return fastVisibleTest; return isVisibleTest;
}
} }
// Actors are hidden under shroud, but not under fog by default // 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)); 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);
}
} }
} }

View File

@@ -73,28 +73,38 @@ namespace OpenRA
public bool FogObscures(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(a); } 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(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(p); }
public bool FogObscures(WPos pos) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(pos); } 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(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(a); }
public bool ShroudObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(p); } 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(WPos pos) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(pos); }
public bool ShroudObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(uv); } public bool ShroudObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(uv); }
public Func<MPos, bool> FogObscuresTest(CellRegion region) public Func<MPos, bool> FogObscuresTest
{
get
{ {
var rp = RenderPlayer; var rp = RenderPlayer;
if (rp == null) if (rp == null)
return FalsePredicate; return FalsePredicate;
var predicate = rp.Shroud.IsVisibleTest(region);
var predicate = rp.Shroud.IsVisibleTest;
return uv => !predicate(uv); return uv => !predicate(uv);
} }
}
public Func<MPos, bool> ShroudObscuresTest(CellRegion region) public Func<MPos, bool> ShroudObscuresTest
{
get
{ {
var rp = RenderPlayer; var rp = RenderPlayer;
if (rp == null) if (rp == null)
return FalsePredicate; return FalsePredicate;
var predicate = rp.Shroud.IsExploredTest(region);
var predicate = rp.Shroud.IsExploredTest;
return uv => !predicate(uv); return uv => !predicate(uv);
} }
}
public bool IsReplay public bool IsReplay
{ {

View File

@@ -30,7 +30,6 @@ namespace OpenRA.Mods.Common.Traits
readonly bool startsRevealed; readonly bool startsRevealed;
readonly MPos[] footprint; readonly MPos[] footprint;
readonly CellRegion footprintRegion;
readonly Lazy<IToolTip> tooltip; readonly Lazy<IToolTip> tooltip;
readonly Lazy<Health> health; readonly Lazy<Health> health;
@@ -46,7 +45,6 @@ namespace OpenRA.Mods.Common.Traits
startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>(); startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>();
var footprintCells = FootprintUtils.Tiles(init.Self).ToList(); var footprintCells = FootprintUtils.Tiles(init.Self).ToList();
footprint = footprintCells.Select(cell => cell.ToMPos(init.World.Map)).ToArray(); footprint = footprintCells.Select(cell => cell.ToMPos(init.World.Map)).ToArray();
footprintRegion = CellRegion.BoundingRegion(init.World.Map.TileShape, footprintCells);
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault()); tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>()); health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
@@ -71,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits
FrozenActor frozenActor; FrozenActor frozenActor;
if (!initialized) 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; frozen[player].NeedRenderables = frozenActor.NeedRenderables = startsRevealed;
player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor); player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor);
isVisible = visible[player] |= startsRevealed; isVisible = visible[player] |= startsRevealed;

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
public void Render(WorldRenderer wr) public void Render(WorldRenderer wr)
{ {
var shroudObscured = world.ShroudObscuresTest(wr.Viewport.VisibleCells); var shroudObscured = world.ShroudObscuresTest;
foreach (var uv in wr.Viewport.VisibleCells.MapCoords) foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
{ {
if (shroudObscured(uv)) if (shroudObscured(uv))

View File

@@ -122,6 +122,9 @@ namespace OpenRA.Mods.Common.Widgets
void UpdateShroudCell(CPos cell) void UpdateShroudCell(CPos cell)
{ {
if (!world.Map.Contains(cell))
return;
var stride = radarSheet.Size.Width; var stride = radarSheet.Size.Width;
var uv = cell.ToMPos(world.Map); var uv = cell.ToMPos(world.Map);
var dx = shroudSprite.Bounds.Left - world.Map.Bounds.Left; var dx = shroudSprite.Bounds.Left - world.Map.Bounds.Left;