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.
- package/.gitattributes +63 -0
- package/CHANGELOG.md +0 -0
- package/CHANGELOG.md.meta +7 -0
- package/Editor/AnimationCreator.cs +218 -0
- package/Editor/AnimationCreator.cs.meta +11 -0
- package/Editor/AnimationEventEditor.cs +742 -0
- package/Editor/AnimationEventEditor.cs.meta +11 -0
- package/Editor/PrefabCheckWizard.cs +140 -0
- package/Editor/PrefabCheckWizard.cs.meta +11 -0
- package/Editor/WallstopStudios.UnityHelpers.Editor.asmdef +16 -0
- package/Editor/WallstopStudios.UnityHelpers.Editor.asmdef.meta +7 -0
- package/Editor.meta +8 -0
- package/LICENSE +21 -0
- package/LICENSE.md +7 -0
- package/LICENSE.md.meta +7 -0
- package/LICENSE.meta +7 -0
- package/README.md +2 -0
- package/README.md.meta +7 -0
- package/Runtime/Core/Attributes/AnimationEventAttribute.cs +102 -0
- package/Runtime/Core/Attributes/AnimationEventAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/AutomaticallyFindAttribute.cs +43 -0
- package/Runtime/Core/Attributes/AutomaticallyFindAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/ChildComponentAttribute.cs +85 -0
- package/Runtime/Core/Attributes/ChildComponentAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/KSerializableAttribute.cs +23 -0
- package/Runtime/Core/Attributes/KSerializableAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/NotNullAttribute.cs +33 -0
- package/Runtime/Core/Attributes/NotNullAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/ParentComponent.cs +85 -0
- package/Runtime/Core/Attributes/ParentComponent.cs.meta +11 -0
- package/Runtime/Core/Attributes/ReadOnlyAttribute.cs +8 -0
- package/Runtime/Core/Attributes/ReadOnlyAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/RelationalComponentExtensions.cs +14 -0
- package/Runtime/Core/Attributes/RelationalComponentExtensions.cs.meta +11 -0
- package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +89 -0
- package/Runtime/Core/Attributes/SiblingComponentAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs +66 -0
- package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes.meta +8 -0
- package/Runtime/Core/DataStructure/Adapters/FastVector2Int.cs +91 -0
- package/Runtime/Core/DataStructure/Adapters/FastVector2Int.cs.meta +11 -0
- package/Runtime/Core/DataStructure/Adapters/FastVector3Int.cs +180 -0
- package/Runtime/Core/DataStructure/Adapters/FastVector3Int.cs.meta +11 -0
- package/Runtime/Core/DataStructure/Adapters/KGuid.cs +274 -0
- package/Runtime/Core/DataStructure/Adapters/KGuid.cs.meta +11 -0
- package/Runtime/Core/DataStructure/Adapters/KVector2.cs +79 -0
- package/Runtime/Core/DataStructure/Adapters/KVector2.cs.meta +11 -0
- package/Runtime/Core/DataStructure/Adapters.meta +8 -0
- package/Runtime/Core/DataStructure/Circle.cs +50 -0
- package/Runtime/Core/DataStructure/Circle.cs.meta +11 -0
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +130 -0
- package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +11 -0
- package/Runtime/Core/DataStructure/ISpatialTree.cs +58 -0
- package/Runtime/Core/DataStructure/ISpatialTree.cs.meta +11 -0
- package/Runtime/Core/DataStructure/KDTree.cs +186 -0
- package/Runtime/Core/DataStructure/KDTree.cs.meta +11 -0
- package/Runtime/Core/DataStructure/QuadTree.cs +184 -0
- package/Runtime/Core/DataStructure/QuadTree.cs.meta +11 -0
- package/Runtime/Core/DataStructure/RTree.cs +247 -0
- package/Runtime/Core/DataStructure/RTree.cs.meta +11 -0
- package/Runtime/Core/DataStructure/StringWrapper.cs +90 -0
- package/Runtime/Core/DataStructure/StringWrapper.cs.meta +11 -0
- package/Runtime/Core/DataStructure/TimedCache.cs +50 -0
- package/Runtime/Core/DataStructure/TimedCache.cs.meta +11 -0
- package/Runtime/Core/DataStructure.meta +8 -0
- package/Runtime/Core/Extension/AnimatorExtensions.cs +25 -0
- package/Runtime/Core/Extension/AnimatorExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/CircleExtensions.cs +25 -0
- package/Runtime/Core/Extension/CircleExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/ColorExtensions.cs +72 -0
- package/Runtime/Core/Extension/ColorExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/DictionaryExtensions.cs +173 -0
- package/Runtime/Core/Extension/DictionaryExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/DirectionExtensions.cs +210 -0
- package/Runtime/Core/Extension/DirectionExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/HashSetExtensions.cs +12 -0
- package/Runtime/Core/Extension/HashSetExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/IEnumerableExtensions.cs +109 -0
- package/Runtime/Core/Extension/IEnumerableExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/IListExtensions.cs +49 -0
- package/Runtime/Core/Extension/IListExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/LoggingExtensions.cs +196 -0
- package/Runtime/Core/Extension/LoggingExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/RandomExtensions.cs +110 -0
- package/Runtime/Core/Extension/RandomExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/StringExtensions.cs +76 -0
- package/Runtime/Core/Extension/StringExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension/UnityExtensions.cs +1409 -0
- package/Runtime/Core/Extension/UnityExtensions.cs.meta +11 -0
- package/Runtime/Core/Extension.meta +8 -0
- package/Runtime/Core/Helper/AssignUtilities.cs +14 -0
- package/Runtime/Core/Helper/AssignUtilities.cs.meta +11 -0
- package/Runtime/Core/Helper/Enumerables.cs +17 -0
- package/Runtime/Core/Helper/Enumerables.cs.meta +11 -0
- package/Runtime/Core/Helper/Geometry.cs +26 -0
- package/Runtime/Core/Helper/Geometry.cs.meta +11 -0
- package/Runtime/Core/Helper/Helpers.cs +1092 -0
- package/Runtime/Core/Helper/Helpers.cs.meta +11 -0
- package/Runtime/Core/Helper/IterationHelpers.cs +32 -0
- package/Runtime/Core/Helper/IterationHelpers.cs.meta +11 -0
- package/Runtime/Core/Helper/LifetimeHelpers.cs +12 -0
- package/Runtime/Core/Helper/LifetimeHelpers.cs.meta +11 -0
- package/Runtime/Core/Helper/Objects.cs +447 -0
- package/Runtime/Core/Helper/Objects.cs.meta +11 -0
- package/Runtime/Core/Helper/SpriteHelpers.cs +53 -0
- package/Runtime/Core/Helper/SpriteHelpers.cs.meta +11 -0
- package/Runtime/Core/Helper/StringInList.cs +31 -0
- package/Runtime/Core/Helper/StringInList.cs.meta +11 -0
- package/Runtime/Core/Helper/WallMath.cs +75 -0
- package/Runtime/Core/Helper/WallMath.cs.meta +11 -0
- package/Runtime/Core/Helper.meta +8 -0
- package/Runtime/Core/Math/Line.cs +51 -0
- package/Runtime/Core/Math/Line.cs.meta +11 -0
- package/Runtime/Core/Math/Parabola.cs +44 -0
- package/Runtime/Core/Math/Parabola.cs.meta +11 -0
- package/Runtime/Core/Math/PointPolygonCheck.cs +25 -0
- package/Runtime/Core/Math/PointPolygonCheck.cs.meta +11 -0
- package/Runtime/Core/Math/Range.cs +56 -0
- package/Runtime/Core/Math/Range.cs.meta +11 -0
- package/Runtime/Core/Math/XXHash.cs +308 -0
- package/Runtime/Core/Math/XXHash.cs.meta +11 -0
- package/Runtime/Core/Math.meta +8 -0
- package/Runtime/Core/Model/Direction.cs +26 -0
- package/Runtime/Core/Model/Direction.cs.meta +11 -0
- package/Runtime/Core/Model.meta +8 -0
- package/Runtime/Core/OneOf/FastOneOf.cs +145 -0
- package/Runtime/Core/OneOf/FastOneOf.cs.meta +11 -0
- package/Runtime/Core/OneOf/None.cs +6 -0
- package/Runtime/Core/OneOf/None.cs.meta +11 -0
- package/Runtime/Core/OneOf.meta +8 -0
- package/Runtime/Core/Random/AbstractRandom.cs +537 -0
- package/Runtime/Core/Random/AbstractRandom.cs.meta +11 -0
- package/Runtime/Core/Random/IRandom.cs +141 -0
- package/Runtime/Core/Random/IRandom.cs.meta +11 -0
- package/Runtime/Core/Random/NativePcgRandom.cs +97 -0
- package/Runtime/Core/Random/NativePcgRandom.cs.meta +11 -0
- package/Runtime/Core/Random/PcgRandom.cs +142 -0
- package/Runtime/Core/Random/PcgRandom.cs.meta +11 -0
- package/Runtime/Core/Random/RandomState.cs +92 -0
- package/Runtime/Core/Random/RandomState.cs.meta +11 -0
- package/Runtime/Core/Random/RandomUtilities.cs +26 -0
- package/Runtime/Core/Random/RandomUtilities.cs.meta +11 -0
- package/Runtime/Core/Random/SquirrelRandom.cs +82 -0
- package/Runtime/Core/Random/SquirrelRandom.cs.meta +11 -0
- package/Runtime/Core/Random/SystemRandom.cs +110 -0
- package/Runtime/Core/Random/SystemRandom.cs.meta +11 -0
- package/Runtime/Core/Random/ThreadLocalRandom.cs +11 -0
- package/Runtime/Core/Random/ThreadLocalRandom.cs.meta +11 -0
- package/Runtime/Core/Random/UnityRandom.cs +24 -0
- package/Runtime/Core/Random/UnityRandom.cs.meta +11 -0
- package/Runtime/Core/Random/XorShiftRandom.cs +45 -0
- package/Runtime/Core/Random/XorShiftRandom.cs.meta +11 -0
- package/Runtime/Core/Random.meta +8 -0
- package/Runtime/Core/Serialization/JsonConverters/Vector2Converter.cs +32 -0
- package/Runtime/Core/Serialization/JsonConverters/Vector2Converter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/Vector3Converter.cs +32 -0
- package/Runtime/Core/Serialization/JsonConverters/Vector3Converter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters.meta +8 -0
- package/Runtime/Core/Serialization/Serializer.cs +125 -0
- package/Runtime/Core/Serialization/Serializer.cs.meta +11 -0
- package/Runtime/Core/Serialization.meta +8 -0
- package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +102 -0
- package/Runtime/Core/Threading/SingleThreadedThreadPool.cs.meta +11 -0
- package/Runtime/Core/Threading.meta +8 -0
- package/Runtime/Core.meta +8 -0
- package/Runtime/Protobuf-Net/System.Buffers.dll +0 -0
- package/Runtime/Protobuf-Net/System.Buffers.dll.meta +33 -0
- package/Runtime/Protobuf-Net/System.Collections.Immutable.dll +0 -0
- package/Runtime/Protobuf-Net/System.Collections.Immutable.dll.meta +33 -0
- package/Runtime/Protobuf-Net/System.Numerics.Vectors.dll +0 -0
- package/Runtime/Protobuf-Net/System.Numerics.Vectors.dll.meta +33 -0
- package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.dll +0 -0
- package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.dll.meta +33 -0
- package/Runtime/Protobuf-Net/protobuf-net.Core.dll +0 -0
- package/Runtime/Protobuf-Net/protobuf-net.Core.dll.meta +33 -0
- package/Runtime/Protobuf-Net/protobuf-net.dll +0 -0
- package/Runtime/Protobuf-Net/protobuf-net.dll.meta +33 -0
- package/Runtime/Protobuf-Net.meta +8 -0
- package/Runtime/Utils/AnimationEventEqualityComparer.cs +149 -0
- package/Runtime/Utils/AnimationEventEqualityComparer.cs.meta +11 -0
- package/Runtime/Utils/AnimatorEnumStateMachine.cs +80 -0
- package/Runtime/Utils/AnimatorEnumStateMachine.cs.meta +11 -0
- package/Runtime/Utils/Buffers.cs +32 -0
- package/Runtime/Utils/Buffers.cs.meta +11 -0
- package/Runtime/Utils/CircleLineRenderer.cs +122 -0
- package/Runtime/Utils/CircleLineRenderer.cs.meta +11 -0
- package/Runtime/Utils/Oscillator.cs +25 -0
- package/Runtime/Utils/Oscillator.cs.meta +11 -0
- package/Runtime/Utils/SetTextureImportData.cs +67 -0
- package/Runtime/Utils/SetTextureImportData.cs.meta +11 -0
- package/Runtime/Utils.meta +8 -0
- package/Runtime/WallstopStudios.UnityHelpers.asmdef +14 -0
- package/Runtime/WallstopStudios.UnityHelpers.asmdef.meta +7 -0
- package/Runtime.meta +8 -0
- package/Tests/Editor/WallstopStudios.UnityHelpers.Tests.Editor.asmdef +17 -0
- package/Tests/Editor/WallstopStudios.UnityHelpers.Tests.Editor.asmdef.meta +7 -0
- package/Tests/Editor.meta +8 -0
- package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +14 -0
- package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs +14 -0
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +106 -0
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +14 -0
- package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures.meta +8 -0
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +14 -0
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +14 -0
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +76 -0
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +141 -0
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs.meta +11 -0
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +14 -0
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs.meta +11 -0
- package/Tests/Runtime/Performance.meta +8 -0
- package/Tests/Runtime/Random/PcgRandomTests.cs +9 -0
- package/Tests/Runtime/Random/PcgRandomTests.cs.meta +11 -0
- package/Tests/Runtime/Random/RandomTestBase.cs +117 -0
- package/Tests/Runtime/Random/RandomTestBase.cs.meta +11 -0
- package/Tests/Runtime/Random/SquirrelRandomTests.cs +9 -0
- package/Tests/Runtime/Random/SquirrelRandomTests.cs.meta +11 -0
- package/Tests/Runtime/Random/SystemRandomTests.cs +10 -0
- package/Tests/Runtime/Random/SystemRandomTests.cs.meta +11 -0
- package/Tests/Runtime/Random/UnityRandomTests.cs +9 -0
- package/Tests/Runtime/Random/UnityRandomTests.cs.meta +11 -0
- package/Tests/Runtime/Random/XorShiftRandomTests.cs +9 -0
- package/Tests/Runtime/Random/XorShiftRandomTests.cs.meta +11 -0
- package/Tests/Runtime/Random.meta +8 -0
- package/Tests/Runtime/WallstopStudios.UnityHelpers.Tests.Runtime.asmdef +22 -0
- package/Tests/Runtime/WallstopStudios.UnityHelpers.Tests.Runtime.asmdef.meta +7 -0
- package/Tests/Runtime.meta +8 -0
- package/Tests.meta +8 -0
- package/Third Party Notices.md +1 -0
- package/Third Party Notices.md.meta +7 -0
- package/package.json +35 -0
- 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,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,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,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,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,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,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,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
|
+
}
|