diff options
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.cs | 132 |
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; + } + } +} |