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
94
95
96
97
|
using System;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Mathematics;
namespace Pathfinding.Util {
/// <summary>Various utilities for handling arrays and memory</summary>
public static class Memory {
/// <summary>
/// Returns a new array with at most length newLength.
/// The array will contain a copy of all elements of arr up to but excluding the index newLength.
/// </summary>
public static T[] ShrinkArray<T>(T[] arr, int newLength) {
newLength = Math.Min(newLength, arr.Length);
var shrunkArr = new T[newLength];
Array.Copy(arr, shrunkArr, newLength);
return shrunkArr;
}
/// <summary>Swaps the variables a and b</summary>
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static void Swap<T>(ref T a, ref T b) {
T tmp = a;
a = b;
b = tmp;
}
public static void Realloc<T>(ref NativeArray<T> arr, int newSize, Allocator allocator, NativeArrayOptions options = NativeArrayOptions.ClearMemory) where T : struct {
if (arr.IsCreated && arr.Length >= newSize) return;
var newArr = new NativeArray<T>(newSize, allocator, options);
if (arr.IsCreated) {
// Copy over old data
NativeArray<T>.Copy(arr, newArr, arr.Length);
arr.Dispose();
}
arr = newArr;
}
public static void Realloc<T>(ref T[] arr, int newSize) {
if (arr == null) {
arr = new T[newSize];
} else if (newSize > arr.Length) {
var newArr = new T[newSize];
arr.CopyTo(newArr, 0);
arr = newArr;
}
}
public static T[] UnsafeAppendBufferToArray<T>(UnsafeAppendBuffer src) where T : unmanaged {
var elementCount = src.Length / UnsafeUtility.SizeOf<T>();
var dst = new T[elementCount];
unsafe {
var gCHandle = System.Runtime.InteropServices.GCHandle.Alloc(dst, System.Runtime.InteropServices.GCHandleType.Pinned);
System.IntPtr value = gCHandle.AddrOfPinnedObject();
UnsafeUtility.MemCpy((byte*)(void*)value, src.Ptr, (long)elementCount * (long)UnsafeUtility.SizeOf<T>());
gCHandle.Free();
}
return dst;
}
public static void Rotate3DArray<T>(T[] arr, int3 size, int dx, int dz) {
int width = size.x;
int height = size.y;
int depth = size.z;
dx = dx % width;
dz = dz % depth;
if (dx != 0) {
if (dx < 0) dx = width + dx;
var tmp = ArrayPool<T>.Claim(dx);
for (int y = 0; y < height; y++) {
var offset = y * width * depth;
for (int z = 0; z < depth; z++) {
Array.Copy(arr, offset + z * width + width - dx, tmp, 0, dx);
Array.Copy(arr, offset + z * width, arr, offset + z * width + dx, width - dx);
Array.Copy(tmp, 0, arr, offset + z * width, dx);
}
}
ArrayPool<T>.Release(ref tmp);
}
if (dz != 0) {
if (dz < 0) dz = depth + dz;
var tmp = ArrayPool<T>.Claim(dz * width);
for (int y = 0; y < height; y++) {
var offset = y * width * depth;
Array.Copy(arr, offset + (depth - dz) * width, tmp, 0, dz * width);
Array.Copy(arr, offset, arr, offset + dz * width, (depth - dz) * width);
Array.Copy(tmp, 0, arr, offset, dz * width);
}
ArrayPool<T>.Release(ref tmp);
}
}
}
}
|