diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs index 32d24f3bca..7bfee01e01 100644 --- a/OpenRa.Game/Graphics/WorldRenderer.cs +++ b/OpenRa.Game/Graphics/WorldRenderer.cs @@ -100,16 +100,13 @@ namespace OpenRa.Game.Graphics lineRenderer.Flush(); - renderer.DrawText(string.Format("RenderFrame {0} ({2:F1} ms)\nTick {1} ({3:F1} ms)\nOre ({4:F1} ms)\nNormal Pathing ({5:F1} ms\t[{9} paths])\nPathToPath ({6:F1}\t[{8} paths])\n$ {7}", + renderer.DrawText(string.Format("RenderFrame {0} ({2:F1} ms)\nTick {1} ({3:F1} ms)\nOre ({4:F1} ms)\n$ {5}\nTiles Expanded {6:F0}", Game.RenderFrame, Game.orderManager.FrameNumber, Game.RenderTime * 1000, Game.TickTime * 1000, Game.OreTime * 1000, - Game.NormalPathTime * 1000, - Game.PathToPathTime * 1000, Game.LocalPlayer.Cash, - Game.PathToPathCount, - Game.NormalPathCount + PerfHistory.items[ "nodes_expanded" ].LastValue ), new int2(5, 5), Color.White); PerfHistory.Render(renderer, lineRenderer); diff --git a/OpenRa.Game/PathFinder.cs b/OpenRa.Game/PathFinder.cs index e272773d5f..12db57d583 100644 --- a/OpenRa.Game/PathFinder.cs +++ b/OpenRa.Game/PathFinder.cs @@ -10,7 +10,7 @@ namespace OpenRa.Game { class PathFinder { - double[][,] passableCost = new double[4][,]; + float[][,] passableCost = new float[4][,]; Map map; public PathFinder(Map map, TileSet tileSet) @@ -18,13 +18,13 @@ namespace OpenRa.Game this.map = map; for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++) - passableCost[(int)umt] = new double[128, 128]; + passableCost[(int)umt] = new float[128, 128]; for( int x = 0 ; x < 128 ; x++ ) for( int y = 0 ; y < 128 ; y++ ) for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ ) passableCost[(int)umt][ x, y ] = ( map.IsInMap( x, y ) ) - ? TerrainCosts.Cost( umt, tileSet.GetWalkability( map.MapTiles[ x, y ] ) ) - : double.PositiveInfinity; + ? (float)TerrainCosts.Cost( umt, tileSet.GetWalkability( map.MapTiles[ x, y ] ) ) + : float.PositiveInfinity; } public List FindUnitPath(int2 src, int2 dest, UnitMovementType umt) @@ -32,7 +32,7 @@ namespace OpenRa.Game using (new PerfSample("find_unit_path")) { var sw = new Stopwatch(); - /*if (passableCost[(int)umt][dest.X, dest.Y] == double.PositiveInfinity) + /*if (passableCost[(int)umt][dest.X, dest.Y] == float.PositiveInfinity) return new List(); if (!Game.BuildingInfluence.CanMoveHere(dest)) return new List();*/ @@ -56,15 +56,27 @@ namespace OpenRa.Game public List FindPathToPath( int2 from, List path, UnitMovementType umt ) { - var sw = new Stopwatch(); using (new PerfSample("find_path_to_path")) { + var anyMovePossible = false; + for( int v = -1; v < 2; v++ ) + for( int u = -1; u < 2; u++ ) + if (u != 0 || v != 0) + { + var p = from + new int2(u, v); + if (passableCost[(int)umt][from.X + u, from.Y + v] < float.PositiveInfinity) + if (Game.BuildingInfluence.CanMoveHere(p) && (Game.UnitInfluence.GetUnitAt(p) == null)) + anyMovePossible = true; + } - CellInfo[,] cellInfo = null;// var cellInfo = InitCellInfo(); + if (!anyMovePossible) + return new List(); + + CellInfo[,] cellInfo = null; var queue = new PriorityQueue(); var estimator = DefaultEstimator(from); - var cost = 0.0; + var cost = 0.0f; var prev = path[0]; for (int i = 0; i < path.Count; i++) { @@ -78,24 +90,22 @@ namespace OpenRa.Game cellInfo[sl.X, sl.Y] = new CellInfo(cost, prev, false); } var d = sl - prev; - cost += ((d.X * d.Y != 0) ? 1.414213563 : 1.0) * passableCost[(int)umt][sl.X, sl.Y]; + cost += ((d.X * d.Y != 0) ? 1.414213563f : 1.0f) * passableCost[(int)umt][sl.X, sl.Y]; prev = sl; } if (queue.Empty) return new List(); var ret = FindPath(cellInfo, queue, estimator, umt, true); ret.Reverse(); - Game.PathToPathTime += sw.ElapsedTime(); - Game.PathToPathCount++; return ret; } } - public List FindUnitPath( int2 unitLocation, Func estimator, UnitMovementType umt ) + public List FindUnitPath( int2 unitLocation, Func estimator, UnitMovementType umt ) { return FindUnitPath( new[] { unitLocation }, estimator, umt ); } - public List FindUnitPath( IEnumerable startLocations, Func estimator, UnitMovementType umt ) + public List FindUnitPath( IEnumerable startLocations, Func estimator, UnitMovementType umt ) { var cellInfo = InitCellInfo(); var queue = new PriorityQueue(); @@ -109,8 +119,9 @@ namespace OpenRa.Game return FindPath( cellInfo, queue, estimator, umt, false ); } - List FindPath( CellInfo[ , ] cellInfo, PriorityQueue queue, Func estimator, UnitMovementType umt, bool checkForBlock ) + List FindPath( CellInfo[ , ] cellInfo, PriorityQueue queue, Func estimator, UnitMovementType umt, bool checkForBlock ) { + int samples = 0; using (new PerfSample("find_path_inner")) { while (!queue.Empty) @@ -120,7 +131,12 @@ namespace OpenRa.Game cellInfo[here.X, here.Y].Seen = true; if (estimator(here) == 0.0) + { + PerfHistory.Increment("nodes_expanded", samples * .01); return MakePath(cellInfo, here); + } + + samples++; foreach (int2 d in Util.directions) { @@ -128,18 +144,18 @@ namespace OpenRa.Game if (cellInfo[newHere.X, newHere.Y].Seen) continue; - if (passableCost[(int)umt][newHere.X, newHere.Y] == double.PositiveInfinity) + if (passableCost[(int)umt][newHere.X, newHere.Y] == float.PositiveInfinity) continue; if (!Game.BuildingInfluence.CanMoveHere(newHere)) continue; if (checkForBlock && Game.UnitInfluence.GetUnitAt(newHere) != null) continue; var est = estimator(newHere); - if (est == double.PositiveInfinity) + if (est == float.PositiveInfinity) continue; - double cellCost = ((d.X * d.Y != 0) ? 1.414213563 : 1.0) * passableCost[(int)umt][newHere.X, newHere.Y]; - double newCost = cellInfo[here.X, here.Y].MinCost + cellCost; + float cellCost = ((d.X * d.Y != 0) ? 1.414213563f : 1.0f) * passableCost[(int)umt][newHere.X, newHere.Y]; + float newCost = cellInfo[here.X, here.Y].MinCost + cellCost; if (newCost >= cellInfo[newHere.X, newHere.Y].MinCost) continue; @@ -151,6 +167,7 @@ namespace OpenRa.Game } } + PerfHistory.Increment("nodes_expanded", samples * .01); // no path exists return new List(); } @@ -161,7 +178,7 @@ namespace OpenRa.Game var cellInfo = new CellInfo[ 128, 128 ]; for( int x = 0 ; x < 128 ; x++ ) for( int y = 0 ; y < 128 ; y++ ) - cellInfo[ x, y ] = new CellInfo( double.PositiveInfinity, new int2( x, y ), false ); + cellInfo[ x, y ] = new CellInfo( float.PositiveInfinity, new int2( x, y ), false ); return cellInfo; } @@ -181,25 +198,25 @@ namespace OpenRa.Game return ret; } - static Func DefaultEstimator(int2 destination) + static Func DefaultEstimator(int2 destination) { return here => { int2 d = ( here - destination ).Abs(); int diag = Math.Min( d.X, d.Y ); int straight = Math.Abs( d.X - d.Y ); - return 1.5 * diag + straight; + return 1.5f * diag + straight; }; } } struct CellInfo { - public double MinCost; + public float MinCost; public int2 Path; public bool Seen; - public CellInfo( double minCost, int2 path, bool seen ) + public CellInfo( float minCost, int2 path, bool seen ) { MinCost = minCost; Path = path; @@ -209,10 +226,10 @@ namespace OpenRa.Game struct PathDistance : IComparable { - public double EstTotal; + public float EstTotal; public int2 Location; - public PathDistance(double estTotal, int2 location) + public PathDistance(float estTotal, int2 location) { EstTotal = estTotal; Location = location; diff --git a/OpenRa.Game/Support/PerfHistory.cs b/OpenRa.Game/Support/PerfHistory.cs index c4df92dd22..60954912e1 100644 --- a/OpenRa.Game/Support/PerfHistory.cs +++ b/OpenRa.Game/Support/PerfHistory.cs @@ -13,7 +13,7 @@ namespace OpenRa.Game.Support static readonly Color[] colors = { Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Orange, Color.Fuchsia, Color.Lime, Color.LightBlue }; static int nextColor; - static Cache items = new Cache( + public static Cache items = new Cache( s => { var x = new PerfItem(s, colors[nextColor++]); @@ -90,6 +90,16 @@ namespace OpenRa.Game.Support yield return samples[n]; } } + + public double LastValue + { + get + { + int n = head; + if (--n < 0) n = samples.Length - 1; + return samples[n]; + } + } } class PerfSample : IDisposable diff --git a/OpenRa.Game/Traits/Activities/Harvest.cs b/OpenRa.Game/Traits/Activities/Harvest.cs index 19656e9293..df28fc6d67 100644 --- a/OpenRa.Game/Traits/Activities/Harvest.cs +++ b/OpenRa.Game/Traits/Activities/Harvest.cs @@ -77,7 +77,7 @@ namespace OpenRa.Game.Traits.Activities var path = Game.PathFinder.FindUnitPath( self.Location, loc => { - if( Game.UnitInfluence.GetUnitAt( loc ) != null ) return double.PositiveInfinity; + if( Game.UnitInfluence.GetUnitAt( loc ) != null ) return float.PositiveInfinity; return Game.map.ContainsResource( loc ) ? 0 : 1; }, UnitMovementType.Wheel ) .TakeWhile( a => a != self.Location )