12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001 |
- using Math = System.Math;
- using UnityEngine;
- using System.Collections.Generic;
- using UnityEngine.Profiling;
- namespace Pathfinding {
- using Pathfinding.Voxels;
- using Pathfinding.Serialization;
- using Pathfinding.Recast;
- using Pathfinding.Util;
- using System.Threading;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [JsonOptIn]
- [Pathfinding.Util.Preserve]
- public class RecastGraph : NavmeshBase, IUpdatableGraph {
- [JsonMember]
-
-
-
-
-
- public float characterRadius = 1.5F;
-
-
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public float contourMaxError = 2F;
-
-
-
-
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public float cellSize = 0.5F;
-
-
-
-
- [JsonMember]
- public float walkableHeight = 2F;
-
-
-
-
- [JsonMember]
- public float walkableClimb = 0.5F;
-
-
-
-
- [JsonMember]
- public float maxSlope = 30;
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public float maxEdgeLength = 20;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public float minRegionSize = 3;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public int editorTileSize = 128;
-
-
-
-
-
-
-
-
- [JsonMember]
- public int tileSizeX = 128;
-
-
-
-
-
-
-
-
- [JsonMember]
- public int tileSizeZ = 128;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public bool useTiles = true;
-
-
-
-
- public bool scanEmptyGraph;
- public enum RelevantGraphSurfaceMode {
-
- DoNotRequire,
-
-
-
-
- OnlyForCompletelyInsideTile,
-
-
-
-
-
- RequireForAll
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public RelevantGraphSurfaceMode relevantGraphSurfaceMode = RelevantGraphSurfaceMode.DoNotRequire;
- [JsonMember]
-
- public bool rasterizeColliders;
- [JsonMember]
-
- public bool rasterizeMeshes = true;
-
- [JsonMember]
- public bool rasterizeTerrain = true;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public bool rasterizeTrees = true;
-
-
-
-
-
-
-
-
-
-
-
- [JsonMember]
- public float colliderRasterizeDetail = 10;
-
-
-
-
- [JsonMember]
- public LayerMask mask = -1;
-
-
-
-
-
-
- [JsonMember]
- public List<string> tagMask = new List<string>();
-
-
-
-
- [JsonMember]
- public int terrainSampleSize = 3;
-
- [JsonMember]
- public Vector3 rotation;
-
-
-
-
- [JsonMember]
- public Vector3 forcedBoundsCenter;
- private Voxelize globalVox;
- public const int BorderVertexMask = 1;
- public const int BorderVertexOffset = 31;
-
-
-
-
-
-
-
- List<NavmeshTile> stagingTiles = new List<NavmeshTile>();
- protected override bool RecalculateNormals { get { return true; } }
- public override float TileWorldSizeX {
- get {
- return tileSizeX*cellSize;
- }
- }
- public override float TileWorldSizeZ {
- get {
- return tileSizeZ*cellSize;
- }
- }
- protected override float MaxTileConnectionEdgeDistance {
- get {
- return walkableClimb;
- }
- }
-
-
-
-
-
- [System.Obsolete("Obsolete since this is not accurate when the graph is rotated (rotation was not supported when this property was created)")]
- public Bounds forcedBounds {
- get {
- return new Bounds(forcedBoundsCenter, forcedBoundsSize);
- }
- }
-
-
-
-
- [System.Obsolete("Use node.ClosestPointOnNode instead")]
- public Vector3 ClosestPointOnNode (TriangleMeshNode node, Vector3 pos) {
- return node.ClosestPointOnNode(pos);
- }
-
-
-
-
- [System.Obsolete("Use node.ContainsPoint instead")]
- public bool ContainsPoint (TriangleMeshNode node, Vector3 pos) {
- return node.ContainsPoint((Int3)pos);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public void SnapForceBoundsToScene () {
- var meshes = CollectMeshes(new Bounds(Vector3.zero, new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity)));
- if (meshes.Count == 0) {
- return;
- }
- var bounds = meshes[0].bounds;
- for (int i = 1; i < meshes.Count; i++) {
- bounds.Encapsulate(meshes[i].bounds);
- meshes[i].Pool();
- }
- forcedBoundsCenter = bounds.center;
- forcedBoundsSize = bounds.size;
- }
- GraphUpdateThreading IUpdatableGraph.CanUpdateAsync (GraphUpdateObject o) {
- return o.updatePhysics ? GraphUpdateThreading.UnityInit | GraphUpdateThreading.SeparateThread | GraphUpdateThreading.UnityPost : GraphUpdateThreading.SeparateThread;
- }
- void IUpdatableGraph.UpdateAreaInit (GraphUpdateObject o) {
- if (!o.updatePhysics) {
- return;
- }
- AstarProfiler.Reset();
- AstarProfiler.StartProfile("UpdateAreaInit");
- AstarProfiler.StartProfile("CollectMeshes");
- RelevantGraphSurface.UpdateAllPositions();
-
-
-
- IntRect touchingTiles = GetTouchingTiles(o.bounds, TileBorderSizeInWorldUnits);
- Bounds tileBounds = GetTileBounds(touchingTiles);
-
- tileBounds.Expand(new Vector3(1, 0, 1)*TileBorderSizeInWorldUnits*2);
- var meshes = CollectMeshes(tileBounds);
- if (globalVox == null) {
-
- globalVox = new Voxelize(CellHeight, cellSize, walkableClimb, walkableHeight, maxSlope, maxEdgeLength);
- }
- globalVox.inputMeshes = meshes;
- AstarProfiler.EndProfile("CollectMeshes");
- AstarProfiler.EndProfile("UpdateAreaInit");
- }
- void IUpdatableGraph.UpdateArea (GraphUpdateObject guo) {
-
-
-
- var affectedTiles = GetTouchingTiles(guo.bounds, TileBorderSizeInWorldUnits);
- if (!guo.updatePhysics) {
- for (int z = affectedTiles.ymin; z <= affectedTiles.ymax; z++) {
- for (int x = affectedTiles.xmin; x <= affectedTiles.xmax; x++) {
- NavmeshTile tile = tiles[z*tileXCount + x];
- NavMeshGraph.UpdateArea(guo, tile);
- }
- }
- return;
- }
- Voxelize vox = globalVox;
- if (vox == null) {
- throw new System.InvalidOperationException("No Voxelizer object. UpdateAreaInit should have been called before this function.");
- }
- AstarProfiler.StartProfile("Build Tiles");
-
- for (int x = affectedTiles.xmin; x <= affectedTiles.xmax; x++) {
- for (int z = affectedTiles.ymin; z <= affectedTiles.ymax; z++) {
- stagingTiles.Add(BuildTileMesh(vox, x, z));
- }
- }
- uint graphIndex = (uint)AstarPath.active.data.GetGraphIndex(this);
-
- for (int i = 0; i < stagingTiles.Count; i++) {
- NavmeshTile tile = stagingTiles[i];
- GraphNode[] nodes = tile.nodes;
- for (int j = 0; j < nodes.Length; j++) nodes[j].GraphIndex = graphIndex;
- }
- for (int i = 0; i < vox.inputMeshes.Count; i++) vox.inputMeshes[i].Pool();
- ListPool<RasterizationMesh>.Release(ref vox.inputMeshes);
- AstarProfiler.EndProfile("Build Tiles");
- }
-
- void IUpdatableGraph.UpdateAreaPost (GraphUpdateObject guo) {
- Profiler.BeginSample("RemoveConnections");
-
-
- for (int i = 0; i < stagingTiles.Count; i++) {
- var tile = stagingTiles[i];
- int index = tile.x + tile.z * tileXCount;
- var oldTile = tiles[index];
-
- for (int j = 0; j < oldTile.nodes.Length; j++) {
- oldTile.nodes[j].Destroy();
- }
- tiles[index] = tile;
- }
- Profiler.EndSample();
- Profiler.BeginSample("Connect With Neighbours");
-
- for (int i = 0; i < stagingTiles.Count; i++) {
- var tile = stagingTiles[i];
- ConnectTileWithNeighbours(tile, false);
- }
-
-
-
-
-
- var updatedTiles = stagingTiles.ToArray();
- navmeshUpdateData.OnRecalculatedTiles(updatedTiles);
- if (OnRecalculatedTiles != null) OnRecalculatedTiles(updatedTiles);
- stagingTiles.Clear();
- Profiler.EndSample();
- }
- protected override IEnumerable<Progress> ScanInternal () {
- TriangleMeshNode.SetNavmeshHolder(AstarPath.active.data.GetGraphIndex(this), this);
- if (!Application.isPlaying) {
- RelevantGraphSurface.FindAllGraphSurfaces();
- }
- RelevantGraphSurface.UpdateAllPositions();
- foreach (var progress in ScanAllTiles()) {
- yield return progress;
- }
- }
- public override GraphTransform CalculateTransform () {
- return new GraphTransform(Matrix4x4.TRS(forcedBoundsCenter, Quaternion.Euler(rotation), Vector3.one) * Matrix4x4.TRS(-forcedBoundsSize*0.5f, Quaternion.identity, Vector3.one));
- }
- void InitializeTileInfo () {
-
- int totalVoxelWidth = (int)(forcedBoundsSize.x/cellSize + 0.5f);
- int totalVoxelDepth = (int)(forcedBoundsSize.z/cellSize + 0.5f);
- if (!useTiles) {
- tileSizeX = totalVoxelWidth;
- tileSizeZ = totalVoxelDepth;
- } else {
- tileSizeX = editorTileSize;
- tileSizeZ = editorTileSize;
- }
-
- tileXCount = (totalVoxelWidth + tileSizeX-1) / tileSizeX;
- tileZCount = (totalVoxelDepth + tileSizeZ-1) / tileSizeZ;
- if (tileXCount * tileZCount > TileIndexMask+1) {
- throw new System.Exception("Too many tiles ("+(tileXCount * tileZCount)+") maximum is "+(TileIndexMask+1)+
- "\nTry disabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* inspector.");
- }
- tiles = new NavmeshTile[tileXCount*tileZCount];
- }
-
- List<RasterizationMesh>[] PutMeshesIntoTileBuckets (List<RasterizationMesh> meshes) {
- var result = new List<RasterizationMesh>[tiles.Length];
- var borderExpansion = new Vector3(1, 0, 1)*TileBorderSizeInWorldUnits*2;
- for (int i = 0; i < result.Length; i++) {
- result[i] = ListPool<RasterizationMesh>.Claim();
- }
- for (int i = 0; i < meshes.Count; i++) {
- var mesh = meshes[i];
- var bounds = mesh.bounds;
-
- bounds.Expand(borderExpansion);
- var rect = GetTouchingTiles(bounds);
- for (int z = rect.ymin; z <= rect.ymax; z++) {
- for (int x = rect.xmin; x <= rect.xmax; x++) {
- result[x + z*tileXCount].Add(mesh);
- }
- }
- }
- return result;
- }
- protected IEnumerable<Progress> ScanAllTiles () {
- transform = CalculateTransform();
- InitializeTileInfo();
-
- if (scanEmptyGraph) {
- FillWithEmptyTiles();
- yield break;
- }
-
-
-
- walkableClimb = Mathf.Min(walkableClimb, walkableHeight);
- yield return new Progress(0, "Finding Meshes");
- var bounds = transform.Transform(new Bounds(forcedBoundsSize*0.5f, forcedBoundsSize));
- var meshes = CollectMeshes(bounds);
- var buckets = PutMeshesIntoTileBuckets(meshes);
- Queue<Int2> tileQueue = new Queue<Int2>();
-
- for (int z = 0; z < tileZCount; z++) {
- for (int x = 0; x < tileXCount; x++) {
- tileQueue.Enqueue(new Int2(x, z));
- }
- }
- var workQueue = new ParallelWorkQueue<Int2>(tileQueue);
-
- var voxelizers = new Voxelize[workQueue.threadCount];
- for (int i = 0; i < voxelizers.Length; i++) voxelizers[i] = new Voxelize(CellHeight, cellSize, walkableClimb, walkableHeight, maxSlope, maxEdgeLength);
- workQueue.action = (tile, threadIndex) => {
- voxelizers[threadIndex].inputMeshes = buckets[tile.x + tile.y*tileXCount];
- tiles[tile.x + tile.y*tileXCount] = BuildTileMesh(voxelizers[threadIndex], tile.x, tile.y, threadIndex);
- };
-
-
-
- int timeoutMillis = Application.isPlaying ? 1 : 200;
-
- foreach (var done in workQueue.Run(timeoutMillis)) {
- yield return new Progress(Mathf.Lerp(0.1f, 0.9f, done / (float)tiles.Length), "Calculated Tiles: " + done + "/" + tiles.Length);
- }
- yield return new Progress(0.9f, "Assigning Graph Indices");
-
- uint graphIndex = (uint)AstarPath.active.data.GetGraphIndex(this);
- GetNodes(node => node.GraphIndex = graphIndex);
-
-
-
-
-
-
-
-
- for (int coordinateSum = 0; coordinateSum <= 1; coordinateSum++) {
- for (int direction = 0; direction <= 1; direction++) {
- for (int i = 0; i < tiles.Length; i++) {
- if ((tiles[i].x + tiles[i].z) % 2 == coordinateSum) {
- tileQueue.Enqueue(new Int2(tiles[i].x, tiles[i].z));
- }
- }
- workQueue = new ParallelWorkQueue<Int2>(tileQueue);
- workQueue.action = (tile, threadIndex) => {
-
- if (direction == 0 && tile.x < tileXCount - 1)
- ConnectTiles(tiles[tile.x + tile.y * tileXCount], tiles[tile.x + 1 + tile.y * tileXCount]);
- if (direction == 1 && tile.y < tileZCount - 1)
- ConnectTiles(tiles[tile.x + tile.y * tileXCount], tiles[tile.x + (tile.y + 1) * tileXCount]);
- };
- var numTilesInQueue = tileQueue.Count;
-
- foreach (var done in workQueue.Run(timeoutMillis)) {
- yield return new Progress(0.95f, "Connected Tiles " + (numTilesInQueue - done) + "/" + numTilesInQueue + " (Phase " + (direction + 1 + 2*coordinateSum) + " of 4)");
- }
- }
- }
- for (int i = 0; i < meshes.Count; i++) meshes[i].Pool();
- ListPool<RasterizationMesh>.Release(ref meshes);
-
- navmeshUpdateData.OnRecalculatedTiles(tiles);
- if (OnRecalculatedTiles != null) OnRecalculatedTiles(tiles.Clone() as NavmeshTile[]);
- }
- List<RasterizationMesh> CollectMeshes (Bounds bounds) {
- Profiler.BeginSample("Find Meshes for rasterization");
- var result = ListPool<RasterizationMesh>.Claim();
- var meshGatherer = new RecastMeshGatherer(bounds, terrainSampleSize, mask, tagMask, colliderRasterizeDetail);
- if (rasterizeMeshes) {
- Profiler.BeginSample("Find meshes");
- meshGatherer.CollectSceneMeshes(result);
- Profiler.EndSample();
- }
- Profiler.BeginSample("Find RecastMeshObj components");
- meshGatherer.CollectRecastMeshObjs(result);
- Profiler.EndSample();
- if (rasterizeTerrain) {
- Profiler.BeginSample("Find terrains");
-
- var desiredTerrainChunkSize = cellSize*Math.Max(tileSizeX, tileSizeZ);
- meshGatherer.CollectTerrainMeshes(rasterizeTrees, desiredTerrainChunkSize, result);
- Profiler.EndSample();
- }
- if (rasterizeColliders) {
- Profiler.BeginSample("Find colliders");
- meshGatherer.CollectColliderMeshes(result);
- Profiler.EndSample();
- }
- if (result.Count == 0) {
- Debug.LogWarning("No MeshFilters were found contained in the layers specified by the 'mask' variables");
- }
- Profiler.EndSample();
- return result;
- }
- float CellHeight {
- get {
-
-
- return Mathf.Max(forcedBoundsSize.y / 64000, 0.001f);
- }
- }
-
- int CharacterRadiusInVoxels {
- get {
-
-
- return Mathf.CeilToInt((characterRadius / cellSize) - 0.1f);
- }
- }
-
-
-
-
- int TileBorderSizeInVoxels {
- get {
- return CharacterRadiusInVoxels + 3;
- }
- }
- float TileBorderSizeInWorldUnits {
- get {
- return TileBorderSizeInVoxels*cellSize;
- }
- }
- Bounds CalculateTileBoundsWithBorder (int x, int z) {
- var bounds = new Bounds();
- bounds.SetMinMax(new Vector3(x*TileWorldSizeX, 0, z*TileWorldSizeZ),
- new Vector3((x+1)*TileWorldSizeX, forcedBoundsSize.y, (z+1)*TileWorldSizeZ)
- );
-
- bounds.Expand(new Vector3(1, 0, 1)*TileBorderSizeInWorldUnits*2);
- return bounds;
- }
- protected NavmeshTile BuildTileMesh (Voxelize vox, int x, int z, int threadIndex = 0) {
- AstarProfiler.StartProfile("Build Tile");
- AstarProfiler.StartProfile("Init");
- vox.borderSize = TileBorderSizeInVoxels;
- vox.forcedBounds = CalculateTileBoundsWithBorder(x, z);
- vox.width = tileSizeX + vox.borderSize*2;
- vox.depth = tileSizeZ + vox.borderSize*2;
- if (!useTiles && relevantGraphSurfaceMode == RelevantGraphSurfaceMode.OnlyForCompletelyInsideTile) {
-
- vox.relevantGraphSurfaceMode = RelevantGraphSurfaceMode.RequireForAll;
- } else {
- vox.relevantGraphSurfaceMode = relevantGraphSurfaceMode;
- }
- vox.minRegionSize = Mathf.RoundToInt(minRegionSize / (cellSize*cellSize));
- AstarProfiler.EndProfile("Init");
-
- vox.Init();
- vox.VoxelizeInput(transform, CalculateTileBoundsWithBorder(x, z));
- AstarProfiler.StartProfile("Filter Ledges");
- vox.FilterLedges(vox.voxelWalkableHeight, vox.voxelWalkableClimb, vox.cellSize, vox.cellHeight);
- AstarProfiler.EndProfile("Filter Ledges");
- AstarProfiler.StartProfile("Filter Low Height Spans");
- vox.FilterLowHeightSpans(vox.voxelWalkableHeight, vox.cellSize, vox.cellHeight);
- AstarProfiler.EndProfile("Filter Low Height Spans");
- vox.BuildCompactField();
- vox.BuildVoxelConnections();
- vox.ErodeWalkableArea(CharacterRadiusInVoxels);
- vox.BuildDistanceField();
- vox.BuildRegions();
- var cset = new VoxelContourSet();
- vox.BuildContours(contourMaxError, 1, cset, Voxelize.RC_CONTOUR_TESS_WALL_EDGES | Voxelize.RC_CONTOUR_TESS_TILE_EDGES);
- VoxelMesh mesh;
- vox.BuildPolyMesh(cset, 3, out mesh);
- AstarProfiler.StartProfile("Build Nodes");
-
- for (int i = 0; i < mesh.verts.Length; i++) {
- mesh.verts[i] *= Int3.Precision;
- }
- vox.transformVoxel2Graph.Transform(mesh.verts);
- NavmeshTile tile = CreateTile(vox, mesh, x, z, threadIndex);
- AstarProfiler.EndProfile("Build Nodes");
- AstarProfiler.EndProfile("Build Tile");
- return tile;
- }
-
-
-
-
- NavmeshTile CreateTile (Voxelize vox, VoxelMesh mesh, int x, int z, int threadIndex) {
- if (mesh.tris == null) throw new System.ArgumentNullException("mesh.tris");
- if (mesh.verts == null) throw new System.ArgumentNullException("mesh.verts");
- if (mesh.tris.Length % 3 != 0) throw new System.ArgumentException("Indices array's length must be a multiple of 3 (mesh.tris)");
- if (mesh.verts.Length >= VertexIndexMask) {
- if (tileXCount*tileZCount == 1) {
- throw new System.ArgumentException("Too many vertices per tile (more than " + VertexIndexMask + ")." +
- "\n<b>Try enabling tiling in the recast graph settings.</b>\n");
- } else {
- throw new System.ArgumentException("Too many vertices per tile (more than " + VertexIndexMask + ")." +
- "\n<b>Try reducing tile size or enabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* Inspector</b>");
- }
- }
-
- var tile = new NavmeshTile {
- x = x,
- z = z,
- w = 1,
- d = 1,
- tris = mesh.tris,
- bbTree = new BBTree(),
- graph = this,
- };
- tile.vertsInGraphSpace = Utility.RemoveDuplicateVertices(mesh.verts, tile.tris);
- tile.verts = (Int3[])tile.vertsInGraphSpace.Clone();
- transform.Transform(tile.verts);
-
-
-
-
-
-
- uint temporaryGraphIndex = (uint)(active.data.graphs.Length + threadIndex);
- if (temporaryGraphIndex > GraphNode.MaxGraphIndex) {
-
- throw new System.Exception("Graph limit reached. Multithreaded recast calculations cannot be done because a few scratch graph indices are required.");
- }
- TriangleMeshNode.SetNavmeshHolder((int)temporaryGraphIndex, tile);
-
-
- tile.nodes = new TriangleMeshNode[tile.tris.Length/3];
- lock (active) {
- CreateNodes(tile.nodes, tile.tris, x + z*tileXCount, temporaryGraphIndex);
- }
- tile.bbTree.RebuildFrom(tile.nodes);
- CreateNodeConnections(tile.nodes);
-
- TriangleMeshNode.SetNavmeshHolder((int)temporaryGraphIndex, null);
- return tile;
- }
- protected override void DeserializeSettingsCompatibility (GraphSerializationContext ctx) {
- base.DeserializeSettingsCompatibility(ctx);
- characterRadius = ctx.reader.ReadSingle();
- contourMaxError = ctx.reader.ReadSingle();
- cellSize = ctx.reader.ReadSingle();
- ctx.reader.ReadSingle();
- walkableHeight = ctx.reader.ReadSingle();
- maxSlope = ctx.reader.ReadSingle();
- maxEdgeLength = ctx.reader.ReadSingle();
- editorTileSize = ctx.reader.ReadInt32();
- tileSizeX = ctx.reader.ReadInt32();
- nearestSearchOnlyXZ = ctx.reader.ReadBoolean();
- useTiles = ctx.reader.ReadBoolean();
- relevantGraphSurfaceMode = (RelevantGraphSurfaceMode)ctx.reader.ReadInt32();
- rasterizeColliders = ctx.reader.ReadBoolean();
- rasterizeMeshes = ctx.reader.ReadBoolean();
- rasterizeTerrain = ctx.reader.ReadBoolean();
- rasterizeTrees = ctx.reader.ReadBoolean();
- colliderRasterizeDetail = ctx.reader.ReadSingle();
- forcedBoundsCenter = ctx.DeserializeVector3();
- forcedBoundsSize = ctx.DeserializeVector3();
- mask = ctx.reader.ReadInt32();
- int count = ctx.reader.ReadInt32();
- tagMask = new List<string>(count);
- for (int i = 0; i < count; i++) {
- tagMask.Add(ctx.reader.ReadString());
- }
- showMeshOutline = ctx.reader.ReadBoolean();
- showNodeConnections = ctx.reader.ReadBoolean();
- terrainSampleSize = ctx.reader.ReadInt32();
-
-
-
- walkableClimb = ctx.DeserializeFloat(walkableClimb);
- minRegionSize = ctx.DeserializeFloat(minRegionSize);
-
- tileSizeZ = ctx.DeserializeInt(tileSizeX);
- showMeshSurface = ctx.reader.ReadBoolean();
- }
- }
- }
|