summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Voxels/CompactVoxelField.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Voxels/CompactVoxelField.cs')
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Voxels/CompactVoxelField.cs132
1 files changed, 132 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Voxels/CompactVoxelField.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Voxels/CompactVoxelField.cs
new file mode 100644
index 0000000..1d8571e
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Voxels/CompactVoxelField.cs
@@ -0,0 +1,132 @@
+using Pathfinding.Jobs;
+using Unity.Collections;
+using Unity.Mathematics;
+using UnityEngine.Assertions;
+
+namespace Pathfinding.Graphs.Navmesh.Voxelization.Burst {
+ /// <summary>Stores a compact voxel field. </summary>
+ public struct CompactVoxelField : IArenaDisposable {
+ public const int UnwalkableArea = 0;
+ public const uint NotConnected = 0x3f;
+ public readonly int voxelWalkableHeight;
+ public readonly int width, depth;
+ public NativeList<CompactVoxelSpan> spans;
+ public NativeList<CompactVoxelCell> cells;
+ public NativeList<int> areaTypes;
+
+ /// <summary>Unmotivated variable, but let's clamp the layers at 65535</summary>
+ public const int MaxLayers = 65535;
+
+ public CompactVoxelField (int width, int depth, int voxelWalkableHeight, Allocator allocator) {
+ spans = new NativeList<CompactVoxelSpan>(0, allocator);
+ cells = new NativeList<CompactVoxelCell>(0, allocator);
+ areaTypes = new NativeList<int>(0, allocator);
+ this.width = width;
+ this.depth = depth;
+ this.voxelWalkableHeight = voxelWalkableHeight;
+ }
+
+ void IArenaDisposable.DisposeWith (DisposeArena arena) {
+ arena.Add(spans);
+ arena.Add(cells);
+ arena.Add(areaTypes);
+ }
+
+ public int GetNeighbourIndex (int index, int direction) {
+ return index + VoxelUtilityBurst.DX[direction] + VoxelUtilityBurst.DZ[direction] * width;
+ }
+
+ public void BuildFromLinkedField (LinkedVoxelField field) {
+ int idx = 0;
+
+ Assert.AreEqual(this.width, field.width);
+ Assert.AreEqual(this.depth, field.depth);
+
+ int w = field.width;
+ int d = field.depth;
+ int wd = w*d;
+
+ int spanCount = field.GetSpanCount();
+ spans.Resize(spanCount, NativeArrayOptions.UninitializedMemory);
+ areaTypes.Resize(spanCount, NativeArrayOptions.UninitializedMemory);
+ cells.Resize(wd, NativeArrayOptions.UninitializedMemory);
+
+#if ENABLE_UNITY_COLLECTIONS_CHECKS
+ if (this.voxelWalkableHeight >= ushort.MaxValue) {
+ throw new System.Exception("Too high walkable height to guarantee correctness. Increase voxel height or lower walkable height.");
+ }
+#endif
+
+ var linkedSpans = field.linkedSpans;
+ for (int z = 0; z < wd; z += w) {
+ for (int x = 0; x < w; x++) {
+ int spanIndex = x+z;
+ if (linkedSpans[spanIndex].bottom == LinkedVoxelField.InvalidSpanValue) {
+ cells[x+z] = new CompactVoxelCell(0, 0);
+ continue;
+ }
+
+ int index = idx;
+ int count = 0;
+
+ while (spanIndex != -1) {
+ if (linkedSpans[spanIndex].area != UnwalkableArea) {
+ int bottom = (int)linkedSpans[spanIndex].top;
+ int next = linkedSpans[spanIndex].next;
+ int top = next != -1 ? (int)linkedSpans[next].bottom : LinkedVoxelField.MaxHeightInt;
+
+ // TODO: Why is top-bottom clamped to a ushort range?
+ spans[idx] = new CompactVoxelSpan((ushort)math.min(bottom, ushort.MaxValue), (uint)math.min(top-bottom, ushort.MaxValue));
+ areaTypes[idx] = linkedSpans[spanIndex].area;
+ idx++;
+ count++;
+ }
+ spanIndex = linkedSpans[spanIndex].next;
+ }
+
+ cells[x+z] = new CompactVoxelCell(index, count);
+ }
+ }
+
+#if ENABLE_UNITY_COLLECTIONS_CHECKS
+ if (idx != spanCount) throw new System.Exception("Found span count does not match expected value");
+#endif
+ }
+ }
+
+ /// <summary>CompactVoxelCell used for recast graphs.</summary>
+ public struct CompactVoxelCell {
+ public int index;
+ public int count;
+
+ public CompactVoxelCell (int i, int c) {
+ index = i;
+ count = c;
+ }
+ }
+
+ /// <summary>CompactVoxelSpan used for recast graphs.</summary>
+ public struct CompactVoxelSpan {
+ public ushort y;
+ public uint con;
+ public uint h;
+ public int reg;
+
+ public CompactVoxelSpan (ushort bottom, uint height) {
+ con = 24;
+ y = bottom;
+ h = height;
+ reg = 0;
+ }
+
+ public void SetConnection (int dir, uint value) {
+ int shift = dir*6;
+
+ con = (uint)((con & ~(0x3f << shift)) | ((value & 0x3f) << shift));
+ }
+
+ public int GetConnection (int dir) {
+ return ((int)con >> dir*6) & 0x3f;
+ }
+ }
+}