com.wallstop-studios.unity-helpers 1.0.0-rc4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/.gitattributes +63 -0
  2. package/CHANGELOG.md +0 -0
  3. package/CHANGELOG.md.meta +7 -0
  4. package/Editor/AnimationCreator.cs +218 -0
  5. package/Editor/AnimationCreator.cs.meta +11 -0
  6. package/Editor/AnimationEventEditor.cs +742 -0
  7. package/Editor/AnimationEventEditor.cs.meta +11 -0
  8. package/Editor/PrefabCheckWizard.cs +140 -0
  9. package/Editor/PrefabCheckWizard.cs.meta +11 -0
  10. package/Editor/WallstopStudios.UnityHelpers.Editor.asmdef +16 -0
  11. package/Editor/WallstopStudios.UnityHelpers.Editor.asmdef.meta +7 -0
  12. package/Editor.meta +8 -0
  13. package/LICENSE +21 -0
  14. package/LICENSE.md +7 -0
  15. package/LICENSE.md.meta +7 -0
  16. package/LICENSE.meta +7 -0
  17. package/README.md +2 -0
  18. package/README.md.meta +7 -0
  19. package/Runtime/Core/Attributes/AnimationEventAttribute.cs +102 -0
  20. package/Runtime/Core/Attributes/AnimationEventAttribute.cs.meta +11 -0
  21. package/Runtime/Core/Attributes/AutomaticallyFindAttribute.cs +43 -0
  22. package/Runtime/Core/Attributes/AutomaticallyFindAttribute.cs.meta +11 -0
  23. package/Runtime/Core/Attributes/ChildComponentAttribute.cs +85 -0
  24. package/Runtime/Core/Attributes/ChildComponentAttribute.cs.meta +11 -0
  25. package/Runtime/Core/Attributes/KSerializableAttribute.cs +23 -0
  26. package/Runtime/Core/Attributes/KSerializableAttribute.cs.meta +11 -0
  27. package/Runtime/Core/Attributes/NotNullAttribute.cs +33 -0
  28. package/Runtime/Core/Attributes/NotNullAttribute.cs.meta +11 -0
  29. package/Runtime/Core/Attributes/ParentComponent.cs +85 -0
  30. package/Runtime/Core/Attributes/ParentComponent.cs.meta +11 -0
  31. package/Runtime/Core/Attributes/ReadOnlyAttribute.cs +8 -0
  32. package/Runtime/Core/Attributes/ReadOnlyAttribute.cs.meta +11 -0
  33. package/Runtime/Core/Attributes/RelationalComponentExtensions.cs +14 -0
  34. package/Runtime/Core/Attributes/RelationalComponentExtensions.cs.meta +11 -0
  35. package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +89 -0
  36. package/Runtime/Core/Attributes/SiblingComponentAttribute.cs.meta +11 -0
  37. package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs +66 -0
  38. package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs.meta +11 -0
  39. package/Runtime/Core/Attributes.meta +8 -0
  40. package/Runtime/Core/DataStructure/Adapters/FastVector2Int.cs +91 -0
  41. package/Runtime/Core/DataStructure/Adapters/FastVector2Int.cs.meta +11 -0
  42. package/Runtime/Core/DataStructure/Adapters/FastVector3Int.cs +180 -0
  43. package/Runtime/Core/DataStructure/Adapters/FastVector3Int.cs.meta +11 -0
  44. package/Runtime/Core/DataStructure/Adapters/KGuid.cs +274 -0
  45. package/Runtime/Core/DataStructure/Adapters/KGuid.cs.meta +11 -0
  46. package/Runtime/Core/DataStructure/Adapters/KVector2.cs +79 -0
  47. package/Runtime/Core/DataStructure/Adapters/KVector2.cs.meta +11 -0
  48. package/Runtime/Core/DataStructure/Adapters.meta +8 -0
  49. package/Runtime/Core/DataStructure/Circle.cs +50 -0
  50. package/Runtime/Core/DataStructure/Circle.cs.meta +11 -0
  51. package/Runtime/Core/DataStructure/CyclicBuffer.cs +130 -0
  52. package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +11 -0
  53. package/Runtime/Core/DataStructure/ISpatialTree.cs +58 -0
  54. package/Runtime/Core/DataStructure/ISpatialTree.cs.meta +11 -0
  55. package/Runtime/Core/DataStructure/KDTree.cs +186 -0
  56. package/Runtime/Core/DataStructure/KDTree.cs.meta +11 -0
  57. package/Runtime/Core/DataStructure/QuadTree.cs +184 -0
  58. package/Runtime/Core/DataStructure/QuadTree.cs.meta +11 -0
  59. package/Runtime/Core/DataStructure/RTree.cs +247 -0
  60. package/Runtime/Core/DataStructure/RTree.cs.meta +11 -0
  61. package/Runtime/Core/DataStructure/StringWrapper.cs +90 -0
  62. package/Runtime/Core/DataStructure/StringWrapper.cs.meta +11 -0
  63. package/Runtime/Core/DataStructure/TimedCache.cs +50 -0
  64. package/Runtime/Core/DataStructure/TimedCache.cs.meta +11 -0
  65. package/Runtime/Core/DataStructure.meta +8 -0
  66. package/Runtime/Core/Extension/AnimatorExtensions.cs +25 -0
  67. package/Runtime/Core/Extension/AnimatorExtensions.cs.meta +11 -0
  68. package/Runtime/Core/Extension/CircleExtensions.cs +25 -0
  69. package/Runtime/Core/Extension/CircleExtensions.cs.meta +11 -0
  70. package/Runtime/Core/Extension/ColorExtensions.cs +72 -0
  71. package/Runtime/Core/Extension/ColorExtensions.cs.meta +11 -0
  72. package/Runtime/Core/Extension/DictionaryExtensions.cs +173 -0
  73. package/Runtime/Core/Extension/DictionaryExtensions.cs.meta +11 -0
  74. package/Runtime/Core/Extension/DirectionExtensions.cs +210 -0
  75. package/Runtime/Core/Extension/DirectionExtensions.cs.meta +11 -0
  76. package/Runtime/Core/Extension/HashSetExtensions.cs +12 -0
  77. package/Runtime/Core/Extension/HashSetExtensions.cs.meta +11 -0
  78. package/Runtime/Core/Extension/IEnumerableExtensions.cs +109 -0
  79. package/Runtime/Core/Extension/IEnumerableExtensions.cs.meta +11 -0
  80. package/Runtime/Core/Extension/IListExtensions.cs +49 -0
  81. package/Runtime/Core/Extension/IListExtensions.cs.meta +11 -0
  82. package/Runtime/Core/Extension/LoggingExtensions.cs +196 -0
  83. package/Runtime/Core/Extension/LoggingExtensions.cs.meta +11 -0
  84. package/Runtime/Core/Extension/RandomExtensions.cs +110 -0
  85. package/Runtime/Core/Extension/RandomExtensions.cs.meta +11 -0
  86. package/Runtime/Core/Extension/StringExtensions.cs +76 -0
  87. package/Runtime/Core/Extension/StringExtensions.cs.meta +11 -0
  88. package/Runtime/Core/Extension/UnityExtensions.cs +1409 -0
  89. package/Runtime/Core/Extension/UnityExtensions.cs.meta +11 -0
  90. package/Runtime/Core/Extension.meta +8 -0
  91. package/Runtime/Core/Helper/AssignUtilities.cs +14 -0
  92. package/Runtime/Core/Helper/AssignUtilities.cs.meta +11 -0
  93. package/Runtime/Core/Helper/Enumerables.cs +17 -0
  94. package/Runtime/Core/Helper/Enumerables.cs.meta +11 -0
  95. package/Runtime/Core/Helper/Geometry.cs +26 -0
  96. package/Runtime/Core/Helper/Geometry.cs.meta +11 -0
  97. package/Runtime/Core/Helper/Helpers.cs +1092 -0
  98. package/Runtime/Core/Helper/Helpers.cs.meta +11 -0
  99. package/Runtime/Core/Helper/IterationHelpers.cs +32 -0
  100. package/Runtime/Core/Helper/IterationHelpers.cs.meta +11 -0
  101. package/Runtime/Core/Helper/LifetimeHelpers.cs +12 -0
  102. package/Runtime/Core/Helper/LifetimeHelpers.cs.meta +11 -0
  103. package/Runtime/Core/Helper/Objects.cs +447 -0
  104. package/Runtime/Core/Helper/Objects.cs.meta +11 -0
  105. package/Runtime/Core/Helper/SpriteHelpers.cs +53 -0
  106. package/Runtime/Core/Helper/SpriteHelpers.cs.meta +11 -0
  107. package/Runtime/Core/Helper/StringInList.cs +31 -0
  108. package/Runtime/Core/Helper/StringInList.cs.meta +11 -0
  109. package/Runtime/Core/Helper/WallMath.cs +75 -0
  110. package/Runtime/Core/Helper/WallMath.cs.meta +11 -0
  111. package/Runtime/Core/Helper.meta +8 -0
  112. package/Runtime/Core/Math/Line.cs +51 -0
  113. package/Runtime/Core/Math/Line.cs.meta +11 -0
  114. package/Runtime/Core/Math/Parabola.cs +44 -0
  115. package/Runtime/Core/Math/Parabola.cs.meta +11 -0
  116. package/Runtime/Core/Math/PointPolygonCheck.cs +25 -0
  117. package/Runtime/Core/Math/PointPolygonCheck.cs.meta +11 -0
  118. package/Runtime/Core/Math/Range.cs +56 -0
  119. package/Runtime/Core/Math/Range.cs.meta +11 -0
  120. package/Runtime/Core/Math/XXHash.cs +308 -0
  121. package/Runtime/Core/Math/XXHash.cs.meta +11 -0
  122. package/Runtime/Core/Math.meta +8 -0
  123. package/Runtime/Core/Model/Direction.cs +26 -0
  124. package/Runtime/Core/Model/Direction.cs.meta +11 -0
  125. package/Runtime/Core/Model.meta +8 -0
  126. package/Runtime/Core/OneOf/FastOneOf.cs +145 -0
  127. package/Runtime/Core/OneOf/FastOneOf.cs.meta +11 -0
  128. package/Runtime/Core/OneOf/None.cs +6 -0
  129. package/Runtime/Core/OneOf/None.cs.meta +11 -0
  130. package/Runtime/Core/OneOf.meta +8 -0
  131. package/Runtime/Core/Random/AbstractRandom.cs +537 -0
  132. package/Runtime/Core/Random/AbstractRandom.cs.meta +11 -0
  133. package/Runtime/Core/Random/IRandom.cs +141 -0
  134. package/Runtime/Core/Random/IRandom.cs.meta +11 -0
  135. package/Runtime/Core/Random/NativePcgRandom.cs +97 -0
  136. package/Runtime/Core/Random/NativePcgRandom.cs.meta +11 -0
  137. package/Runtime/Core/Random/PcgRandom.cs +142 -0
  138. package/Runtime/Core/Random/PcgRandom.cs.meta +11 -0
  139. package/Runtime/Core/Random/RandomState.cs +92 -0
  140. package/Runtime/Core/Random/RandomState.cs.meta +11 -0
  141. package/Runtime/Core/Random/RandomUtilities.cs +26 -0
  142. package/Runtime/Core/Random/RandomUtilities.cs.meta +11 -0
  143. package/Runtime/Core/Random/SquirrelRandom.cs +82 -0
  144. package/Runtime/Core/Random/SquirrelRandom.cs.meta +11 -0
  145. package/Runtime/Core/Random/SystemRandom.cs +110 -0
  146. package/Runtime/Core/Random/SystemRandom.cs.meta +11 -0
  147. package/Runtime/Core/Random/ThreadLocalRandom.cs +11 -0
  148. package/Runtime/Core/Random/ThreadLocalRandom.cs.meta +11 -0
  149. package/Runtime/Core/Random/UnityRandom.cs +24 -0
  150. package/Runtime/Core/Random/UnityRandom.cs.meta +11 -0
  151. package/Runtime/Core/Random/XorShiftRandom.cs +45 -0
  152. package/Runtime/Core/Random/XorShiftRandom.cs.meta +11 -0
  153. package/Runtime/Core/Random.meta +8 -0
  154. package/Runtime/Core/Serialization/JsonConverters/Vector2Converter.cs +32 -0
  155. package/Runtime/Core/Serialization/JsonConverters/Vector2Converter.cs.meta +11 -0
  156. package/Runtime/Core/Serialization/JsonConverters/Vector3Converter.cs +32 -0
  157. package/Runtime/Core/Serialization/JsonConverters/Vector3Converter.cs.meta +11 -0
  158. package/Runtime/Core/Serialization/JsonConverters.meta +8 -0
  159. package/Runtime/Core/Serialization/Serializer.cs +125 -0
  160. package/Runtime/Core/Serialization/Serializer.cs.meta +11 -0
  161. package/Runtime/Core/Serialization.meta +8 -0
  162. package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +102 -0
  163. package/Runtime/Core/Threading/SingleThreadedThreadPool.cs.meta +11 -0
  164. package/Runtime/Core/Threading.meta +8 -0
  165. package/Runtime/Core.meta +8 -0
  166. package/Runtime/Protobuf-Net/System.Buffers.dll +0 -0
  167. package/Runtime/Protobuf-Net/System.Buffers.dll.meta +33 -0
  168. package/Runtime/Protobuf-Net/System.Collections.Immutable.dll +0 -0
  169. package/Runtime/Protobuf-Net/System.Collections.Immutable.dll.meta +33 -0
  170. package/Runtime/Protobuf-Net/System.Numerics.Vectors.dll +0 -0
  171. package/Runtime/Protobuf-Net/System.Numerics.Vectors.dll.meta +33 -0
  172. package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.dll +0 -0
  173. package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.dll.meta +33 -0
  174. package/Runtime/Protobuf-Net/protobuf-net.Core.dll +0 -0
  175. package/Runtime/Protobuf-Net/protobuf-net.Core.dll.meta +33 -0
  176. package/Runtime/Protobuf-Net/protobuf-net.dll +0 -0
  177. package/Runtime/Protobuf-Net/protobuf-net.dll.meta +33 -0
  178. package/Runtime/Protobuf-Net.meta +8 -0
  179. package/Runtime/Utils/AnimationEventEqualityComparer.cs +149 -0
  180. package/Runtime/Utils/AnimationEventEqualityComparer.cs.meta +11 -0
  181. package/Runtime/Utils/AnimatorEnumStateMachine.cs +80 -0
  182. package/Runtime/Utils/AnimatorEnumStateMachine.cs.meta +11 -0
  183. package/Runtime/Utils/Buffers.cs +32 -0
  184. package/Runtime/Utils/Buffers.cs.meta +11 -0
  185. package/Runtime/Utils/CircleLineRenderer.cs +122 -0
  186. package/Runtime/Utils/CircleLineRenderer.cs.meta +11 -0
  187. package/Runtime/Utils/Oscillator.cs +25 -0
  188. package/Runtime/Utils/Oscillator.cs.meta +11 -0
  189. package/Runtime/Utils/SetTextureImportData.cs +67 -0
  190. package/Runtime/Utils/SetTextureImportData.cs.meta +11 -0
  191. package/Runtime/Utils.meta +8 -0
  192. package/Runtime/WallstopStudios.UnityHelpers.asmdef +14 -0
  193. package/Runtime/WallstopStudios.UnityHelpers.asmdef.meta +7 -0
  194. package/Runtime.meta +8 -0
  195. package/Tests/Editor/WallstopStudios.UnityHelpers.Tests.Editor.asmdef +17 -0
  196. package/Tests/Editor/WallstopStudios.UnityHelpers.Tests.Editor.asmdef.meta +7 -0
  197. package/Tests/Editor.meta +8 -0
  198. package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +14 -0
  199. package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs.meta +11 -0
  200. package/Tests/Runtime/DataStructures/QuadTreeTests.cs +14 -0
  201. package/Tests/Runtime/DataStructures/QuadTreeTests.cs.meta +11 -0
  202. package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +106 -0
  203. package/Tests/Runtime/DataStructures/SpatialTreeTests.cs.meta +11 -0
  204. package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +14 -0
  205. package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs.meta +11 -0
  206. package/Tests/Runtime/DataStructures.meta +8 -0
  207. package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +14 -0
  208. package/Tests/Runtime/Performance/KDTreePerformanceTests.cs.meta +11 -0
  209. package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +14 -0
  210. package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs.meta +11 -0
  211. package/Tests/Runtime/Performance/RandomPerformanceTests.cs +76 -0
  212. package/Tests/Runtime/Performance/RandomPerformanceTests.cs.meta +11 -0
  213. package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +141 -0
  214. package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs.meta +11 -0
  215. package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +14 -0
  216. package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs.meta +11 -0
  217. package/Tests/Runtime/Performance.meta +8 -0
  218. package/Tests/Runtime/Random/PcgRandomTests.cs +9 -0
  219. package/Tests/Runtime/Random/PcgRandomTests.cs.meta +11 -0
  220. package/Tests/Runtime/Random/RandomTestBase.cs +117 -0
  221. package/Tests/Runtime/Random/RandomTestBase.cs.meta +11 -0
  222. package/Tests/Runtime/Random/SquirrelRandomTests.cs +9 -0
  223. package/Tests/Runtime/Random/SquirrelRandomTests.cs.meta +11 -0
  224. package/Tests/Runtime/Random/SystemRandomTests.cs +10 -0
  225. package/Tests/Runtime/Random/SystemRandomTests.cs.meta +11 -0
  226. package/Tests/Runtime/Random/UnityRandomTests.cs +9 -0
  227. package/Tests/Runtime/Random/UnityRandomTests.cs.meta +11 -0
  228. package/Tests/Runtime/Random/XorShiftRandomTests.cs +9 -0
  229. package/Tests/Runtime/Random/XorShiftRandomTests.cs.meta +11 -0
  230. package/Tests/Runtime/Random.meta +8 -0
  231. package/Tests/Runtime/WallstopStudios.UnityHelpers.Tests.Runtime.asmdef +22 -0
  232. package/Tests/Runtime/WallstopStudios.UnityHelpers.Tests.Runtime.asmdef.meta +7 -0
  233. package/Tests/Runtime.meta +8 -0
  234. package/Tests.meta +8 -0
  235. package/Third Party Notices.md +1 -0
  236. package/Third Party Notices.md.meta +7 -0
  237. package/package.json +35 -0
  238. package/package.json.meta +7 -0
