94 lines
3.1 KiB
C#
94 lines
3.1 KiB
C#
using UnityEngine;
|
|
using Unity.Collections;
|
|
using Unity.Mathematics;
|
|
using Pathfinding.Jobs;
|
|
|
|
namespace Pathfinding.Graphs.Grid.Jobs {
|
|
/// <summary>
|
|
/// Reads node data from managed <see cref="GridNodeBase"/> objects into unmanaged arrays.
|
|
///
|
|
/// This is done so that burst jobs can later access this data directly.
|
|
///
|
|
/// Later, data will be written back to the managed objects using the <see cref="JobWriteNodeData"/> job.
|
|
/// </summary>
|
|
public struct JobReadNodeData : IJobParallelForBatched {
|
|
public System.Runtime.InteropServices.GCHandle nodesHandle;
|
|
public uint graphIndex;
|
|
|
|
public Slice3D slice;
|
|
|
|
[WriteOnly]
|
|
public NativeArray<Vector3> nodePositions;
|
|
|
|
[WriteOnly]
|
|
public NativeArray<uint> nodePenalties;
|
|
|
|
[WriteOnly]
|
|
public NativeArray<int> nodeTags;
|
|
|
|
[WriteOnly]
|
|
public NativeArray<ulong> nodeConnections;
|
|
|
|
[WriteOnly]
|
|
public NativeArray<bool> nodeWalkableWithErosion;
|
|
|
|
[WriteOnly]
|
|
public NativeArray<bool> nodeWalkable;
|
|
|
|
public bool allowBoundsChecks => false;
|
|
|
|
struct Reader : GridIterationUtilities.ISliceAction {
|
|
public GridNodeBase[] nodes;
|
|
public NativeArray<Vector3> nodePositions;
|
|
public NativeArray<uint> nodePenalties;
|
|
public NativeArray<int> nodeTags;
|
|
public NativeArray<ulong> nodeConnections;
|
|
public NativeArray<bool> nodeWalkableWithErosion;
|
|
public NativeArray<bool> nodeWalkable;
|
|
|
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
|
public void Execute (uint outerIdx, uint innerIdx) {
|
|
var dataIdx = (int)innerIdx;
|
|
// The data bounds may have more layers than the existing nodes if a new layer is being added.
|
|
// We can only copy from the nodes that exist.
|
|
if (outerIdx < nodes.Length) {
|
|
var node = nodes[outerIdx];
|
|
if (node != null) {
|
|
nodePositions[dataIdx] = (Vector3)node.position;
|
|
nodePenalties[dataIdx] = node.Penalty;
|
|
nodeTags[dataIdx] = (int)node.Tag;
|
|
nodeConnections[dataIdx] = node is GridNode gn ? (ulong)gn.GetAllConnectionInternal() : (node as LevelGridNode).gridConnections;
|
|
nodeWalkableWithErosion[dataIdx] = node.Walkable;
|
|
nodeWalkable[dataIdx] = node.WalkableErosion;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Fallback in case the node was null (only happens for layered grid graphs),
|
|
// or if we are adding more layers to the graph, in which case we are outside
|
|
// the bounds of the nodes array.
|
|
nodePositions[dataIdx] = Vector3.zero;
|
|
nodePenalties[dataIdx] = 0;
|
|
nodeTags[dataIdx] = 0;
|
|
nodeConnections[dataIdx] = 0;
|
|
nodeWalkableWithErosion[dataIdx] = false;
|
|
nodeWalkable[dataIdx] = false;
|
|
}
|
|
}
|
|
|
|
public void Execute (int startIndex, int count) {
|
|
var reader = new Reader {
|
|
// This is a managed type, we need to trick Unity to allow this inside of a job
|
|
nodes = (GridNodeBase[])nodesHandle.Target,
|
|
nodePositions = nodePositions,
|
|
nodePenalties = nodePenalties,
|
|
nodeTags = nodeTags,
|
|
nodeConnections = nodeConnections,
|
|
nodeWalkableWithErosion = nodeWalkableWithErosion,
|
|
nodeWalkable = nodeWalkable
|
|
};
|
|
GridIterationUtilities.ForEachCellIn3DSlice(slice, ref reader);
|
|
}
|
|
}
|
|
}
|