public override void DeserializeExtraInfo(GraphSerializationContext ctx) { BinaryReader reader = ctx.reader; this.tileXCount = reader.ReadInt32(); if (this.tileXCount < 0) { return; } this.tileZCount = reader.ReadInt32(); this.tiles = new RecastGraph.NavmeshTile[this.tileXCount * this.tileZCount]; TriangleMeshNode.SetNavmeshHolder(ctx.graphIndex, this); for (int i = 0; i < this.tileZCount; i++) { for (int j = 0; j < this.tileXCount; j++) { int num = j + i * this.tileXCount; int num2 = reader.ReadInt32(); if (num2 < 0) { throw new Exception("Invalid tile coordinates (x < 0)"); } int num3 = reader.ReadInt32(); if (num3 < 0) { throw new Exception("Invalid tile coordinates (z < 0)"); } if (num2 != j || num3 != i) { this.tiles[num] = this.tiles[num3 * this.tileXCount + num2]; } else { RecastGraph.NavmeshTile navmeshTile = new RecastGraph.NavmeshTile(); navmeshTile.x = num2; navmeshTile.z = num3; navmeshTile.w = reader.ReadInt32(); navmeshTile.d = reader.ReadInt32(); navmeshTile.bbTree = new BBTree(); this.tiles[num] = navmeshTile; int num4 = reader.ReadInt32(); if (num4 % 3 != 0) { throw new Exception("Corrupt data. Triangle indices count must be divisable by 3. Got " + num4); } navmeshTile.tris = new int[num4]; for (int k = 0; k < navmeshTile.tris.Length; k++) { navmeshTile.tris[k] = reader.ReadInt32(); } navmeshTile.verts = new Int3[reader.ReadInt32()]; for (int l = 0; l < navmeshTile.verts.Length; l++) { navmeshTile.verts[l] = new Int3(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); } int num5 = reader.ReadInt32(); navmeshTile.nodes = new TriangleMeshNode[num5]; num <<= 12; for (int m = 0; m < navmeshTile.nodes.Length; m++) { TriangleMeshNode triangleMeshNode = new TriangleMeshNode(this.active); navmeshTile.nodes[m] = triangleMeshNode; triangleMeshNode.DeserializeNode(ctx); triangleMeshNode.v0 = (navmeshTile.tris[m * 3] | num); triangleMeshNode.v1 = (navmeshTile.tris[m * 3 + 1] | num); triangleMeshNode.v2 = (navmeshTile.tris[m * 3 + 2] | num); triangleMeshNode.UpdatePositionFromVertices(); } navmeshTile.bbTree.RebuildFrom(navmeshTile.nodes); } } } }
public void ReplaceTile(int x, int z, int w, int d, Int3[] verts, int[] tris, bool worldSpace) { if (x + w > this.tileXCount || z + d > this.tileZCount || x < 0 || z < 0) { throw new ArgumentException(string.Concat(new object[] { "Tile is placed at an out of bounds position or extends out of the graph bounds (", x, ", ", z, " [", w, ", ", d, "] ", this.tileXCount, " ", this.tileZCount, ")" })); } if (w < 1 || d < 1) { throw new ArgumentException(string.Concat(new object[] { "width and depth must be greater or equal to 1. Was ", w, ", ", d })); } for (int i = z; i < z + d; i++) { for (int j = x; j < x + w; j++) { RecastGraph.NavmeshTile navmeshTile = this.tiles[j + i * this.tileXCount]; if (navmeshTile != null) { this.RemoveConnectionsFromTile(navmeshTile); for (int k = 0; k < navmeshTile.nodes.Length; k++) { navmeshTile.nodes[k].Destroy(); } for (int l = navmeshTile.z; l < navmeshTile.z + navmeshTile.d; l++) { for (int m = navmeshTile.x; m < navmeshTile.x + navmeshTile.w; m++) { RecastGraph.NavmeshTile navmeshTile2 = this.tiles[m + l * this.tileXCount]; if (navmeshTile2 == null || navmeshTile2 != navmeshTile) { throw new Exception("This should not happen"); } if (l < z || l >= z + d || m < x || m >= x + w) { this.tiles[m + l * this.tileXCount] = RecastGraph.NewEmptyTile(m, l); if (this.batchTileUpdate) { this.batchUpdatedTiles.Add(m + l * this.tileXCount); } } else { this.tiles[m + l * this.tileXCount] = null; } } } } } } RecastGraph.NavmeshTile navmeshTile3 = new RecastGraph.NavmeshTile(); navmeshTile3.x = x; navmeshTile3.z = z; navmeshTile3.w = w; navmeshTile3.d = d; navmeshTile3.tris = tris; navmeshTile3.verts = verts; navmeshTile3.bbTree = new BBTree(); if (navmeshTile3.tris.Length % 3 != 0) { throw new ArgumentException("Triangle array's length must be a multiple of 3 (tris)"); } if (navmeshTile3.verts.Length > 65535) { throw new ArgumentException("Too many vertices per tile (more than 65535)"); } if (!worldSpace) { if (!Mathf.Approximately((float)(x * this.tileSizeX) * this.cellSize * 1000f, (float)Math.Round((double)((float)(x * this.tileSizeX) * this.cellSize * 1000f)))) { UnityEngine.Debug.LogWarning("Possible numerical imprecision. Consider adjusting tileSize and/or cellSize"); } if (!Mathf.Approximately((float)(z * this.tileSizeZ) * this.cellSize * 1000f, (float)Math.Round((double)((float)(z * this.tileSizeZ) * this.cellSize * 1000f)))) { UnityEngine.Debug.LogWarning("Possible numerical imprecision. Consider adjusting tileSize and/or cellSize"); } Int3 rhs = (Int3)(new Vector3((float)(x * this.tileSizeX) * this.cellSize, 0f, (float)(z * this.tileSizeZ) * this.cellSize) + this.forcedBounds.min); for (int n = 0; n < verts.Length; n++) { verts[n] += rhs; } } TriangleMeshNode[] array = new TriangleMeshNode[navmeshTile3.tris.Length / 3]; navmeshTile3.nodes = array; int graphIndex = AstarPath.active.astarData.graphs.Length; TriangleMeshNode.SetNavmeshHolder(graphIndex, navmeshTile3); int num = x + z * this.tileXCount; num <<= 12; for (int num2 = 0; num2 < array.Length; num2++) { TriangleMeshNode triangleMeshNode = new TriangleMeshNode(this.active); array[num2] = triangleMeshNode; triangleMeshNode.GraphIndex = (uint)graphIndex; triangleMeshNode.v0 = (navmeshTile3.tris[num2 * 3] | num); triangleMeshNode.v1 = (navmeshTile3.tris[num2 * 3 + 1] | num); triangleMeshNode.v2 = (navmeshTile3.tris[num2 * 3 + 2] | num); if (!Polygon.IsClockwise(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2))) { int v = triangleMeshNode.v0; triangleMeshNode.v0 = triangleMeshNode.v2; triangleMeshNode.v2 = v; } triangleMeshNode.Walkable = true; triangleMeshNode.Penalty = this.initialPenalty; triangleMeshNode.UpdatePositionFromVertices(); } navmeshTile3.bbTree.RebuildFrom(array); this.CreateNodeConnections(navmeshTile3.nodes); for (int num3 = z; num3 < z + d; num3++) { for (int num4 = x; num4 < x + w; num4++) { this.tiles[num4 + num3 * this.tileXCount] = navmeshTile3; } } if (this.batchTileUpdate) { this.batchUpdatedTiles.Add(x + z * this.tileXCount); } else { this.ConnectTileWithNeighbours(navmeshTile3); } TriangleMeshNode.SetNavmeshHolder(graphIndex, null); graphIndex = AstarPath.active.astarData.GetGraphIndex(this); for (int num5 = 0; num5 < array.Length; num5++) { array[num5].GraphIndex = (uint)graphIndex; } }
private RecastGraph.NavmeshTile CreateTile(Voxelize vox, VoxelMesh mesh, int x, int z) { if (mesh.tris == null) { throw new ArgumentNullException("mesh.tris"); } if (mesh.verts == null) { throw new ArgumentNullException("mesh.verts"); } RecastGraph.NavmeshTile navmeshTile = new RecastGraph.NavmeshTile(); navmeshTile.x = x; navmeshTile.z = z; navmeshTile.w = 1; navmeshTile.d = 1; navmeshTile.tris = mesh.tris; navmeshTile.verts = mesh.verts; navmeshTile.bbTree = new BBTree(); if (navmeshTile.tris.Length % 3 != 0) { throw new ArgumentException("Indices array's length must be a multiple of 3 (mesh.tris)"); } if (navmeshTile.verts.Length >= 4095) { throw new ArgumentException("Too many vertices per tile (more than " + 4095 + ").\nTry enabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* Inspector"); } Dictionary<Int3, int> dictionary = this.cachedInt3_int_dict; dictionary.Clear(); int[] array = new int[navmeshTile.verts.Length]; int num = 0; for (int i = 0; i < navmeshTile.verts.Length; i++) { if (!dictionary.ContainsKey(navmeshTile.verts[i])) { dictionary.Add(navmeshTile.verts[i], num); array[i] = num; navmeshTile.verts[num] = navmeshTile.verts[i]; num++; } else { array[i] = dictionary[navmeshTile.verts[i]]; } } for (int j = 0; j < navmeshTile.tris.Length; j++) { navmeshTile.tris[j] = array[navmeshTile.tris[j]]; } Int3[] array2 = new Int3[num]; for (int k = 0; k < num; k++) { array2[k] = navmeshTile.verts[k]; } navmeshTile.verts = array2; TriangleMeshNode[] array3 = new TriangleMeshNode[navmeshTile.tris.Length / 3]; navmeshTile.nodes = array3; int graphIndex = AstarPath.active.astarData.graphs.Length; TriangleMeshNode.SetNavmeshHolder(graphIndex, navmeshTile); int num2 = x + z * this.tileXCount; num2 <<= 12; for (int l = 0; l < array3.Length; l++) { TriangleMeshNode triangleMeshNode = new TriangleMeshNode(this.active); array3[l] = triangleMeshNode; triangleMeshNode.GraphIndex = (uint)graphIndex; triangleMeshNode.v0 = (navmeshTile.tris[l * 3] | num2); triangleMeshNode.v1 = (navmeshTile.tris[l * 3 + 1] | num2); triangleMeshNode.v2 = (navmeshTile.tris[l * 3 + 2] | num2); if (!Polygon.IsClockwise(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2))) { int v = triangleMeshNode.v0; triangleMeshNode.v0 = triangleMeshNode.v2; triangleMeshNode.v2 = v; } triangleMeshNode.Walkable = true; triangleMeshNode.Penalty = this.initialPenalty; triangleMeshNode.UpdatePositionFromVertices(); } navmeshTile.bbTree.RebuildFrom(array3); this.CreateNodeConnections(navmeshTile.nodes); TriangleMeshNode.SetNavmeshHolder(graphIndex, null); return navmeshTile; }