@@ -0,0 +1,106 @@
1
+ namespace UnityHelpers.Tests.DataStructures
2
+ {
3
+ using System.Collections.Generic;
4
+ using System.Linq;
5
+ using Core.DataStructure;
6
+ using Core.Helper;
7
+ using Core.Random;
8
+ using NUnit.Framework;
9
+ using Vector2 = UnityEngine.Vector2;
10
+
11
+ public abstract class SpatialTreeTests<TTree> where TTree : ISpatialTree<Vector2>
12
+ {
13
+ private IRandom Random => PcgRandom.Instance;
14
+
15
+ protected abstract TTree CreateTree(IEnumerable<Vector2> points);
16
+
17
+ [Test]
18
+ public void SimpleWithinCircle()
19
+ {
20
+ Vector2 center = new(Random.NextFloat(-100, 100), Random.NextFloat(-100, 100));
21
+ float radius = Random.NextFloat(5, 25f);
22
+
23
+ const int numPoints = 1_000;
24
+ HashSet<Vector2> points = new(numPoints);
25
+ for (int i = 0; i < numPoints; ++i)
26
+ {
27
+ Vector2 point;
28
+ do
29
+ {
30
+ point = Helpers.GetRandomPointInCircle(center, radius);
31
+ }
32
+ while (!points.Add(point));
33
+ }
34
+
35
+ TTree quadTree = CreateTree(points);
36
+
37
+ List<Vector2> pointsInRange = quadTree.GetElementsInRange(center, radius).ToList();
38
+ Assert.IsTrue(points.SetEquals(pointsInRange), "Found {0} points in range, expected {1}.", pointsInRange.Count, points.Count);
39
+ // Translate by a unit-square - there should be no points in this range
40
+ Vector2 offset = center;
41
+ offset.x -= radius * 2;
42
+ offset.y -= radius * 2;
43
+
44
+ pointsInRange = quadTree.GetElementsInRange(offset, radius).ToList();
45
+ Assert.AreEqual(
46
+ 0, pointsInRange.Count, "Found {0} points within {1} range of {2} (original center {3})",
47
+ pointsInRange.Count, radius, offset, center);
48
+ }
49
+
50
+ [Test]
51
+ public void SimplePointOutsideRange()
52
+ {
53
+ Vector2 point = new(Random.NextFloat(-100, 100), Random.NextFloat(-100, 100));
54
+
55
+ Vector2 direction = Helpers.GetRandomPointInCircle(Vector2.zero, 1f).normalized;
56
+ float range = Random.NextFloat(25, 1_000);
57
+ Vector2 testPoint = point + (direction * range);
58
+ List<Vector2> points = new(1) { testPoint };
59
+
60
+ TTree quadTree = CreateTree(points);
61
+ List<Vector2> pointsInRange = quadTree.GetElementsInRange(point, range * 0.99f).ToList();
62
+ Assert.AreEqual(0, pointsInRange.Count);
63
+ pointsInRange = quadTree.GetElementsInRange(point, range * 1.01f).ToList();
64
+ Assert.AreEqual(1, pointsInRange.Count, "Failed to find point {0} from test point {1} with {2:0.00} range.", point, testPoint, range);
65
+ Assert.AreEqual(testPoint, pointsInRange[0]);
66
+ }
67
+
68
+ [Test]
69
+ public void SimpleANN()
70
+ {
71
+ List<Vector2> points = new();
72
+ for (int x = 0; x < 100; ++x)
73
+ {
74
+ for (int y = 0; y < 100; ++y)
75
+ {
76
+ Vector2 point = new(x, y);
77
+ points.Add(point);
78
+ }
79
+ }
80
+
81
+ TTree quadTree = CreateTree(points);
82
+ Vector2 center = quadTree.Boundary.center;
83
+
84
+ List<Vector2> nearestNeighbors = new();
85
+ int nearestNeighborCount = 1;
86
+ quadTree.GetApproximateNearestNeighbors(center, nearestNeighborCount, nearestNeighbors);
87
+ Assert.AreEqual(nearestNeighborCount, nearestNeighbors.Count);
88
+ Assert.IsTrue(nearestNeighbors.All(neighbor => (neighbor - center).magnitude <= 2f));
89
+
90
+ nearestNeighborCount = 4;
91
+ quadTree.GetApproximateNearestNeighbors(center, nearestNeighborCount, nearestNeighbors);
92
+ Assert.AreEqual(nearestNeighborCount, nearestNeighbors.Count);
93
+ Assert.IsTrue(nearestNeighbors.All(neighbor => (neighbor - center).magnitude <= 2.2f));
94
+
95
+ nearestNeighborCount = 16;
96
+ quadTree.GetApproximateNearestNeighbors(center, nearestNeighborCount, nearestNeighbors);
97
+ Assert.AreEqual(nearestNeighborCount, nearestNeighbors.Count);
98
+ Assert.IsTrue(nearestNeighbors.All(neighbor => (neighbor - center).magnitude <= 5.6f), "Max: {0}", nearestNeighbors.Select(neighbor => (neighbor - center).magnitude).Max());
99
+
100
+ center = new Vector2(-100, -100);
101
+
102
+ quadTree.GetApproximateNearestNeighbors(center, nearestNeighborCount, nearestNeighbors);
103
+ Assert.AreEqual(nearestNeighborCount, nearestNeighbors.Count);
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 0445f017299145d419297a7e0da52411
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,14 @@
1
+ namespace UnityHelpers.Tests.DataStructures
2
+ {
3
+ using System.Collections.Generic;
4
+ using UnityEngine;
5
+ using Core.DataStructure;
6
+
7
+ public sealed class UnbalancedKDTreeTests : SpatialTreeTests<KDTree<Vector2>>
8
+ {
9
+ protected override KDTree<Vector2> CreateTree(IEnumerable<Vector2> points)
10
+ {
11
+ return new KDTree<Vector2>(points, _ => _, balanced: false);
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 9b456860735e5b04d80f1423f2d92a98
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 85bbbe201ca08f241959c78b20b73e22
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,14 @@
1
+ namespace UnityHelpers.Tests.Performance
2
+ {
3
+ using System.Collections.Generic;
4
+ using Core.DataStructure;
5
+ using UnityEngine;
6
+
7
+ public sealed class KDTreePerformanceTests : SpatialTreePerformanceTest<KDTree<Vector2>>
8
+ {
9
+ protected override KDTree<Vector2> CreateTree(IEnumerable<Vector2> points)
10
+ {
11
+ return new KDTree<Vector2>(points, _ => _);
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: aec27da8346dc82439a2b67406674902
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,14 @@
1
+ namespace UnityHelpers.Tests.Performance
2
+ {
3
+ using System.Collections.Generic;
4
+ using UnityEngine;
5
+ using Core.DataStructure;
6
+
7
+ public sealed class QuadTreePerformanceTests : SpatialTreePerformanceTest<QuadTree<Vector2>>
8
+ {
9
+ protected override QuadTree<Vector2> CreateTree(IEnumerable<Vector2> points)
10
+ {
11
+ return new QuadTree<Vector2>(points, _ => _);
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 9a83172c3da6b894d850aae0b3aae31e
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,76 @@
1
+ namespace UnityHelpers.Tests.Performance
2
+ {
3
+ using System;
4
+ using System.Diagnostics;
5
+ using NUnit.Framework;
6
+ using UnityHelpers.Core.Random;
7
+
8
+ public sealed class RandomPerformanceTests
9
+ {
10
+ [Test]
11
+ public void Benchmark()
12
+ {
13
+ TimeSpan timeout = TimeSpan.FromSeconds(1);
14
+
15
+ UnityEngine.Debug.Log($"| Random | Next | NextFloat | NextDouble |");
16
+ UnityEngine.Debug.Log($"| ------ | ---- | --------- | ---------- |");
17
+
18
+ RunTest(new PcgRandom(), timeout);
19
+ RunTest(new SystemRandom(), timeout);
20
+ RunTest(new SquirrelRandom(), timeout);
21
+ RunTest(new XorShiftRandom(), timeout);
22
+ }
23
+
24
+ private void RunTest<T>(T random, TimeSpan timeout) where T : IRandom
25
+ {
26
+ int nextInt = RunNext(timeout, random);
27
+ int nextFloat = RunNextFloat(timeout, random);
28
+ int nextDouble = RunNextDouble(timeout, random);
29
+
30
+ UnityEngine.Debug.Log($"| {random.GetType().Name} | {(nextInt / timeout.TotalSeconds):N0} | {(nextFloat / timeout.TotalSeconds):N0} | {(nextDouble / timeout.TotalSeconds):N0} |");
31
+ }
32
+
33
+ // Copy-pasta'd for maximum speed
34
+ private int RunNext<T>(TimeSpan timeout, T random) where T : IRandom
35
+ {
36
+ int count = 0;
37
+ Stopwatch timer = Stopwatch.StartNew();
38
+ do
39
+ {
40
+ _ = random.Next();
41
+ ++count;
42
+ }
43
+ while (timer.Elapsed < timeout);
44
+
45
+ return count;
46
+ }
47
+
48
+ private int RunNextFloat<T>(TimeSpan timeout, T random) where T : IRandom
49
+ {
50
+ int count = 0;
51
+ Stopwatch timer = Stopwatch.StartNew();
52
+ do
53
+ {
54
+ _ = random.NextFloat();
55
+ ++count;
56
+ }
57
+ while (timer.Elapsed < timeout);
58
+
59
+ return count;
60
+ }
61
+
62
+ private int RunNextDouble<T>(TimeSpan timeout, T random) where T : IRandom
63
+ {
64
+ int count = 0;
65
+ Stopwatch timer = Stopwatch.StartNew();
66
+ do
67
+ {
68
+ _ = random.NextDouble();
69
+ ++count;
70
+ }
71
+ while (timer.Elapsed < timeout);
72
+
73
+ return count;
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: cd362cfc7f5bcc74fa5a42a2670f070c
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,141 @@
1
+ namespace UnityHelpers.Tests.Performance
2
+ {
3
+ using NUnit.Framework;
4
+ using System.Collections.Generic;
5
+ using System.Diagnostics;
6
+ using System;
7
+ using System.Collections;
8
+ using System.Linq;
9
+ using System.Threading.Tasks;
10
+ using UnityEngine;
11
+ using Core.DataStructure;
12
+ using UnityEngine.TestTools;
13
+
14
+ public abstract class SpatialTreePerformanceTest<TTree> where TTree : ISpatialTree<Vector2>
15
+ {
16
+ protected abstract TTree CreateTree(IEnumerable<Vector2> points);
17
+
18
+ [UnityTest]
19
+ public IEnumerator Performance()
20
+ {
21
+ UnityEngine.Debug.Log("| Operation | Operations / Second |");
22
+ UnityEngine.Debug.Log("| --------- | ------------------- |");
23
+
24
+ Vector2[] points = new Vector2[1_000_000];
25
+ float radius = 500;
26
+ ParallelLoopResult result = Parallel.For(0, 1_000_000, index =>
27
+ {
28
+ // ReSharper disable once PossibleLossOfFraction
29
+ points[index] = new Vector2(index % 1_000, index / 1_000);
30
+ });
31
+
32
+ while (!result.IsCompleted)
33
+ {
34
+ yield return null;
35
+ }
36
+
37
+ Stopwatch timer = Stopwatch.StartNew();
38
+ TTree tree = CreateTree(points);
39
+ timer.Stop();
40
+ UnityEngine.Debug.Log($"| Construction (1 million points) | {(int)Math.Floor(1 / timer.Elapsed.TotalSeconds)} ({timer.Elapsed.TotalSeconds} total) |");
41
+ Vector2 center = tree.Boundary.center;
42
+ int count = 0;
43
+ TimeSpan timeout = TimeSpan.FromSeconds(1);
44
+ timer.Restart();
45
+ do
46
+ {
47
+ int elementsInRange = tree.GetElementsInRange(center, radius).Count();
48
+ Assert.AreEqual(785456, elementsInRange);
49
+ ++count;
50
+ }
51
+ while (timer.Elapsed < timeout);
52
+
53
+ UnityEngine.Debug.Log($"| Elements In Range - Full | {(int)Math.Floor(count / timeout.TotalSeconds)} |");
54
+
55
+ radius /= 2f;
56
+ count = 0;
57
+ timer.Restart();
58
+ do
59
+ {
60
+ int elementsInRange = tree.GetElementsInRange(center, radius).Count();
61
+ Assert.AreEqual(196364, elementsInRange);
62
+ ++count;
63
+ }
64
+ while (timer.Elapsed < timeout);
65
+ UnityEngine.Debug.Log($"| Elements In Range - Half | {(int)Math.Floor(count / timeout.TotalSeconds)} |");
66
+
67
+ radius /= 2f;
68
+ count = 0;
69
+ timer.Restart();
70
+ do
71
+ {
72
+ int elementsInRange = tree.GetElementsInRange(center, radius).Count();
73
+ Assert.AreEqual(49080, elementsInRange);
74
+ ++count;
75
+ }
76
+ while (timer.Elapsed < timeout);
77
+ UnityEngine.Debug.Log($"| Elements In Range - Quarter | {(int)Math.Floor(count / timeout.TotalSeconds)} |");
78
+
79
+ radius = 1f;
80
+ count = 0;
81
+ timer.Restart();
82
+ do
83
+ {
84
+ int elementsInRange = tree.GetElementsInRange(center, radius).Count();
85
+ Assert.AreEqual(4, elementsInRange);
86
+ ++count;
87
+ }
88
+ while (timer.Elapsed < timeout);
89
+ UnityEngine.Debug.Log($"| Elements In Range - 1 Range | {(int)Math.Floor(count / timeout.TotalSeconds)} |");
90
+
91
+ int nearestNeighborCount = 500;
92
+ List<Vector2> nearestNeighbors = new();
93
+ count = 0;
94
+ timer.Restart();
95
+ do
96
+ {
97
+ tree.GetApproximateNearestNeighbors(center, nearestNeighborCount, nearestNeighbors);
98
+ Assert.IsTrue(nearestNeighbors.Count <= nearestNeighborCount);
99
+ ++count;
100
+ }
101
+ while (timer.Elapsed < timeout);
102
+ UnityEngine.Debug.Log($"| ANN - 500 | {(int)Math.Floor(count / timeout.TotalSeconds)} |");
103
+
104
+ nearestNeighborCount = 100;
105
+ count = 0;
106
+ timer.Restart();
107
+ do
108
+ {
109
+ tree.GetApproximateNearestNeighbors(center, nearestNeighborCount, nearestNeighbors);
110
+ Assert.IsTrue(nearestNeighbors.Count <= nearestNeighborCount);
111
+ ++count;
112
+ }
113
+ while (timer.Elapsed < timeout);
114
+ UnityEngine.Debug.Log($"| ANN - 100 | {(int)Math.Floor(count / timeout.TotalSeconds)} |");
115
+
116
+ nearestNeighborCount = 10;
117
+ count = 0;
118
+ timer.Restart();
119
+ do
120
+ {
121
+ tree.GetApproximateNearestNeighbors(center, nearestNeighborCount, nearestNeighbors);
122
+ Assert.IsTrue(nearestNeighbors.Count <= nearestNeighborCount);
123
+ ++count;
124
+ }
125
+ while (timer.Elapsed < timeout);
126
+ UnityEngine.Debug.Log($"| ANN - 10 | {(int)Math.Floor(count / timeout.TotalSeconds)} |");
127
+
128
+ nearestNeighborCount = 1;
129
+ count = 0;
130
+ timer.Restart();
131
+ do
132
+ {
133
+ tree.GetApproximateNearestNeighbors(center, nearestNeighborCount, nearestNeighbors);
134
+ Assert.IsTrue(nearestNeighbors.Count <= nearestNeighborCount);
135
+ ++count;
136
+ }
137
+ while (timer.Elapsed < timeout);
138
+ UnityEngine.Debug.Log($"| ANN - 1 | {(int)Math.Floor(count / timeout.TotalSeconds)} |");
139
+ }
140
+ }
141
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: dfc116ec86bb06747ba0d3471eb2bbba
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,14 @@
1
+ namespace UnityHelpers.Tests.Performance
2
+ {
3
+ using System.Collections.Generic;
4
+ using UnityEngine;
5
+ using Core.DataStructure;
6
+
7
+ public sealed class UnbalancedKDTreeTests : SpatialTreePerformanceTest<KDTree<Vector2>>
8
+ {
9
+ protected override KDTree<Vector2> CreateTree(IEnumerable<Vector2> points)
10
+ {
11
+ return new KDTree<Vector2>(points, _ => _, balanced: false);
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 6cc8f8f6f409cc540accf2e960fc2ee8
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: af87f90044cdc7140b0dc8a0fd6c11d2
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,9 @@
1
+ namespace UnityHelpers.Tests.Random
2
+ {
3
+ using UnityHelpers.Core.Random;
4
+
5
+ public sealed class PcgRandomTests : RandomTestBase
6
+ {
7
+ protected override IRandom NewRandom() => new PcgRandom();
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 1275f0d928181ce439edbcf9a7f0ca2e
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,117 @@
1
+ namespace UnityHelpers.Tests.Random
2
+ {
3
+ using System;
4
+ using System.Collections.Generic;
5
+ using System.Diagnostics;
6
+ using System.Linq;
7
+ using NUnit.Framework;
8
+ using UnityHelpers.Core.Random;
9
+
10
+ public abstract class RandomTestBase
11
+ {
12
+ protected const int SampleCount = 10_000_000;
13
+
14
+ protected int[] _samples = new int[1_000];
15
+
16
+ protected abstract IRandom NewRandom();
17
+
18
+ [SetUp]
19
+ public virtual void Setup()
20
+ {
21
+ Array.Clear(_samples, 0, _samples.Length);
22
+ }
23
+
24
+ [TearDown]
25
+ public virtual void Teardown()
26
+ {
27
+ // No-op in base
28
+ }
29
+
30
+ [Test]
31
+ public void Int()
32
+ {
33
+ TestAndVerify(random => random.Next(0, _samples.Length));
34
+ }
35
+
36
+ [Test]
37
+ public void Uint()
38
+ {
39
+ TestAndVerify(random => (int)random.NextUint(0, (uint)_samples.Length));
40
+ }
41
+
42
+ [Test]
43
+ public void Short()
44
+ {
45
+ TestAndVerify(random => random.NextShort(0, (short)_samples.Length));
46
+ }
47
+
48
+ [Test]
49
+ public void Byte()
50
+ {
51
+ TestAndVerify(random => random.NextByte(0, (byte)(_samples.Length < byte.MaxValue ? _samples.Length : byte.MaxValue)), byte.MaxValue);
52
+ }
53
+
54
+ [Test]
55
+ public void Float()
56
+ {
57
+ TestAndVerify(random => (int)Math.Floor(random.NextFloat(0, _samples.Length)));
58
+ }
59
+
60
+ [Test]
61
+ public void Double()
62
+ {
63
+ TestAndVerify(random => (int)Math.Floor(random.NextDouble(0, _samples.Length)));
64
+ }
65
+
66
+ [Test]
67
+ public void Long()
68
+ {
69
+ TestAndVerify(random => (int)random.NextLong(0, _samples.Length));
70
+ }
71
+
72
+ [Test]
73
+ public void Ulong()
74
+ {
75
+ TestAndVerify(random => (int)random.NextUlong(0, (ulong)_samples.Length));
76
+ }
77
+
78
+ protected void TestAndVerify(Func<IRandom, int> sample, int? maxLength = null)
79
+ {
80
+ IRandom random = NewRandom();
81
+ for (int i = 0; i < SampleCount; ++i)
82
+ {
83
+ int index = sample(random);
84
+ if (index < 0 || _samples.Length <= index)
85
+ {
86
+ Assert.Fail("Index {0} out of range", index);
87
+ }
88
+ else
89
+ {
90
+ _samples[index]++;
91
+ }
92
+ }
93
+
94
+ int sampleLength = Math.Min(_samples.Length, maxLength ?? _samples.Length);
95
+ double average = SampleCount * 1.0 / sampleLength;
96
+ double deviationAllowed = average * 0.05;
97
+ List<int> zeroCountIndexes = new();
98
+ List<int> outsideRange = new();
99
+ for (int i = 0; i < sampleLength; i++)
100
+ {
101
+ int count = _samples[i];
102
+ if (count == 0)
103
+ {
104
+ zeroCountIndexes.Add(i);
105
+ }
106
+
107
+ if (deviationAllowed < Math.Abs(count - average))
108
+ {
109
+ outsideRange.Add(i);
110
+ }
111
+ }
112
+
113
+ Assert.AreEqual(0, zeroCountIndexes.Count, "No samples at {0} indices: [{1}]", zeroCountIndexes.Count, string.Join(",", zeroCountIndexes));
114
+ Assert.AreEqual(0, outsideRange.Count, "{0} indexes outside of dev {1:0.00}. Expected: {2:0.00}. Found: [{3}]", outsideRange.Count, deviationAllowed, average, string.Join(",", outsideRange.Select(index => _samples[index])));
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 7742eba2bde9bee4192ce9349334b67a
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,9 @@
1
+ namespace UnityHelpers.Tests.Random
2
+ {
3
+ using UnityHelpers.Core.Random;
4
+
5
+ public sealed class SquirrelRandomTests : RandomTestBase
6
+ {
7
+ protected override IRandom NewRandom() => new SquirrelRandom();
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 1b42060f8efe0774ca7a1b5e67045d80
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,10 @@
1
+ namespace UnityHelpers.Tests.Random
2
+ {
3
+ using System;
4
+ using UnityHelpers.Core.Random;
5
+
6
+ public sealed class SystemRandomTests : RandomTestBase
7
+ {
8
+ protected override IRandom NewRandom() => new SystemRandom(Guid.NewGuid().GetHashCode());
9
+ }
10
+ }