Advertisement
Guest User

Untitled

a guest
Feb 11th, 2020
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 20.21 KB | None | 0 0
  1.         private struct AStarJob : IJobChunk
  2.         {
  3.             [NativeDisableParallelForRestriction] public BufferFromEntity<PathNodeEntry> PathNodeBuffer;
  4. //            public EntityCommandBuffer.Concurrent CommandBuffer;
  5.             public ArchetypeChunkComponentType<AStarData> AStarDataType;
  6.             public ArchetypeChunkComponentType<Translation> TranslateDataType;
  7.             public ArchetypeChunkComponentType<MovementData> MovementDataType;
  8.            
  9.             [ReadOnly] public uint RandomSeed;
  10.             [ReadOnly] public ArchetypeChunkEntityType EntityType;
  11.  
  12.             [ReadOnly] public DynamicBuffer<Edge> pathsBetweenNodes;
  13.             [ReadOnly] public DynamicBuffer<NodeOctreeCell> childCells;
  14.             [ReadOnly] public DynamicBuffer<IntBufferData> nodeIdsSortedByCellIds;
  15.             [ReadOnly] public int parentCellId;
  16. //            [ReadOnly] public Entity GraphEntity;
  17.  
  18.             [ReadOnly] public DynamicBuffer<Node> Nodes;
  19.  
  20.             public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
  21.             {
  22.                 var chunkMovementData = chunk.GetNativeArray(MovementDataType);
  23.                 var chunkAStarData = chunk.GetNativeArray(AStarDataType);
  24.                 var chunkTranslate = chunk.GetNativeArray(TranslateDataType);
  25.                 var chunkEntities = chunk.GetNativeArray(EntityType);
  26.  
  27. //                Nodes = CommandBuffer.SetBuffer<Node>(chunkIndex, GraphEntity);
  28.                
  29.                 for (int i = 0; i < chunk.Count; i++)
  30.                 {
  31.                     AStarData aStarData = chunkAStarData[i];
  32.                     MovementData movementData = chunkMovementData[i];
  33.                     Translation translation = chunkTranslate[i];
  34.                     Entity entity = chunkEntities[i];
  35.  
  36.                     if (!aStarData.IsSearchingPath && movementData.hasArrived)
  37.                     {
  38.                         Random random = new Random((uint) chunkIndex + (uint) i + RandomSeed);
  39.                         float3 randomTarget = new float3(random.NextFloat(movementData.minX, movementData.maxX), movementData.y,
  40.                             random.NextFloat(movementData.minZ, movementData.maxZ));
  41.  
  42.                         if (TryGetClosestNodeToPoint(randomTarget, out Node targetGraphNode) &&
  43.                             TryGetClosestNodeToPoint(translation.Value, out Node startGraphNode))
  44.                         {
  45.                             aStarData.IsSearchingPath = true;
  46.                             aStarData.HasFoundPath = false;
  47.                             AStarPathNode startNode = new AStarPathNode
  48.                             {
  49.                                 GCost = 0,
  50.                                 HCost = Utils.GetHeuristicLengthOf(targetGraphNode.Position - startGraphNode.Position),
  51.                                 Index = startGraphNode.Id,
  52.                                 PreviousNodeId = -1,
  53.                                 Position = startGraphNode.Position,
  54.                             };
  55.                             startNode.CalculateFCost();
  56.                            
  57.                             NativeList<AStarPathNode> sortedNodes = new NativeList<AStarPathNode>(Allocator.Temp);
  58.                             sortedNodes.Add(startNode);
  59.                             NativeHashMap<int, AStarPathNode> openList = new NativeHashMap<int, AStarPathNode>(15, Allocator.Temp);
  60.                             openList.Add(startNode.Index, startNode);
  61.                             NativeHashMap<int, AStarPathNode> closedList = new NativeHashMap<int, AStarPathNode>(15, Allocator.Temp);
  62.  
  63.                             bool isPathFound = false;
  64.                             while (openList.Length > 0 && !isPathFound)
  65.                             {
  66.                                 int currentIndex = sortedNodes[0].Index;
  67.                                 Node currentNode = Nodes[currentIndex];
  68.                                 AStarPathNode currentSearchNode = openList[currentIndex];
  69.                                 closedList.Add(currentIndex, currentSearchNode);
  70.                                
  71.                                 var newSorted = Utils.RemoveAt(sortedNodes, 0);
  72.                                 sortedNodes.Dispose();
  73.                                 sortedNodes = newSorted;
  74.                                
  75.                                 openList.Remove(currentIndex);
  76.  
  77.                                 if (currentSearchNode.Index == targetGraphNode.Id)
  78.                                 {
  79.                                     int pathIndex = currentSearchNode.Index;
  80.                                     NativeList<int> pathToTarget = new NativeList<int>(Allocator.Temp);
  81.                                     while (pathIndex >= 0)
  82.                                     {
  83.                                         pathToTarget.Add(pathIndex);
  84.                                         pathIndex = closedList[pathIndex].PreviousNodeId;
  85.                                     }
  86.                                     isPathFound = true;
  87.  
  88.                                     DynamicBuffer<PathNodeEntry> pathNodes = PathNodeBuffer[entity]; // CommandBuffer.SetBuffer<PathNodeEntry>(chunkIndex, entity);
  89.                                     pathNodes.Clear();
  90.                                     for (int pathIndexId = pathToTarget.Length - 1; pathIndexId >= 0; pathIndexId--)
  91.                                     {
  92.                                         pathNodes.Add(new PathNodeEntry {node = Nodes[pathToTarget[pathIndexId]]});
  93.                                     }
  94.  
  95.                                     pathToTarget.Dispose();
  96.  
  97.                                     movementData.ResetPath();
  98.                                     chunkMovementData[i] = movementData;
  99.                                            
  100.                                     aStarData.HasFoundPath = true;
  101.                                     break;
  102.                                 }
  103.  
  104.                                 for (int neighbourId = 0; neighbourId < currentNode.NumberOfEdges; neighbourId++)
  105.                                 {
  106.                                     Edge nextEdge = pathsBetweenNodes[currentNode.FirstEdgeId + neighbourId];
  107.                                     if (!closedList.ContainsKey(nextEdge.TargetNodeId))
  108.                                     {
  109.                                         Node nextNode = Nodes[nextEdge.TargetNodeId];
  110.                                         AStarPathNode nextSearchNode = new AStarPathNode
  111.                                         {
  112.                                             GCost = currentSearchNode.GCost + nextEdge.Cost,
  113.                                             HCost = Utils.GetHeuristicLengthOf(targetGraphNode.Position - nextNode.Position),
  114.                                             Index = nextNode.Id,
  115.                                             PreviousNodeId = currentNode.Id,
  116.                                             Position = nextNode.Position
  117.                                         };
  118.                                         nextSearchNode.CalculateFCost();
  119.  
  120.                                         if (openList.ContainsKey(nextSearchNode.Index))
  121.                                         {
  122.                                             if (nextSearchNode.FCost < openList[nextSearchNode.Index].FCost)
  123.                                             {
  124.                                                 openList[nextSearchNode.Index] = nextSearchNode;
  125.  
  126.                                                 // Sort the IDs to reflect the new FCost
  127.                                                 int removeId = -1;
  128.                                                 for (int sortedListId = 0; sortedListId < sortedNodes.Length; sortedListId++)
  129.                                                 {
  130.                                                     if (nextSearchNode.Index == sortedNodes[sortedListId].Index)
  131.                                                     {
  132.                                                         removeId = sortedListId;
  133.                                                         break;
  134.                                                     }
  135.                                                 }
  136.  
  137.                                                 if (removeId >= 0)
  138.                                                 {
  139.                                                     var newSortedInside = Utils.RemoveAt(sortedNodes, removeId);
  140.                                                     sortedNodes.Dispose();
  141.                                                     sortedNodes = newSortedInside;
  142.                                                 }
  143.                                                
  144.                                                 int insertId = -1;
  145.                                                 for (int sortedListId = 0; sortedListId < sortedNodes.Length; sortedListId++)
  146.                                                 {
  147.                                                     if (nextSearchNode.FCost < openList[sortedNodes[sortedListId].Index].FCost)
  148.                                                     {
  149.                                                         insertId = sortedListId;
  150.                                                         break;
  151.                                                     }
  152.                                                 }
  153.                                                 if (insertId < 0)
  154.                                                 {
  155.                                                     sortedNodes.Add(nextSearchNode);
  156.                                                 }
  157.                                                 else
  158.                                                 {
  159.                                                     NativeList<AStarPathNode> newSortedNodes = Utils.InsertIntoNativeList(sortedNodes, nextSearchNode, insertId);
  160.                                                     sortedNodes.Dispose();
  161.                                                     sortedNodes = newSortedNodes;
  162.                                                 }
  163.                                             }
  164.                                         }
  165.                                         else
  166.                                         {
  167.                                             openList.Add(nextSearchNode.Index, nextSearchNode);
  168.                                             int insertId = -1;
  169.                                             for (int sortedListId = 0; sortedListId < sortedNodes.Length; sortedListId++)
  170.                                             {
  171.                                                 if (nextSearchNode.FCost < openList[sortedNodes[sortedListId].Index].FCost)
  172.                                                 {
  173.                                                     insertId = sortedListId;
  174.                                                     break;
  175.                                                 }
  176.                                             }
  177.  
  178.                                             if (insertId < 0)
  179.                                             {
  180.                                                 sortedNodes.Add(nextSearchNode);
  181.                                             }
  182.                                             else
  183.                                             {
  184.                                                 NativeList<AStarPathNode> newSortedNodes = Utils.InsertIntoNativeList(sortedNodes, nextSearchNode, insertId);
  185.                                                 sortedNodes.Dispose();
  186.                                                 sortedNodes = newSortedNodes;
  187.                                             }
  188.                                         }
  189.                                     }
  190.                                 }
  191.                             }
  192.                             aStarData.IsSearchingPath = false;
  193.                             chunkAStarData[i] = aStarData;
  194.                             openList.Dispose();
  195.                             closedList.Dispose();
  196.                             sortedNodes.Dispose();
  197.                         }
  198.                     }
  199.                 }
  200.             }
  201.  
  202.  
  203.             private bool TryGetClosestNodeToPoint(float3 point, out Node result)
  204.             {
  205.                 NativeList<int> cellIdsToIterate = new NativeList<int>(Allocator.Temp);
  206.                 cellIdsToIterate.Add(parentCellId);
  207.  
  208.                 NodeOctreeCell lastParent = new NodeOctreeCell();
  209.                 bool isLastParentSet = false;
  210.                 bool foundNode = false;
  211.                 result = new Node();
  212.  
  213.                 while (!foundNode && cellIdsToIterate.Length > 0)
  214.                 {
  215.                     NodeOctreeCell currentCell = childCells[cellIdsToIterate[0]];
  216.                     if (currentCell.DoesContain(point))
  217.                     {
  218.                         NativeList<int> subCellList = GetOctreeCellIds(currentCell);
  219.                         if (subCellList.Length > 0)
  220.                         {
  221.                             lastParent = currentCell;
  222.                             isLastParentSet = true;
  223.                             cellIdsToIterate.Dispose();
  224.                             cellIdsToIterate = new NativeList<int>(Allocator.Temp);
  225.                             cellIdsToIterate.AddRange(subCellList);
  226.                         }
  227.                         else
  228.                         {
  229.                             if (currentCell.NumberOfChildNodes > 0)
  230.                             {
  231.                                 NativeArray<Node> childNodes = GetChildNodes(currentCell);
  232.                                 Node closest = childNodes[0];
  233.                                 float closestSqrDist = math.distancesq(point, closest.Position);
  234.                                 for (int n = 1; n < childNodes.Length; n++)
  235.                                 {
  236.                                     float sqrDist = math.distancesq(point, childNodes[n].Position);
  237.                                     if (sqrDist < closestSqrDist)
  238.                                     {
  239.                                         closestSqrDist = sqrDist;
  240.                                         closest = childNodes[n];
  241.                                     }
  242.                                 }
  243.  
  244.                                 childNodes.Dispose();
  245.  
  246.                                 foundNode = true;
  247.                                 result = closest;
  248.                             }
  249.                             else if (isLastParentSet)
  250.                             {
  251.                                 NativeList<Node> allNodesInLastParent = new NativeList<Node>(Allocator.Temp);
  252.                                 NativeArray<Node> childNodesOfLastParent = GetChildNodes(lastParent);
  253.                                 if (childNodesOfLastParent.Length > 0)
  254.                                 {
  255.                                     allNodesInLastParent.AddRange(childNodesOfLastParent);
  256.                                 }
  257.                                 else
  258.                                 {
  259.                                     var childCellsOfLastParent = GetOctreeCellIds(lastParent);
  260.                                     // ReSharper disable once ForCanBeConvertedToForeach - No foreach in burst jobs
  261.                                     for (int i = 0; i < childCellsOfLastParent.Length; i++)
  262.                                     {
  263.                                         NativeArray<Node> cellChildNodes = GetChildNodes(childCells[childCellsOfLastParent[i]]);
  264.                                         if (cellChildNodes.Length > 0)
  265.                                         {
  266.                                             allNodesInLastParent.AddRange(cellChildNodes);
  267.                                         }
  268.  
  269.                                         cellChildNodes.Dispose();
  270.                                     }
  271.  
  272.                                     childCellsOfLastParent.Dispose();
  273.                                 }
  274.  
  275.                                 childNodesOfLastParent.Dispose();
  276.  
  277.                                 if (allNodesInLastParent.Length > 0)
  278.                                 {
  279.                                     Node closest = allNodesInLastParent[0];
  280.                                     float closestSqrDist = math.distancesq(point, closest.Position);
  281.                                     for (int n = 1; n < allNodesInLastParent.Length; n++)
  282.                                     {
  283.                                         float sqrDist = math.distancesq(point, allNodesInLastParent[n].Position);
  284.                                         if (sqrDist < closestSqrDist)
  285.                                         {
  286.                                             closestSqrDist = sqrDist;
  287.                                             closest = allNodesInLastParent[n];
  288.                                         }
  289.                                     }
  290.  
  291.                                     foundNode = true;
  292.                                     result = closest;
  293.                                 }
  294.                                 else
  295.                                 {
  296.                                     // A cell was hit, that has no way points. No close point can be found.
  297.                                     cellIdsToIterate.Clear();
  298.                                 }
  299.  
  300.                                 allNodesInLastParent.Dispose();
  301.                             }
  302.                             else
  303.                             {
  304.                                 cellIdsToIterate.Clear();
  305.                             }
  306.                         }
  307.  
  308.                         subCellList.Dispose();
  309.                     }
  310.                     else
  311.                     {
  312.                         cellIdsToIterate.RemoveAtSwapBack(0);
  313.                     }
  314.                 }
  315.  
  316.                 return foundNode;
  317.             }
  318.  
  319.             /// <summary>
  320.             /// Returns a the child cells for a certain parent cell.
  321.             /// </summary>
  322.             /// <param name="parentCell"> The parent cell. </param>
  323.             /// <returns> The child cells you wanted to retrieve. </returns>
  324.             private NativeList<int> GetOctreeCellIds(NodeOctreeCell parentCell)
  325.             {
  326.                 return GetOctreeCellIds(parentCell.FirstChildCellId, parentCell.NumberOfChildCells);
  327.             }
  328.  
  329.             /// <summary>
  330.             /// Returns a sub-array of child cells for a range of number of cells, starting with a given cell ID.
  331.             /// </summary>
  332.             /// <param name="firstChildCellId"> ID of the first cell. </param>
  333.             /// <param name="numberOfChildCells"> Total number of cells. </param>
  334.             /// <returns> The child cells you wanted to retrieve. </returns>
  335.             private NativeList<int> GetOctreeCellIds(int firstChildCellId, int numberOfChildCells)
  336.             {
  337.                 if (firstChildCellId == -1 || numberOfChildCells == 0)
  338.                 {
  339.                     return new NativeList<int>(Allocator.Temp);
  340.                 }
  341.  
  342.                 NativeList<int> cellIds = new NativeList<int>(Allocator.Temp);
  343.                 NativeList<NodeOctreeCell> subList = Utils.GetSubList(childCells, firstChildCellId, numberOfChildCells);
  344.                 for (int i = 0; i < subList.Length; i++)
  345.                 {
  346.                     cellIds.Add(subList[i].Id);
  347.                 }
  348.  
  349.                 return cellIds;
  350.             }
  351.  
  352.             private NativeArray<Node> GetChildNodes(NodeOctreeCell parentCell)
  353.             {
  354.                 return GetChildNodes(parentCell.FirstSortedNodeId, parentCell.NumberOfChildNodes);
  355.             }
  356.  
  357.             private NativeArray<Node> GetChildNodes(int firstSortedNodeId, int numberOfNodes)
  358.             {
  359.                 NativeArray<int> cellChildNodeIds = Utils.GetIntDataSubArray(nodeIdsSortedByCellIds, firstSortedNodeId, numberOfNodes);
  360.                 NativeArray<Node> cellChildNodes = new NativeArray<Node>(cellChildNodeIds.Length, Allocator.Temp);
  361.                 for (int i = 0; i < cellChildNodeIds.Length; i++)
  362.                 {
  363.                     cellChildNodes[i] = Nodes[cellChildNodeIds[i]];
  364.                 }
  365.  
  366.                 cellChildNodeIds.Dispose();
  367.  
  368.                 return cellChildNodes;
  369.             }
  370.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement