summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Jobs/JobCreateTiles.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Jobs/JobCreateTiles.cs')
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Jobs/JobCreateTiles.cs115
1 files changed, 115 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Jobs/JobCreateTiles.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Jobs/JobCreateTiles.cs
new file mode 100644
index 0000000..44368b3
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Navmesh/Jobs/JobCreateTiles.cs
@@ -0,0 +1,115 @@
+using Pathfinding.Util;
+using Unity.Collections;
+using Unity.Jobs;
+using UnityEngine;
+using UnityEngine.Assertions;
+using UnityEngine.Profiling;
+
+namespace Pathfinding.Graphs.Navmesh.Jobs {
+ /// <summary>
+ /// Builds tiles optimized for pathfinding, from a list of <see cref="TileMesh.TileMeshUnsafe"/>.
+ ///
+ /// This job takes the following steps:
+ /// - Transform all vertices using the <see cref="graphToWorldSpace"/> matrix.
+ /// - Remove duplicate vertices
+ /// - If <see cref="recalculateNormals"/> is enabled: ensure all triangles are laid out in the clockwise direction.
+ /// </summary>
+ public struct JobCreateTiles : IJob {
+ /// <summary>An array of <see cref="TileMesh.TileMeshUnsafe"/> of length tileRect.Width*tileRect.Height</summary>
+ [ReadOnly]
+ public NativeArray<TileMesh.TileMeshUnsafe> tileMeshes;
+
+ /// <summary>
+ /// An array of <see cref="NavmeshTile"/> of length tileRect.Width*tileRect.Height.
+ /// This array will be filled with the created tiles.
+ /// </summary>
+ public System.Runtime.InteropServices.GCHandle tiles;
+
+ /// <summary>Graph index of the graph that these nodes will be added to</summary>
+ public uint graphIndex;
+
+ /// <summary>
+ /// Number of tiles in the graph.
+ ///
+ /// This may be much bigger than the <see cref="tileRect"/> that we are actually processing.
+ /// For example if a graph update is performed, the <see cref="tileRect"/> will just cover the tiles that are recalculated,
+ /// while <see cref="graphTileCount"/> will contain all tiles in the graph.
+ /// </summary>
+ public Int2 graphTileCount;
+
+ /// <summary>
+ /// Rectangle of tiles that we are processing.
+ ///
+ /// (xmax, ymax) must be smaller than graphTileCount.
+ /// If for examples <see cref="graphTileCount"/> is (10, 10) and <see cref="tileRect"/> is {2, 3, 5, 6} then we are processing tiles (2, 3) to (5, 6) inclusive.
+ /// </summary>
+ public IntRect tileRect;
+
+ /// <summary>Initial penalty for all nodes in the tile</summary>
+ public uint initialPenalty;
+
+ /// <summary>
+ /// If true, all triangles will be guaranteed to be laid out in clockwise order.
+ /// If false, their original order will be preserved.
+ /// </summary>
+ public bool recalculateNormals;
+
+ /// <summary>Size of a tile in world units along the graph's X and Z axes</summary>
+ public Vector2 tileWorldSize;
+
+ /// <summary>Matrix to convert from graph space to world space</summary>
+ public Matrix4x4 graphToWorldSpace;
+
+ public void Execute () {
+ var tiles = (NavmeshTile[])this.tiles.Target;
+ Assert.AreEqual(tileMeshes.Length, tiles.Length);
+ Assert.AreEqual(tileRect.Area, tileMeshes.Length);
+ Assert.IsTrue(tileRect.xmax < graphTileCount.x);
+ Assert.IsTrue(tileRect.ymax < graphTileCount.y);
+
+ var tileRectWidth = tileRect.Width;
+ var tileRectDepth = tileRect.Height;
+
+ for (int z = 0; z < tileRectDepth; z++) {
+ for (int x = 0; x < tileRectWidth; x++) {
+ var tileIndex = z*tileRectWidth + x;
+ // If we are just updating a part of the graph we still want to assign the nodes the proper global tile index
+ var graphTileIndex = (z + tileRect.ymin)*graphTileCount.x + (x + tileRect.xmin);
+ var mesh = tileMeshes[tileIndex];
+
+ // Convert tile space to graph space and world space
+ var verticesInGraphSpace = mesh.verticesInTileSpace.AsUnsafeSpan<Int3>().Clone(Allocator.Persistent);
+ var verticesInWorldSpace = verticesInGraphSpace.Clone(Allocator.Persistent);
+ var tileSpaceToGraphSpaceOffset = (Int3) new Vector3(tileWorldSize.x * (x + tileRect.xmin), 0, tileWorldSize.y * (z + tileRect.ymin));
+ for (int i = 0; i < verticesInGraphSpace.Length; i++) {
+ var v = verticesInGraphSpace[i] + tileSpaceToGraphSpaceOffset;
+ verticesInGraphSpace[i] = v;
+ verticesInWorldSpace[i] = (Int3)graphToWorldSpace.MultiplyPoint3x4((Vector3)v);
+ }
+
+ // Create a new navmesh tile and assign its settings
+ var triangles = mesh.triangles.AsUnsafeSpan<int>().Clone(Allocator.Persistent);
+ var tile = new NavmeshTile {
+ x = x + tileRect.xmin,
+ z = z + tileRect.ymin,
+ w = 1,
+ d = 1,
+ tris = triangles,
+ vertsInGraphSpace = verticesInGraphSpace,
+ verts = verticesInWorldSpace,
+ bbTree = new BBTree(triangles, verticesInGraphSpace),
+ nodes = new TriangleMeshNode[triangles.Length/3],
+ // Leave empty for now, it will be filled in later
+ graph = null,
+ };
+
+ Profiler.BeginSample("CreateNodes");
+ NavmeshBase.CreateNodes(tile, tile.tris, graphTileIndex, graphIndex, mesh.tags.AsUnsafeSpan<uint>(), false, null, initialPenalty, false);
+ Profiler.EndSample();
+
+ tiles[tileIndex] = tile;
+ }
+ }
+ }
+ }
+}