Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
64a6d04
Create helper node class.
TheNexusAvenger Mar 1, 2022
72031a1
Remove neighbors to self when split.
TheNexusAvenger Mar 1, 2022
75fa18b
Add GetOuterNeighbors helper method.
TheNexusAvenger Mar 1, 2022
ca3d6de
Create edge helper class.
TheNexusAvenger Mar 1, 2022
5a927c2
Add polygon helper classes.
TheNexusAvenger Mar 1, 2022
b150cdd
Fix edge case with extra edges not part of a shape.
TheNexusAvenger Mar 1, 2022
c765e30
Add polygon optimization.
TheNexusAvenger Mar 1, 2022
6818ffa
Move classes. Change Polygons to Shapes.
TheNexusAvenger Mar 2, 2022
1fe8a8b
Remove unused methods.
TheNexusAvenger Mar 2, 2022
775f273
Implement height map to shapes solver.
TheNexusAvenger Mar 2, 2022
3e5c562
Add point in shape helper method.
TheNexusAvenger Mar 16, 2022
c26ba08
Add line intersection tester.
TheNexusAvenger Mar 16, 2022
832a0ca
Add generating nodes from shape.
TheNexusAvenger Mar 16, 2022
c46000a
Add shape nesting.
TheNexusAvenger Mar 16, 2022
2bc1a7e
Add additional test cases.
TheNexusAvenger Mar 23, 2022
3ca1a7f
Fix edge cases with point in shape.
TheNexusAvenger Mar 23, 2022
57526ba
Store bounding shape with inner shapes.
TheNexusAvenger Mar 23, 2022
c8cc170
Split line intersection test.
TheNexusAvenger Mar 23, 2022
8fda7b5
Test for inner shapes with checking for valid lines.
TheNexusAvenger Mar 23, 2022
23317e2
Generate nodes to contained shapes.
TheNexusAvenger Mar 23, 2022
5bced66
Generate nodes for shapes.
TheNexusAvenger Mar 23, 2022
fddd513
Add caching for solver results.
TheNexusAvenger Mar 23, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions Uchu.NavMesh.Test/Grid/EdgeTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Numerics;
using NUnit.Framework;
using Uchu.NavMesh.Grid;

namespace Uchu.NavMesh.Test.Grid;

public class EdgeTest
{
/// <summary>
/// First test edge used.
/// </summary>
public Edge TestEdge1 = new Edge(Vector3.One, Vector3.Zero);

/// <summary>
/// Second test edge used.
/// </summary>
public Edge TestEdge2 = new Edge(Vector3.Zero, Vector3.One);

/// <summary>
/// Tests the Equals method.
/// </summary>
[Test]
public void TestEquals()
{
Assert.AreEqual(this.TestEdge1, this.TestEdge1);
Assert.AreEqual(this.TestEdge2, this.TestEdge2);
Assert.AreEqual(this.TestEdge1, this.TestEdge2);
}

/// <summary>
/// Tests the GetHashCode method.
/// </summary>
[Test]
public void TestGetHashCode()
{
Assert.AreEqual(this.TestEdge1.GetHashCode(), this.TestEdge2.GetHashCode());
}
}
325 changes: 325 additions & 0 deletions Uchu.NavMesh.Test/Shape/OrderedShapeTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
using System.Collections.Generic;
using System.Numerics;
using NUnit.Framework;
using Uchu.NavMesh.Shape;

namespace Uchu.NavMesh.Test.Shape;

public class OrderedShapeTest
{
/// <summary>
/// Tests the Optimize method.
/// </summary>
[Test]
public void TestOptimize()
{
// Create the test shape.
var shape = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(0, 2),
new Vector2(0, 3),
new Vector2(1, 4),
new Vector2(1, 3),
new Vector2(1, 2),
new Vector2(1, 1),
new Vector2(1, 0),
new Vector2(1, -1),
new Vector2(0, -1),
},
};

// Test optimizing the shape.
shape.Optimize();
Assert.AreEqual(new List<Vector2>()
{
new Vector2(0, 3),
new Vector2(1, 4),
new Vector2(1, -1),
new Vector2(0, -1),
}, shape.Points);
}

/// <summary>
/// Tests the PointInShape method.
/// </summary>
[Test]
public void TestPointInShape()
{
// Create the test shape.
var shape = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(0, 0),
new Vector2(-2, -2),
new Vector2(-2, 2),
new Vector2(2, 2),
new Vector2(2, -2),
},
};

