summaryrefslogtreecommitdiff
path: root/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Collisions.Tests/QuadTreeTests.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Plugins/MonoGame.Extended/tests/MonoGame.Extended.Collisions.Tests/QuadTreeTests.cs')
-rw-r--r--Plugins/MonoGame.Extended/tests/MonoGame.Extended.Collisions.Tests/QuadTreeTests.cs446
1 files changed, 446 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Collisions.Tests/QuadTreeTests.cs b/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Collisions.Tests/QuadTreeTests.cs
new file mode 100644
index 0000000..1013288
--- /dev/null
+++ b/Plugins/MonoGame.Extended/tests/MonoGame.Extended.Collisions.Tests/QuadTreeTests.cs
@@ -0,0 +1,446 @@
+using System.Collections.Generic;
+using MonoGame.Extended.Collisions.QuadTree;
+using Xunit;
+
+namespace MonoGame.Extended.Collisions.Tests
+{
+ public class QuadTreeTests
+ {
+ private QuadTree.QuadTree MakeTree()
+ {
+ // Bounds set to ensure actors will fit inside the tree with default bounds.
+ var bounds = _quadTreeArea;
+ var tree = new QuadTree.QuadTree(bounds);
+
+ return tree;
+ }
+
+ private RectangleF _quadTreeArea = new RectangleF(-10f, -15, 20.0f, 30.0f);
+
+ [Fact]
+ public void ConstructorTest()
+ {
+ var bounds = new RectangleF(-10f, -15, 20.0f, 30.0f);
+ var tree = new QuadTree.QuadTree(bounds);
+
+ Assert.Equal(bounds, tree.NodeBounds);
+ Assert.True(tree.IsLeaf);
+ }
+
+ [Fact]
+ public void NumTargetsEmptyTest()
+ {
+ var tree = MakeTree();
+
+ Assert.Equal(0, tree.NumTargets());
+ }
+
+ [Fact]
+ public void NumTargetsOneTest()
+ {
+ var tree = MakeTree();
+ var actor = new BasicActor();
+
+ tree.Insert(new QuadtreeData(actor));
+
+ Assert.Equal(1, tree.NumTargets());
+ }
+
+
+ [Fact]
+ public void NumTargetsMultipleTest()
+ {
+ var tree = MakeTree();
+ for (int i = 0; i < 5; i++)
+ {
+ tree.Insert(new QuadtreeData(new BasicActor()));
+ }
+
+ Assert.Equal(5, tree.NumTargets());
+ }
+
+ [Fact]
+ public void NumTargetsManyTest()
+ {
+ var tree = MakeTree();
+ for (int i = 0; i < 1000; i++)
+ {
+ tree.Insert(new QuadtreeData(new BasicActor()));
+ Assert.Equal(i + 1, tree.NumTargets());
+ }
+
+ Assert.Equal(1000, tree.NumTargets());
+ }
+
+ [Fact]
+ public void InsertOneTest()
+ {
+ var tree = MakeTree();
+ var actor = new BasicActor();
+
+ tree.Insert(new QuadtreeData(actor));
+
+ Assert.Equal(1, tree.NumTargets());
+ }
+
+ [Fact]
+ public void InsertOneOverlappingQuadrantsTest()
+ {
+ var tree = MakeTree();
+ var actor = new BasicActor
+ {
+ Bounds = new RectangleF(-2.5f, -2.5f, 5f, 5f)
+ };
+
+ tree.Insert(new QuadtreeData(actor));
+
+ Assert.Equal(1, tree.NumTargets());
+ }
+
+ [Fact]
+ public void InsertMultipleTest()
+ {
+ var tree = MakeTree();
+
+ for (int i = 0; i < 10; i++)
+ {
+ tree.Insert(new QuadtreeData(new BasicActor()
+ {
+ Bounds = new RectangleF(0, 0, 1, 1)
+ }));
+ }
+
+ Assert.Equal(10, tree.NumTargets());
+ }
+
+ [Fact]
+ public void InsertManyTest()
+ {
+ var tree = MakeTree();
+
+ for (int i = 0; i < 1000; i++)
+ {
+ tree.Insert(new QuadtreeData(new BasicActor()
+ {
+ Bounds = new RectangleF(0, 0, 1, 1)
+ }));
+ }
+
+ Assert.Equal(1000, tree.NumTargets());
+ }
+
+ [Fact]
+ public void InsertMultipleOverlappingQuadrantsTest()
+ {
+ var tree = MakeTree();
+
+ for (int i = 0; i < 10; i++)
+ {
+ var actor = new BasicActor()
+ {
+ Bounds = new RectangleF(-10f, -15, 20.0f, 30.0f)
+ };
+ tree.Insert(new QuadtreeData(actor));
+ }
+
+ Assert.Equal(10, tree.NumTargets());
+ }
+
+ [Fact]
+ public void RemoveToEmptyTest()
+ {
+ var actor = new BasicActor()
+ {
+ Bounds = new RectangleF(-5f, -7f, 10.0f, 15.0f)
+ };
+ var data = new QuadtreeData(actor);
+
+ var tree = MakeTree();
+ tree.Insert(data);
+
+ tree.Remove(data);
+
+ Assert.Equal(0, tree.NumTargets());
+ }
+
+ [Fact]
+ public void RemoveTwoTest()
+ {
+ var tree = MakeTree();
+ var inserted = new List<QuadtreeData>();
+ var numTargets = 2;
+
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor()
+ {
+ Bounds = new RectangleF(0, 0, 1, 1)
+ });
+ tree.Insert(data);
+ inserted.Add(data);
+ }
+
+
+ var inTree = numTargets;
+ Assert.Equal(inTree, tree.NumTargets());
+
+ foreach (var data in inserted)
+ {
+ tree.Remove(data);
+ Assert.Equal(--inTree, tree.NumTargets());
+ }
+ }
+
+ [Fact]
+ public void RemoveThreeTest()
+ {
+ var tree = MakeTree();
+ var inserted = new List<QuadtreeData>();
+ var numTargets = 3;
+
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor()
+ {
+ Bounds = new RectangleF(0, 0, 1, 1)
+ });
+ tree.Insert(data);
+ inserted.Add(data);
+ }
+
+
+ var inTree = numTargets;
+ Assert.Equal(inTree, tree.NumTargets());
+
+ foreach (var data in inserted)
+ {
+ tree.Remove(data);
+ Assert.Equal(--inTree, tree.NumTargets());
+ }
+ }
+
+ [Fact]
+ public void RemoveManyTest()
+ {
+ var tree = MakeTree();
+ var inserted = new List<QuadtreeData>();
+ var numTargets = 1000;
+
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor()
+ {
+ Bounds = new RectangleF(0, 0, 1, 1)
+ });
+ tree.Insert(data);
+ inserted.Add(data);
+ }
+
+
+ var inTree = numTargets;
+ Assert.Equal(inTree, tree.NumTargets());
+
+ foreach (var data in inserted)
+ {
+ data.RemoveFromAllParents();
+ Assert.Equal(--inTree, tree.NumTargets());
+ }
+ }
+
+
+ [Fact]
+ public void ShakeWhenEmptyTest()
+ {
+ var tree = MakeTree();
+ tree.Shake();
+
+ Assert.Equal(0, tree.NumTargets());
+ }
+
+ [Fact]
+ public void ShakeAfterSplittingWhenEmptyTest()
+ {
+ var tree = MakeTree();
+
+ tree.Split();
+ tree.Shake();
+ Assert.Equal(0, tree.NumTargets());
+ }
+
+ [Fact]
+ public void ShakeAfterSplittingNotEmptyTest()
+ {
+ var tree = MakeTree();
+
+ tree.Split();
+ var data = new QuadtreeData(new BasicActor());
+ tree.Insert(data);
+ tree.Shake();
+ Assert.Equal(1, tree.NumTargets());
+ }
+
+ [Fact]
+ public void ShakeWhenContainingOneTest()
+ {
+ var tree = MakeTree();
+ var numTargets = 1;
+
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor());
+ tree.Insert(data);
+ }
+
+ tree.Shake();
+ Assert.Equal(numTargets, tree.NumTargets());
+ }
+
+ [Fact]
+ public void ShakeWhenContainingTwoTest()
+ {
+ var tree = MakeTree();
+ var numTargets = 2;
+
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor());
+ tree.Insert(data);
+ }
+
+ tree.Shake();
+ Assert.Equal(numTargets, tree.NumTargets());
+ }
+
+ [Fact]
+ public void ShakeWhenContainingThreeTest()
+ {
+ var tree = MakeTree();
+ var numTargets = 3;
+
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor());
+ tree.Insert(data);
+ }
+
+ tree.Shake();
+ Assert.Equal(numTargets, tree.NumTargets());
+ }
+
+ [Fact]
+ public void ShakeWhenContainingManyTest()
+ {
+ var tree = MakeTree();
+ var numTargets = QuadTree.QuadTree.DefaultMaxObjectsPerNode + 1;
+
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor());
+ tree.Insert(data);
+ }
+
+ tree.Shake();
+ Assert.Equal(numTargets, tree.NumTargets());
+ }
+
+ [Fact]
+ public void QueryWhenEmptyTest()
+ {
+ var tree = MakeTree();
+
+ var query = tree.Query(ref _quadTreeArea);
+
+ Assert.Empty(query);
+ Assert.Equal(0, tree.NumTargets());
+ }
+
+ [Fact]
+ public void QueryNotOverlappingTest()
+ {
+ var tree = MakeTree();
+
+ var area = new RectangleF(100f, 100f, 1f, 1f);
+ var query = tree.Query(ref area);
+
+ Assert.Empty(query);
+ Assert.Equal(0, tree.NumTargets());
+ }
+
+ [Fact]
+ public void QueryLeafNodeNotEmptyTest()
+ {
+ var tree = MakeTree();
+ var actor = new BasicActor();
+ tree.Insert(new QuadtreeData(actor));
+
+ var query = tree.Query(ref _quadTreeArea);
+ Assert.Single(query);
+ Assert.Equal(tree.NumTargets(), query.Count);
+ }
+
+ [Fact]
+ public void QueryLeafNodeNoOverlapTest()
+ {
+ var tree = MakeTree();
+ var actor = new BasicActor();
+ tree.Insert(new QuadtreeData(actor));
+
+ var area = new RectangleF(100f, 100f, 1f, 1f);
+ var query = tree.Query(ref area);
+ Assert.Empty(query);
+ }
+
+ [Fact]
+ public void QueryLeafNodeMultipleTest()
+ {
+ var tree = MakeTree();
+ var numTargets = QuadTree.QuadTree.DefaultMaxObjectsPerNode;
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor());
+ tree.Insert(data);
+ }
+
+
+ var query = tree.Query(ref _quadTreeArea);
+ Assert.Equal(numTargets, query.Count);
+ Assert.Equal(tree.NumTargets(), query.Count);
+ }
+
+ [Fact]
+ public void QueryNonLeafManyTest()
+ {
+ var tree = MakeTree();
+ var numTargets = 2*QuadTree.QuadTree.DefaultMaxObjectsPerNode;
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor());
+ tree.Insert(data);
+ }
+
+
+ var query = tree.Query(ref _quadTreeArea);
+ Assert.Equal(numTargets, query.Count);
+ Assert.Equal(tree.NumTargets(), query.Count);
+ }
+
+ [Fact]
+ public void QueryTwiceConsecutiveTest()
+ {
+ var tree = MakeTree();
+ var numTargets = 2 * QuadTree.QuadTree.DefaultMaxObjectsPerNode;
+ for (int i = 0; i < numTargets; i++)
+ {
+ var data = new QuadtreeData(new BasicActor());
+ tree.Insert(data);
+ }
+
+
+ var query1 = tree.Query(ref _quadTreeArea);
+ var query2 = tree.Query(ref _quadTreeArea);
+ Assert.Equal(numTargets, query1.Count);
+ Assert.Equal(tree.NumTargets(), query1.Count);
+ Assert.Equal(query1.Count, query2.Count);
+ }
+ }
+}