1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
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);
}
}
}
|