// Test that various parts are in the shape.
Assert.IsTrue(shape.PointInShape(new Vector2(0, 0)));
Assert.IsTrue(shape.PointInShape(new Vector2(0.5f, 1)));
Assert.IsTrue(shape.PointInShape(new Vector2(1.5f, -1)));
Assert.IsTrue(shape.PointInShape(new Vector2(0, 1)));
Assert.IsFalse(shape.PointInShape(new Vector2(0, -1)));
Assert.IsFalse(shape.PointInShape(new Vector2(-3, -1)));
Assert.IsFalse(shape.PointInShape(new Vector2(3, -1)));
Assert.IsFalse(shape.PointInShape(new Vector2(0, 3)));

// Test edges cases where the point is inline with the lines.
Assert.IsTrue(shape.PointInShape(new Vector2(-1, 0)));
Assert.IsTrue(shape.PointInShape(new Vector2(1, 0)));
Assert.IsFalse(shape.PointInShape(new Vector2(-3, 0)));
Assert.IsFalse(shape.PointInShape(new Vector2(3, 0)));
}

/// <summary>
/// Tests the LineValid method.
/// </summary>
[Test]
public void TestLineValid()
{
// Create the test shape.
var shape = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(0, 0),
new Vector2(-2, -2),
new Vector2(-2, 2),
new Vector2(2, 2),
new Vector2(2, -2),
},
};

// Test with lines that make up the shape.
Assert.IsTrue(shape.LineValid(new Vector2(0, 0), new Vector2(-2, -2)));
Assert.IsTrue(shape.LineValid(new Vector2(2, 2), new Vector2(-2, 2)));

// Test with lines completely inside or outside the shape.
Assert.IsTrue(shape.LineValid(new Vector2(-1, 1), new Vector2(1, 1)));
Assert.IsFalse(shape.LineValid(new Vector2(-2, -2), new Vector2(2, -2)));

// Test with intersections.
Assert.IsFalse(shape.LineValid(new Vector2(-1, -1), new Vector2(1, -1)));
Assert.IsFalse(shape.LineValid(new Vector2(-2, -2), new Vector2(2, 2)));
}

/// <summary>
/// Tests the LineValid method with a containing shape..
/// </summary>
[Test]
public void TestLineValidContainingShape()
{
// Create the test shape.
var shape = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-2, -2),
new Vector2(-2, 2),
new Vector2(2, 2),
new Vector2(2, -2),
},
Shapes = new List<OrderedShape>()
{
new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-1, -1),
new Vector2(-1, 1),
new Vector2(1, 1),
new Vector2(1, -1),
},
}
}
};

// Test with lines that make up the shape.
Assert.IsTrue(shape.LineValid(new Vector2(-2, 2), new Vector2(-2, -2)));
Assert.IsTrue(shape.LineValid(new Vector2(2, 2), new Vector2(-2, 2)));

// Test with lines completely inside or outside the shape.
Assert.IsTrue(shape.LineValid(new Vector2(-1, 1.5f), new Vector2(1, 1.5f)));
Assert.IsFalse(shape.LineValid(new Vector2(-3, -3), new Vector2(3, -3)));

// Test with lines that are part of the inner shape.
Assert.IsTrue(shape.LineValid(new Vector2(-1, -1), new Vector2(-1, 1)));
Assert.IsTrue(shape.LineValid(new Vector2(1, -1), new Vector2(1, 1)));

// Test with lines that intersect the inner shape.
Assert.IsFalse(shape.LineValid(new Vector2(-2, -2), new Vector2(2, 2)));
Assert.IsFalse(shape.LineValid(new Vector2(-2, 2), new Vector2(2, -2)));

// Test with lines inside the inner shape.
Assert.IsFalse(shape.LineValid(new Vector2(-1, -1), new Vector2(1, 1)));
Assert.IsFalse(shape.LineValid(new Vector2(-1, 1), new Vector2(-1, 1)));

// Test with intersections.
Assert.IsFalse(shape.LineValid(new Vector2(-3, -1), new Vector2(-1, -1)));
}

/// <summary>
/// Tests the TryAddShape method.
/// </summary>
[Test]
public void TestTryAddShape()
{
// Create several rectangles.
var shape1 = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-1, 0),
new Vector2(-1, 1),
new Vector2(1, 1),
new Vector2(1, 0),
},
};
var shape2 = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-1, 0),
new Vector2(-1, -1),
new Vector2(1, -1),
new Vector2(1, 0),
},
};
var shape3 = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-2, -2),
new Vector2(-2, 2),
new Vector2(2, 2),
new Vector2(2, -2),
},
};
var shape4 = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-3, -3),
new Vector2(-3, 3),
new Vector2(3, 3),
new Vector2(3, -3),
},
};

