Skip to content

Commit

Permalink
#35: working on issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Barsonax committed Oct 31, 2017
1 parent 1ce5ce0 commit e9ed238
Show file tree
Hide file tree
Showing 43 changed files with 413 additions and 509 deletions.
2 changes: 1 addition & 1 deletion AppData.dat
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<startScene dataType="Struct" type="Duality.ContentRef`1[[Duality.Resources.Scene]]">
<contentPath dataType="String">Data\BigMapExample\BigMapExample.Scene.res</contentPath>
</startScene>
<version dataType="UInt">1166</version>
<version dataType="UInt">1172</version>
<websiteUrl dataType="String">http://www.adamslair.net</websiteUrl>
</root>
<!-- XmlFormatterBase Document Separator -->
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ public SourceNodeGrid GenerateGrid2D()
});

Parallel.ForEach(_sourceNodeGrid, gridNode =>
{
{
if (MovementPenalties != null)
{
var index = baseTilemap.Tiles[gridNode.GridX, gridNode.GridY].Index;
var nodeGridCoordinates = _sourceNodeGrid.NodeArray.GetCoordinates(gridNode.Index.Index);
var index = baseTilemap.Tiles[nodeGridCoordinates.X, nodeGridCoordinates.Y].Index;
if (index < MovementPenalties.Length)
gridNode.MovementPenalty = MovementPenalties[index];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Duality.Plugins.Tilemaps;
using Pathfindax.Grid;
using Pathfindax.Nodes;
using Pathfindax.Utils;

namespace Duality.Plugins.Pathfindax.Tilemaps.Generators
{
Expand Down Expand Up @@ -67,12 +68,12 @@ public TilemapNodeConnectionGenerator()
/// <param name="sourceNodeGrid"></param>
public void CalculateGridNodeCollision(TilemapColliderWithBody[] tilemapColliderWithBodies, SourceGridNode sourceGridNode, ISourceNodeGrid<SourceGridNode> sourceNodeGrid)
{
CalculateNodeCollisionCategories(sourceGridNode.GridX, sourceGridNode.GridY, tilemapColliderWithBodies);
var nodeGridCoordinates = sourceNodeGrid.NodeArray.GetCoordinates(sourceGridNode.Index.Index);
CalculateNodeCollisionCategories(nodeGridCoordinates.X, nodeGridCoordinates.Y, tilemapColliderWithBodies);
var selfCollisionCategory = _nodeCollisions[0];
if (selfCollisionCategory.PathfindaxCollisionCategory != PathfindaxCollisionCategory.None)
sourceGridNode.Clearances = new[] { new GridClearance(selfCollisionCategory.PathfindaxCollisionCategory, 0) }; //This node is blocked so it has a clearance of 0.

if (sourceGridNode.GridX == 0 || sourceGridNode.GridY == 0 || sourceGridNode.GridX == sourceNodeGrid.NodeArray.Width - 1 || sourceGridNode.GridY == sourceNodeGrid.NodeArray.Height - 1)
if (nodeGridCoordinates.X == 0 || nodeGridCoordinates.Y == 0 || nodeGridCoordinates.X == sourceNodeGrid.NodeArray.Width - 1 || nodeGridCoordinates.Y == sourceNodeGrid.NodeArray.Height - 1)
{
var connections = new List<NodeConnection>(5);
for (var index = 1; index < _nodeCollisions.Length; index++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Duality.Plugins.Pathfindax.Components
/// </summary>
[EditorHintCategory(PathfindaxStrings.Pathfindax)]
[RequiredComponent(typeof(ISourceNodeNetworkProvider<ISourceNodeGrid<SourceGridNode>>))]
public class AStarGridPathfinderComponent : PathfinderComponentBase<ISourceNodeGrid<SourceGridNode>>
public class AStarGridPathfinderComponent : PathfinderComponentBase<SourceNodeGrid>
{
/// <inheritdoc />
public override void OnInit(InitContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public PathRequest RequestPath(float x1, float y1, float x2, float y2, Pathfinda
/// <param name="end"></param>
/// <param name="agentSize"></param>
/// <param name="collisionLayer"></param>
public PathRequest RequestPath(ISourceNode start, ISourceNode end, PathfindaxCollisionCategory collisionLayer = PathfindaxCollisionCategory.None, byte agentSize = 1)
public PathRequest RequestPath(DefinitionNode start, DefinitionNode end, PathfindaxCollisionCategory collisionLayer = PathfindaxCollisionCategory.None, byte agentSize = 1)
{
return new PathRequest(PathfinderComponent, start, end, collisionLayer, agentSize);
}
Expand Down
4 changes: 2 additions & 2 deletions Source/Code/Pathfindax.Test/Tests/AstarGridAlgorithmTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public class AstarGridAlgorithmTests
public void FindPath_InitializedNodegrid_PathLengthIsNot0(AstarNodeGrid sourceNodeGrid, float x1, float y1, float x2, float y2)
{
var aStarAlgorithm = new AStarGridAlgorithm();
var start = sourceNodeGrid.SourceNodeGrid.GetNode(x1, y1);
var end = sourceNodeGrid.SourceNodeGrid.GetNode(x2, y2);
var start = sourceNodeGrid._sourceNodeGrid.GetNode(x1, y1);
var end = sourceNodeGrid._sourceNodeGrid.GetNode(x2, y2);
var pathRequest = new PathRequest(start, end);
var path = aStarAlgorithm.FindPath(sourceNodeGrid, pathRequest);
Assert.AreEqual(path.Count > 0, true);
Expand Down
37 changes: 17 additions & 20 deletions Source/Code/Pathfindax/Algorithms/AStarAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ namespace Pathfindax.Algorithms
/// </summary>
public class AStarAlgorithm : IPathFindAlgorithm<INodeNetwork<AstarNode>>
{
/// <inheritdoc />
public IList<ISourceNode> FindPath(INodeNetwork<AstarNode> nodeNetwork, PathRequest pathRequest)
public List<DefinitionNode> FindPath(INodeNetwork<AstarNode> nodeNetwork, PathRequest pathRequest)
{
var startNode = NodePointer.Dereference(pathRequest.PathStart.Index, nodeNetwork);
var endNode = NodePointer.Dereference(pathRequest.PathEnd.Index, nodeNetwork);
return FindPath(nodeNetwork, startNode, endNode, pathRequest.CollisionLayer);
return FindPath(nodeNetwork, startNode, endNode, pathRequest.AgentSize);
}

private static IList<ISourceNode> FindPath(INodeNetwork<AstarNode> nodeNetwork, AstarNode startNode, AstarNode targetNode, PathfindaxCollisionCategory collisionCategory)
private static List<DefinitionNode> FindPath(INodeNetwork<AstarNode> nodeNetwork, AstarNode startNode, AstarNode targetNode, byte neededClearance)
{
try
{
Expand All @@ -31,9 +30,9 @@ private static IList<ISourceNode> FindPath(INodeNetwork<AstarNode> nodeNetwork,
var pathSucces = false;
if (startNode == targetNode)
{
return new List<ISourceNode> { targetNode.SourceNode };
return new List<DefinitionNode> { targetNode.SourceNode.DefinitionNode };
}
if ((startNode.SourceNode.CollisionCategory & collisionCategory) == 0 && (targetNode.SourceNode.CollisionCategory & collisionCategory) == 0)
if (startNode.SourceNode.Clearance >= neededClearance && targetNode.SourceNode.Clearance >= neededClearance)
{
var openSet = new MinHeap<AstarNode>(nodeNetwork.SourceNodeNetwork.NodeCount);
var closedSet = new HashSet<AstarNode>();
Expand All @@ -56,17 +55,15 @@ private static IList<ISourceNode> FindPath(INodeNetwork<AstarNode> nodeNetwork,

foreach (var connection in currentNode.SourceNode.Connections)
{
var toNode = NodePointer.Dereference(connection.To, nodeNetwork);
if ((connection.CollisionCategory & collisionCategory) != 0 || (toNode.SourceNode.CollisionCategory & collisionCategory) != 0 || closedSet.Contains(toNode))
{
continue;
}
var newMovementCostToNeighbour = currentNode.GCost + GetDistance(currentNode.SourceNode, toNode.SourceNode) + currentNode.SourceNode.MovementPenalty;
var toNode = NodePointer.Dereference(connection, nodeNetwork);
if (closedSet.Contains(toNode)) continue;

var newMovementCostToNeighbour = currentNode.GCost + GetDistance(currentNode.SourceNode.DefinitionNode, toNode.SourceNode.DefinitionNode) + currentNode.SourceNode.DefinitionNode.MovementPenalty;
if (newMovementCostToNeighbour < toNode.GCost || !openSet.Contains(toNode))
{
toNode.GCost = newMovementCostToNeighbour;
toNode.HCost = GetDistance(toNode.SourceNode, targetNode.SourceNode);
toNode.Parent = currentNode.SourceNode.Index;
toNode.HCost = GetDistance(toNode.SourceNode.DefinitionNode, targetNode.SourceNode.DefinitionNode);
toNode.Parent = currentNode.SourceNode.DefinitionNode.Index;
neighbourUpdates++;
if (!openSet.Contains(toNode))
openSet.Add(toNode);
Expand All @@ -88,25 +85,25 @@ private static IList<ISourceNode> FindPath(INodeNetwork<AstarNode> nodeNetwork,
}
}

private static IList<ISourceNode> RetracePath(INodeNetwork<AstarNode> nodeNetwork, AstarNode startGridNode, AstarNode endGridNode)
private static List<DefinitionNode> RetracePath(INodeNetwork<AstarNode> nodeNetwork, AstarNode startGridNode, AstarNode endGridNode)
{
var path = new List<ISourceNode>();
var path = new List<DefinitionNode>();
var currentNode = endGridNode;

while (true)
{
path.Add(currentNode.SourceNode);
path.Add(currentNode.SourceNode.DefinitionNode);
if (currentNode == startGridNode) break;
currentNode = NodePointer.Dereference(currentNode.Parent, nodeNetwork);
}
path.Reverse();
return path;
}

private static float GetDistance(SourceNode sourceNodeA, SourceNode sourceNodeB)
private static float GetDistance(DefinitionNode sourceNodeA, DefinitionNode sourceNodeB)
{
var dstX = Math.Abs(sourceNodeA.WorldPosition.X - sourceNodeB.WorldPosition.X);
var dstY = Math.Abs(sourceNodeA.WorldPosition.Y - sourceNodeB.WorldPosition.Y);
var dstX = Math.Abs(sourceNodeA.Position.X - sourceNodeB.Position.X);
var dstY = Math.Abs(sourceNodeA.Position.Y - sourceNodeB.Position.Y);
return dstY + dstX;
}
}
Expand Down
59 changes: 29 additions & 30 deletions Source/Code/Pathfindax/Algorithms/AStarGridAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@
using Pathfindax.Grid;
using Pathfindax.Nodes;
using Pathfindax.PathfindEngine;
using Pathfindax.Utils;

namespace Pathfindax.Algorithms
{
/// <summary>
/// Class that implements the A* algorithm for grids to find paths
/// </summary>
public class AStarGridAlgorithm : IPathFindAlgorithm<INodeGrid<AstarGridNode>>
public class AStarGridAlgorithm : IPathFindAlgorithm<AstarNodeGrid>
{
/// <inheritdoc />
public IList<ISourceNode> FindPath(INodeGrid<AstarGridNode> nodeGrid, PathRequest pathRequest)
public List<DefinitionNode> FindPath(AstarNodeGrid nodeGrid, PathRequest pathRequest)
{
var startNode = NodePointer.Dereference(pathRequest.PathStart.Index, nodeGrid.NodeArray);
var endNode = NodePointer.Dereference(pathRequest.PathEnd.Index, nodeGrid.NodeArray);
return FindPath(nodeGrid, startNode, endNode, pathRequest.CollisionLayer, pathRequest.AgentSize);
var pathfindingGrid = nodeGrid.GetPathfindingGrid(pathRequest.CollisionLayer);
var startNode = NodePointer.Dereference(pathRequest.PathStart.Index, pathfindingGrid);
var endNode = NodePointer.Dereference(pathRequest.PathEnd.Index, pathfindingGrid);
return FindPath(pathfindingGrid, startNode, endNode, pathRequest.AgentSize);
}

private static IList<ISourceNode> FindPath(INodeGrid<AstarGridNode> nodeGrid, AstarGridNode startGridNode, AstarGridNode targetGridNode, PathfindaxCollisionCategory collisionCategory, byte neededClearance)
private static List<DefinitionNode> FindPath(Array2D<AstarNode> pathfindingGrid, AstarNode startGridNode, AstarNode targetGridNode, byte neededClearance)
{
try
{
Expand All @@ -31,13 +32,12 @@ private static IList<ISourceNode> FindPath(INodeGrid<AstarGridNode> nodeGrid, As
var pathSucces = false;
if (startGridNode == targetGridNode)
{
return new List<ISourceNode> { targetGridNode.SourceGridNode };
return new List<DefinitionNode> { targetGridNode.SourceNode.DefinitionNode };
}
var array = nodeGrid.NodeArray.Array;
if (startGridNode.SourceGridNode.GetTrueClearance(collisionCategory) >= neededClearance && targetGridNode.SourceGridNode.GetTrueClearance(collisionCategory) >= neededClearance)
{
var openSet = new MinHeap<AstarGridNode>(nodeGrid.NodeArray.Length);
var closedSet = new HashSet<AstarGridNode>();
if (startGridNode.SourceNode.Clearance >= neededClearance && targetGridNode.SourceNode.Clearance >= neededClearance)
{
var openSet = new MinHeap<AstarNode>(pathfindingGrid.Length);
var closedSet = new HashSet<AstarNode>();
var itterations = 0;
var neighbourUpdates = 0;
openSet.Add(startGridNode);
Expand All @@ -55,22 +55,19 @@ private static IList<ISourceNode> FindPath(INodeGrid<AstarGridNode> nodeGrid, As
break;
}

foreach (var connection in currentNode.SourceGridNode.Connections)
foreach (var connection in currentNode.SourceNode.Connections)
{
var toNode = NodePointer.Dereference(connection.To, array);
if ((connection.CollisionCategory & collisionCategory) != 0 || closedSet.Contains(toNode))
{
continue;
}
var toNode = NodePointer.Dereference(connection, pathfindingGrid);
if (closedSet.Contains(toNode)) continue;

if (toNode.SourceGridNode.GetTrueClearance(collisionCategory) >= neededClearance)
if (toNode.SourceNode.Clearance >= neededClearance)
{
var newMovementCostToNeighbour = currentNode.GCost + GetDistance(currentNode.SourceGridNode, toNode.SourceGridNode) + currentNode.SourceGridNode.MovementPenalty;
var newMovementCostToNeighbour = currentNode.GCost + GetDistance(pathfindingGrid.Width, currentNode.SourceNode, toNode.SourceNode) + currentNode.SourceNode.DefinitionNode.MovementPenalty;
if (newMovementCostToNeighbour < toNode.GCost || !openSet.Contains(toNode))
{
toNode.GCost = newMovementCostToNeighbour;
toNode.HCost = GetDistance(toNode.SourceGridNode, targetGridNode.SourceGridNode);
toNode.Parent = currentNode.SourceGridNode.Index;
toNode.HCost = GetDistance(pathfindingGrid.Width, toNode.SourceNode, targetGridNode.SourceNode);
toNode.Parent = currentNode.SourceNode.DefinitionNode.Index;
neighbourUpdates++;
if (!openSet.Contains(toNode))
openSet.Add(toNode);
Expand All @@ -81,7 +78,7 @@ private static IList<ISourceNode> FindPath(INodeGrid<AstarGridNode> nodeGrid, As
}
if (pathSucces)
{
return RetracePath(array, startGridNode, targetGridNode);
return RetracePath(pathfindingGrid, startGridNode, targetGridNode);
}
Debug.WriteLine("Did not find a path :(");
return null;
Expand All @@ -93,25 +90,27 @@ private static IList<ISourceNode> FindPath(INodeGrid<AstarGridNode> nodeGrid, As
}
}

private static IList<ISourceNode> RetracePath(AstarGridNode[] nodeArray, AstarGridNode startGridNode, AstarGridNode endGridNode)
private static List<DefinitionNode> RetracePath(Array2D<AstarNode> nodeArray, AstarNode startGridNode, AstarNode endGridNode)
{
var path = new List<ISourceNode>();
var path = new List<DefinitionNode>();
var currentNode = endGridNode;

while (true)
{
path.Add(currentNode.SourceGridNode);
path.Add(currentNode.SourceNode.DefinitionNode);
if (currentNode == startGridNode) break;
currentNode = NodePointer.Dereference(currentNode.Parent, nodeArray);
}
path.Reverse();
return path;
}

private static int GetDistance(SourceGridNode gridNodeA, SourceGridNode gridNodeB)
private static int GetDistance(int width, SourceNode gridNodeA, SourceNode gridNodeB)
{
var dstX = Math.Abs(gridNodeA.GridX - gridNodeB.GridX);
var dstY = Math.Abs(gridNodeA.GridY - gridNodeB.GridY);
var gridNodeACoords = GridMath.TransformToGridCoords(width, gridNodeA.DefinitionNode.Index.Index);
var gridNodeBCoords = GridMath.TransformToGridCoords(width, gridNodeB.DefinitionNode.Index.Index);
var dstX = Math.Abs(gridNodeACoords.X - gridNodeBCoords.X);
var dstY = Math.Abs(gridNodeACoords.Y - gridNodeBCoords.Y);
return dstY + dstX;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public interface IPathFindAlgorithm<in TNodeNetwork>
/// <param name="nodeNetwork">The <typeparamref name="TNodeNetwork"/> in which the pathfinding will be done</param>
/// <param name="pathRequest">The <see cref="PathRequest"/> that contains the info needed such as the start and end of the path</param>
/// <returns>A list of nodes in the defining the path</returns>
IList<ISourceNode> FindPath(TNodeNetwork nodeNetwork, PathRequest pathRequest);
List<DefinitionNode> FindPath(TNodeNetwork nodeNetwork, PathRequest pathRequest);
}
}
11 changes: 8 additions & 3 deletions Source/Code/Pathfindax/Collections/Array2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ namespace Pathfindax.Collections
/// A array class that provides both single dimensional and 2-dimensional access to a array.
/// </summary>
/// <typeparam name="TItem"></typeparam>
public class Array2D<TItem> : IReadOnlyArray2D<TItem>, IWriteOnlyArray2D<TItem>
public class Array2D<TItem> : IReadOnlyArray2D<TItem>, IWriteOnlyArray2D<TItem>, IReadOnlyList<TItem>
{
/// <summary>
/// The length of the internal array
/// </summary>
public int Length => Array.Length;

/// <summary>
/// The length of the internal array
/// </summary>
public int Count => Array.Length;

/// <summary>
/// The width of the array in items
/// </summary>
Expand All @@ -34,7 +39,7 @@ public class Array2D<TItem> : IReadOnlyArray2D<TItem>, IWriteOnlyArray2D<TItem>
public TItem this[int x, int y]
{
get => Array[x + y * Width];
set => Array[x + y * Width] = value;
set => Array[x + y * Width] = value;
}

/// <summary>
Expand All @@ -44,7 +49,7 @@ public class Array2D<TItem> : IReadOnlyArray2D<TItem>, IWriteOnlyArray2D<TItem>
public TItem this[int i]
{
get => Array[i];
set => Array[i] = value;
set => Array[i] = value;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

namespace Pathfindax.Collections
{
public interface IReadOnlyArray2D<out TItem> : IEnumerable<TItem>
public interface IReadOnlyArray2D<out TItem> : IReadOnlyArray2D ,IEnumerable<TItem>
{
TItem this[int i] { get; }
TItem this[int x, int y] { get; }
}

public interface IReadOnlyArray2D
{
int Height { get; }
int Length { get; }
int Width { get; }
Expand Down
5 changes: 3 additions & 2 deletions Source/Code/Pathfindax/Factories/NodeFactory.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using Pathfindax.Nodes;
using Pathfindax.Grid;
using Pathfindax.Nodes;

namespace Pathfindax.Factories
{
public static class NodeFactory
{
public static void CreateConnection<T>(T from, SourceNode to)
where T : SourceNode
where T : DefinitionNode
{
from.Connections.Add(new NodeConnection(to));
}
Expand Down

0 comments on commit e9ed238

Please sign in to comment.