// Assert certain shapes that can't be added.
Assert.IsFalse(shape1.TryAddShape(shape2));
Assert.IsFalse(shape1.TryAddShape(shape3));

// Assert adding shapes.
Assert.IsTrue(shape4.TryAddShape(shape1));
Assert.IsTrue(shape4.TryAddShape(shape3));
Assert.IsTrue(shape4.TryAddShape(shape2));

// Assert the correct shapes are stored.
Assert.AreEqual(new List<OrderedShape>(), shape1.Shapes);
Assert.AreEqual(new List<OrderedShape>(), shape2.Shapes);
Assert.AreEqual(new List<OrderedShape>() {shape1, shape2}, shape3.Shapes);
Assert.AreEqual(new List<OrderedShape>() {shape3}, shape4.Shapes);
}

/// <summary>
/// Tests the GenerateGraph method.
/// </summary>
[Test]
public void TestGenerateGraph()
{
// Create the test shape.
var shape = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(0, -1),
new Vector2(-2, -2),
new Vector2(-2, 2),
new Vector2(2, 2),
new Vector2(2, -2),
},
};
shape.GenerateGraph();

// Test that the connected nodes are correct.
Assert.AreEqual(4, shape.Nodes[0].Nodes.Count);
Assert.AreEqual(new Vector2(-2, -2), shape.Nodes[0].Nodes[0].Point);
Assert.AreEqual(new Vector2(-2, 2), shape.Nodes[0].Nodes[1].Point);
Assert.AreEqual(new Vector2(2, 2), shape.Nodes[0].Nodes[2].Point);
Assert.AreEqual(new Vector2(2, -2), shape.Nodes[0].Nodes[3].Point);
Assert.AreEqual(3, shape.Nodes[1].Nodes.Count);
Assert.AreEqual(new Vector2(0, -1), shape.Nodes[1].Nodes[0].Point);
Assert.AreEqual(new Vector2(-2, 2), shape.Nodes[1].Nodes[1].Point);
Assert.AreEqual(new Vector2(2, 2), shape.Nodes[1].Nodes[2].Point);
Assert.AreEqual(4, shape.Nodes[2].Nodes.Count);
Assert.AreEqual(4, shape.Nodes[3].Nodes.Count);
Assert.AreEqual(3, shape.Nodes[4].Nodes.Count);
}

/// <summary>
/// Tests the GenerateGraph method with contained shapes.
/// </summary>
[Test]
public void TestGenerateGraphContainedShapes()
{
// Create the test shape.
var shape = new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-4, -4),
new Vector2(-4, 4),
new Vector2(4, 4),
new Vector2(4, -4),
},
Shapes = new List<OrderedShape>()
{
new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-2, -2),
new Vector2(-2, -1),
new Vector2(2, -1),
new Vector2(2, -2),
},
},
new OrderedShape()
{
Points = new List<Vector2>()
{
new Vector2(-2, 2),
new Vector2(-2, 1),
new Vector2(2, 1),
new Vector2(2, 2),
},
},
},
};
shape.GenerateGraph();

// Test that the connected nodes are correct.
// Due to how many nodes there are, only the totals are checked.
Assert.AreEqual(7, shape.Nodes[0].Nodes.Count);
Assert.AreEqual(7, shape.Nodes[1].Nodes.Count);
Assert.AreEqual(7, shape.Nodes[2].Nodes.Count);
Assert.AreEqual(7, shape.Nodes[3].Nodes.Count);
Assert.AreEqual(5, shape.Nodes[4].Nodes.Count);
Assert.AreEqual(6, shape.Nodes[5].Nodes.Count);
Assert.AreEqual(6, shape.Nodes[6].Nodes.Count);
Assert.AreEqual(5, shape.Nodes[7].Nodes.Count);
Assert.AreEqual(5, shape.Nodes[8].Nodes.Count);
Assert.AreEqual(6, shape.Nodes[9].Nodes.Count);
Assert.AreEqual(6, shape.Nodes[10].Nodes.Count);
Assert.AreEqual(5, shape.Nodes[11].Nodes.Count);
}
}
Loading