public override void GetNodes (GraphNodeDelegateCancelable del) {
			if (nodes == null) return;

			for (int i=0;i < nodes.Length;i++) {
				if (nodes[i] != null && !del(nodes[i])) break;
			}
		}
예제 #2
0
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (this.root != null)
     {
         this.root.GetNodes(del);
     }
 }
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (root == null)
     {
         return;
     }
     root.GetNodes(del);
 }
예제 #4
0
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (this.nodes != null)
     {
         for (int i = 0; (i < this.nodeCount) && del(this.nodes[i]); i++)
         {
         }
     }
 }
예제 #5
0
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (nodes == null)
     {
         return;
     }
     for (int i = 0; i < nodes.Length && del(nodes[i]); i++)
     {
     }
 }
예제 #6
0
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (nodes == null)
     {
         return;
     }
     for (var i = 0; i < nodeCount && del(nodes[i]); i++)
     {
     }
 }
예제 #7
0
//#endif

        /** Count nodes in the graph.
         * Note that this is, unless the graph type has overriden it, an O(n) operation.
         *
         * \todo GridGraph should override this
         */
        public virtual int CountNodes()
        {
            var count = 0;
            GraphNodeDelegateCancelable del = delegate(GraphNode node) {
                count++;
                return(true);
            };

            GetNodes(del);
            return(count);
        }
예제 #8
0
        /** Count nodes in the graph.
         * Note that this is, unless the graph type has overriden it, an O(n) operation.
         *
         * \todo GridGraph should override this
         */
        public virtual int CountNodes()
        {
            int count = 0;
            GraphNodeDelegateCancelable del = node => {
                count++;
                return(true);
            };

            GetNodes(del);
            return(count);
        }
예제 #9
0
 private void OnDrawGizmos()
 {
     if (this.isScanning)
     {
         return;
     }
     if (AstarPath.active == null)
     {
         AstarPath.active = this;
     }
     else if (AstarPath.active != this)
     {
         return;
     }
     if (this.graphs == null)
     {
         return;
     }
     if (this.workItems.workItemsInProgress)
     {
         return;
     }
     if (this.showNavGraphs && !this.manualDebugFloorRoof)
     {
         this.RecalculateDebugLimits();
     }
     for (int i = 0; i < this.graphs.Length; i++)
     {
         if (this.graphs[i] != null && this.graphs[i].drawGizmos)
         {
             this.graphs[i].OnDrawGizmos(this.showNavGraphs);
         }
     }
     if (this.showNavGraphs)
     {
         this.euclideanEmbedding.OnDrawGizmos();
         if (this.showUnwalkableNodes)
         {
             Gizmos.color = AstarColor.UnwalkableNode;
             GraphNodeDelegateCancelable del = new GraphNodeDelegateCancelable(this.DrawUnwalkableNode);
             for (int j = 0; j < this.graphs.Length; j++)
             {
                 if (this.graphs[j] != null && this.graphs[j].drawGizmos)
                 {
                     this.graphs[j].GetNodes(del);
                 }
             }
         }
     }
     if (this.OnDrawGizmosCallback != null)
     {
         this.OnDrawGizmosCallback();
     }
 }
예제 #10
0
        protected void GenerateTileFromInputMesh(AStarPathfindingWalkableArea walkArea)
        {
            if (null == walkArea)
            {
                EB.Debug.LogWarning("GenerateTileFromInputMesh: walkArea is empty");
                return;
            }

            Mesh inputMesh = walkArea.gameObject.GetComponent <MeshFilter>().sharedMesh;

            if (null == inputMesh)
            {
                EB.Debug.LogWarning("GenerateTileFromInputMesh: inputMesh is empty");
                return;
            }

            List <Vector3> allPoints = new List <Vector3>(inputMesh.vertices);
            Bounds         bounds    = GameUtils.CalculateBounds(allPoints);

            forcedBoundsCenter = walkArea.transform.TransformPoint(bounds.center);
            forcedBoundsSize   = bounds.size;

            // this section changes the size of the bounds and tile, so that we always get one single tile
            SetUpNavMeshToFitOnOneTile();
            CalculateNumberOfTiles(ref tileXCount, ref tileZCount);
            Debug.Assert(tileXCount == 1 && tileZCount == 1, "Their should be only one tile when using a prebuilt nav mesh");

            tiles = new NavmeshTile[tileXCount * tileZCount];             // only one tile

            // ignore this setting
            scanEmptyGraph = false;

            // the Vector3 vertices in the mesh need to be converted to the APP Int3 format
            Int3[] Int3Verts = new Int3[inputMesh.vertices.Length];
            for (int i = 0; i < Int3Verts.Length; ++i)
            {
                Vector3 tempVert = inputMesh.vertices[i];
                tempVert = walkArea.transform.TransformPoint(tempVert);                 // get the world space position, rather than local space

                Int3Verts[i] = (Int3)tempVert;
            }
            tiles[0] = CreateTile(inputMesh.triangles, Int3Verts, 0, 0);             // our single tile

            //Assign graph index to nodes
            uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex(this);
            GraphNodeDelegateCancelable del = delegate(GraphNode n)
            {
                n.GraphIndex = graphIndex;
                return(true);
            };

            GetNodes(del);
        }
예제 #11
0
 // Token: 0x06000549 RID: 1353 RVA: 0x0002E604 File Offset: 0x0002CA04
 public void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (this.node != null)
     {
         del(this.node);
         return;
     }
     this.c0.GetNodes(del);
     this.c1.GetNodes(del);
     this.c2.GetNodes(del);
     this.c3.GetNodes(del);
 }
예제 #12
0
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (this.nodes == null)
     {
         return;
     }
     int num = 0;
     while (num < this.nodes.Length && del(this.nodes[num]))
     {
         num++;
     }
 }
        public void GetNodes(GraphNodeDelegateCancelable del)
        {
            if (node != null)
            {
                del(node);
                return;
            }

            c0.GetNodes(del);
            c1.GetNodes(del);
            c2.GetNodes(del);
            c3.GetNodes(del);
        }
예제 #14
0
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (this.nodes == null)
     {
         return;
     }
     for (int i = 0; i < this.nodes.Length; i++)
     {
         if (this.nodes[i] != null && !del(this.nodes[i]))
         {
             break;
         }
     }
 }
예제 #15
0
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (nodes == null)
     {
         return;
     }
     for (int i = 0; i < nodes.GetLength(0); i++)
     {
         for (int j = 0; j < nodes.GetLength(1); j++)
         {
             // Call the delegate and check if it wants
             // more nodes or not
             if (!del(nodes[i, j]))
             {
                 // If it did not want more nodes
                 // then just return
                 return;
             }
         }
     }
 }
예제 #16
0
		public void GetNodes (GraphNodeDelegateCancelable del) {
			if (node != null) {
				del (node);
				return;
			}
			
			c0.GetNodes (del);
			c1.GetNodes (del);
			c2.GetNodes (del);
			c3.GetNodes (del);
		}
예제 #17
0
		public override void GetNodes (GraphNodeDelegateCancelable del) {
			if (nodes == null) return;
			for (int i=0;i<nodes.Length && del (nodes[i]);i++) {}
		}
예제 #18
0
 public override void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (this.tiles == null)
     {
         return;
     }
     for (int i = 0; i < this.tiles.Length; i++)
     {
         if (this.tiles[i] != null && this.tiles[i].x + this.tiles[i].z * this.tileXCount == i)
         {
             TriangleMeshNode[] nodes = this.tiles[i].nodes;
             if (nodes != null)
             {
                 int num = 0;
                 while (num < nodes.Length && del(nodes[num]))
                 {
                     num++;
                 }
             }
         }
     }
 }
예제 #19
0
        /** This performs a linear search through all polygons returning the closest one.
         * This will fill the NNInfo with .node for the closest node not necessarily complying with the NNConstraint, and .constrainedNode with the closest node
         * complying with the NNConstraint.
         * \see GetNearestForce(Node[],Int3[],Vector3,NNConstraint,bool)
         */
        public static NNInfo GetNearestForceBoth(NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode)
        {
            Int3 pos = (Int3)position;

            float     minDist = -1;
            GraphNode minNode = null;

            float     minConstDist = -1;
            GraphNode minConstNode = null;

            float maxDistSqr = constraint.constrainDistance ? AstarPath.active.maxNearestNodeDistanceSqr : float.PositiveInfinity;

            GraphNodeDelegateCancelable del = delegate(GraphNode _node) {
                TriangleMeshNode node = _node as TriangleMeshNode;

                if (accurateNearestNode)
                {
                    Vector3 closest = node.ClosestPointOnNode(position);
                    float   dist    = ((Vector3)pos - closest).sqrMagnitude;

                    if (minNode == null || dist < minDist)
                    {
                        minDist = dist;
                        minNode = node;
                    }

                    if (dist < maxDistSqr && constraint.Suitable(node))
                    {
                        if (minConstNode == null || dist < minConstDist)
                        {
                            minConstDist = dist;
                            minConstNode = node;
                        }
                    }
                }
                else
                {
                    if (!node.ContainsPoint((Int3)position))
                    {
                        float dist = (node.position - pos).sqrMagnitude;
                        if (minNode == null || dist < minDist)
                        {
                            minDist = dist;
                            minNode = node;
                        }

                        if (dist < maxDistSqr && constraint.Suitable(node))
                        {
                            if (minConstNode == null || dist < minConstDist)
                            {
                                minConstDist = dist;
                                minConstNode = node;
                            }
                        }
                    }
                    else
                    {
                        int dist = AstarMath.Abs(node.position.y - pos.y);

                        if (minNode == null || dist < minDist)
                        {
                            minDist = dist;
                            minNode = node;
                        }

                        if (dist < maxDistSqr && constraint.Suitable(node))
                        {
                            if (minConstNode == null || dist < minConstDist)
                            {
                                minConstDist = dist;
                                minConstNode = node;
                            }
                        }
                    }
                }
                return(true);
            };

            graph.GetNodes(del);

            NNInfo nninfo = new NNInfo(minNode);

            //Find the point closest to the nearest triangle

            if (nninfo.node != null)
            {
                TriangleMeshNode node = nninfo.node as TriangleMeshNode;                //minNode2 as MeshNode;

                Vector3 clP = node.ClosestPointOnNode(position);

                nninfo.clampedPosition = clP;
            }

            nninfo.constrainedNode = minConstNode;
            if (nninfo.constrainedNode != null)
            {
                TriangleMeshNode node = nninfo.constrainedNode as TriangleMeshNode;                //minNode2 as MeshNode;

                Vector3 clP = node.ClosestPointOnNode(position);

                nninfo.constClampedPosition = clP;
            }

            return(nninfo);
        }
예제 #20
0
        protected void ScanAllTiles(OnScanStatus statusCallback)
        {
#if ASTARDEBUG
            System.Console.WriteLine("Recast Graph -- Collecting Meshes");
#endif

#if BNICKSON_UPDATED
            editorTileSize = (int)(EditorVars.GridSize / cellSize);
#endif

            //----

            //Voxel grid size
            int gw = (int)(forcedBounds.size.x / cellSize + 0.5f);
            int gd = (int)(forcedBounds.size.z / cellSize + 0.5f);

            if (!useTiles)
            {
                tileSizeX = gw;
                tileSizeZ = gd;
            }
            else
            {
                tileSizeX = editorTileSize;
                tileSizeZ = editorTileSize;
            }

            //Number of tiles
            int tw = (gw + tileSizeX - 1) / tileSizeX;
            int td = (gd + tileSizeZ - 1) / tileSizeZ;

            tileXCount = tw;
            tileZCount = td;

            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];

#if ASTARDEBUG
            System.Console.WriteLine("Recast Graph -- Creating Voxel Base");
#endif

            // If this is true, just fill the graph with empty tiles
            if (scanEmptyGraph)
            {
                for (int z = 0; z < td; z++)
                {
                    for (int x = 0; x < tw; x++)
                    {
                        tiles[z * tileXCount + x] = NewEmptyTile(x, z);
                    }
                }
                return;
            }

            AstarProfiler.StartProfile("Finding Meshes");
            List <ExtraMesh> extraMeshes;

#if !NETFX_CORE || UNITY_EDITOR
            System.Console.WriteLine("Collecting Meshes");
#endif
            CollectMeshes(out extraMeshes, forcedBounds);

            AstarProfiler.EndProfile("Finding Meshes");

            // A walkableClimb higher than walkableHeight can cause issues when generating the navmesh since then it can in some cases
            // Both be valid for a character to walk under an obstacle and climb up on top of it (and that cannot be handled with navmesh without links)
            // The editor scripts also enforce this but we enforce it here too just to be sure
            walkableClimb = Mathf.Min(walkableClimb, walkableHeight);

            //Create the voxelizer and set all settings
            var vox = new Voxelize(cellHeight, cellSize, walkableClimb, walkableHeight, maxSlope);
            vox.inputExtraMeshes = extraMeshes;

            vox.maxEdgeLength = maxEdgeLength;

            int lastInfoCallback = -1;
            var watch            = System.Diagnostics.Stopwatch.StartNew();

            //Generate all tiles
            for (int z = 0; z < td; z++)
            {
                for (int x = 0; x < tw; x++)
                {
                    int tileNum = z * tileXCount + x;
#if !NETFX_CORE || UNITY_EDITOR
                    System.Console.WriteLine("Generating Tile #" + (tileNum) + " of " + td * tw);
#endif

                    //Call statusCallback only 10 times since it is very slow in the editor
                    if (statusCallback != null && (tileNum * 10 / tiles.Length > lastInfoCallback || watch.ElapsedMilliseconds > 2000))
                    {
                        lastInfoCallback = tileNum * 10 / tiles.Length;
                        watch.Reset();
                        watch.Start();

                        statusCallback(new Progress(Mathf.Lerp(0.1f, 0.9f, tileNum / (float)tiles.Length), "Building Tile " + tileNum + "/" + tiles.Length));
                    }

                    BuildTileMesh(vox, x, z);
                }
            }

#if !NETFX_CORE
            System.Console.WriteLine("Assigning Graph Indices");
#endif

            if (statusCallback != null)
            {
                statusCallback(new Progress(0.9f, "Connecting tiles"));
            }

            //Assign graph index to nodes
            uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex(this);

            GraphNodeDelegateCancelable del = delegate(GraphNode n) {
                n.GraphIndex = graphIndex;
                return(true);
            };
            GetNodes(del);

#if BNICKSON_UPDATED
#if DEBUG
            if (useCenterTileOnly && (3 != tileXCount || 3 != tileZCount))
            {
                EB.Debug.LogError("RecastGenerator.ScanAllTiles() : Incorrect amount of tiles generated if ceneter tile is all that is required");
            }
#endif

            int centerXTile = (tileXCount / 2);
            int centerZTile = (tileZCount / 2);
#endif

            for (int z = 0; z < td; z++)
            {
                for (int x = 0; x < tw; x++)
                {
#if BNICKSON_UPDATED
                    // if we're only using the center tile, and this is not the center tile
                    if (useCenterTileOnly && !(centerZTile == z && centerXTile == x))
                    {
                        continue;
                    }
#endif

#if !NETFX_CORE
                    System.Console.WriteLine("Connecing Tile #" + (z * tileXCount + x) + " of " + td * tw);
#endif
                    if (x < tw - 1)
                    {
                        ConnectTiles(tiles[x + z * tileXCount], tiles[x + 1 + z * tileXCount]);
                    }
                    if (z < td - 1)
                    {
                        ConnectTiles(tiles[x + z * tileXCount], tiles[x + (z + 1) * tileXCount]);
                    }
                }
            }

            AstarProfiler.PrintResults();
        }
예제 #21
0
        public static NNInfo GetNearestForceBoth(NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode)
        {
            Int3      pos                   = (Int3)position;
            float     minDist               = -1f;
            GraphNode minNode               = null;
            float     minConstDist          = -1f;
            GraphNode minConstNode          = null;
            float     maxDistSqr            = (!constraint.constrainDistance) ? float.PositiveInfinity : AstarPath.active.maxNearestNodeDistanceSqr;
            GraphNodeDelegateCancelable del = delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode3 = _node as TriangleMeshNode;
                if (accurateNearestNode)
                {
                    Vector3 b            = triangleMeshNode3.ClosestPointOnNode(position);
                    float   sqrMagnitude = ((Vector3)pos - b).sqrMagnitude;
                    if (minNode == null || sqrMagnitude < minDist)
                    {
                        minDist = sqrMagnitude;
                        minNode = triangleMeshNode3;
                    }
                    if (sqrMagnitude < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || sqrMagnitude < minConstDist))
                    {
                        minConstDist = sqrMagnitude;
                        minConstNode = triangleMeshNode3;
                    }
                }
                else if (!triangleMeshNode3.ContainsPoint((Int3)position))
                {
                    float sqrMagnitude2 = (triangleMeshNode3.position - pos).sqrMagnitude;
                    if (minNode == null || sqrMagnitude2 < minDist)
                    {
                        minDist = sqrMagnitude2;
                        minNode = triangleMeshNode3;
                    }
                    if (sqrMagnitude2 < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || sqrMagnitude2 < minConstDist))
                    {
                        minConstDist = sqrMagnitude2;
                        minConstNode = triangleMeshNode3;
                    }
                }
                else
                {
                    int num = AstarMath.Abs(triangleMeshNode3.position.y - pos.y);
                    if (minNode == null || (float)num < minDist)
                    {
                        minDist = (float)num;
                        minNode = triangleMeshNode3;
                    }
                    if ((float)num < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || (float)num < minConstDist))
                    {
                        minConstDist = (float)num;
                        minConstNode = triangleMeshNode3;
                    }
                }
                return(true);
            };

            graph.GetNodes(del);
            NNInfo result = new NNInfo(minNode);

            if (result.node != null)
            {
                TriangleMeshNode triangleMeshNode = result.node as TriangleMeshNode;
                Vector3          clampedPosition  = triangleMeshNode.ClosestPointOnNode(position);
                result.clampedPosition = clampedPosition;
            }
            result.constrainedNode = minConstNode;
            if (result.constrainedNode != null)
            {
                TriangleMeshNode triangleMeshNode2    = result.constrainedNode as TriangleMeshNode;
                Vector3          constClampedPosition = triangleMeshNode2.ClosestPointOnNode(position);
                result.constClampedPosition = constClampedPosition;
            }
            return(result);
        }
예제 #22
0
 public void GetNodes(GraphNodeDelegateCancelable del)
 {
     if (this.nodes == null)
     {
         return;
     }
     int num = 0;
     while (num < this.nodes.Length && del(this.nodes[num]))
     {
         num++;
     }
 }
예제 #23
0
파일: Base.cs 프로젝트: Marchys/fanalet
		/** Calls a delegate with all nodes in the graph.
		 * This is the primary way of "looping" through all nodes in a graph.
		 * 
		 * This function should not change anything in the graph structure.
		 */
		public abstract void GetNodes (GraphNodeDelegateCancelable del);
예제 #24
0
		public override void GetNodes (GraphNodeDelegateCancelable del) {
			/*if (nodes == null) return;
			for (int i=0;i<nodes.Length && del (nodes[i]);i++) {}*/
			if (tiles == null) return;
			//
			for (int i=0;i<tiles.Length;i++) {
				if (tiles[i] == null || tiles[i].x+tiles[i].z*tileXCount != i) continue;
				TriangleMeshNode[] nodes = tiles[i].nodes;
				
				if (nodes == null) continue;
				
				for (int j=0;j<nodes.Length && del (nodes[j]);j++) {}
			}
		}
        public void FloodFill()
        {
            if (astar.astarData.graphs == null)
            {
                return;
            }

            uint area = 0;

            lastUniqueAreaIndex = 0;

            if (floodStack == null)
            {
                floodStack = new Stack <GraphNode> (1024);
            }

            Stack <GraphNode> stack = floodStack;

            var graphs = astar.graphs;

            // Iterate through all nodes in all graphs
            // and reset their Area field
            for (int i = 0; i < graphs.Length; i++)
            {
                NavGraph graph = graphs[i];

                if (graph != null)
                {
                    graph.GetNodes(node => {
                        node.Area = 0;
                        return(true);
                    });
                }
            }

            int smallAreasDetected = 0;

            bool warnAboutAreas = false;

            List <GraphNode> smallAreaList = Pathfinding.Util.ListPool <GraphNode> .Claim();

            for (int i = 0; i < graphs.Length; i++)
            {
                NavGraph graph = graphs[i];

                if (graph == null)
                {
                    continue;
                }

                GraphNodeDelegateCancelable del = delegate(GraphNode node) {
                    if (node.Walkable && node.Area == 0)
                    {
                        area++;

                        uint thisArea = area;

                        if (area > GraphNode.MaxAreaIndex)
                        {
                            if (smallAreaList.Count > 0)
                            {
                                GraphNode smallOne = smallAreaList[smallAreaList.Count - 1];
                                thisArea = smallOne.Area;
                                smallAreaList.RemoveAt(smallAreaList.Count - 1);

                                //Flood fill the area again with area ID GraphNode.MaxAreaIndex-1, this identifies a small area
                                stack.Clear();

                                stack.Push(smallOne);
                                smallOne.Area = GraphNode.MaxAreaIndex;

                                while (stack.Count > 0)
                                {
                                    stack.Pop().FloodFill(stack, GraphNode.MaxAreaIndex);
                                }

                                smallAreasDetected++;
                            }
                            else
                            {
                                // Forced to consider this a small area
                                area--;
                                thisArea       = area;
                                warnAboutAreas = true;
                            }
                        }

                        stack.Clear();

                        stack.Push(node);

                        int counter = 1;

                        node.Area = thisArea;

                        while (stack.Count > 0)
                        {
                            counter++;
                            stack.Pop().FloodFill(stack, thisArea);
                        }

                        if (counter < astar.minAreaSize)
                        {
                            smallAreaList.Add(node);
                        }
                    }
                    return(true);
                };

                graph.GetNodes(del);
            }

            lastUniqueAreaIndex = area;

            if (warnAboutAreas)
            {
                Debug.LogError("Too many areas - The maximum number of areas is " + GraphNode.MaxAreaIndex + ". Try raising the A* Inspector -> Settings -> Min Area Size value. Enable the optimization ASTAR_MORE_AREAS under the Optimizations tab.");
            }

            if (smallAreasDetected > 0)
            {
                astar.Log(smallAreasDetected + " small areas were detected (fewer than " + astar.minAreaSize + " nodes)," +
                          "these might have the same IDs as other areas, but it shouldn't affect pathfinding in any significant way (you might get All Nodes Searched as a reason for path failure)." +
                          "\nWhich areas are defined as 'small' is controlled by the 'Min Area Size' variable, it can be changed in the A* inspector-->Settings-->Min Area Size" +
                          "\nThe small areas will use the area id " + GraphNode.MaxAreaIndex);
            }

            Pathfinding.Util.ListPool <GraphNode> .Release(smallAreaList);
        }
예제 #26
0
        // generate a nav mesh with one tile per zone
        protected void GenerateTilesForZones(AStarPathfindingWalkableArea[] walkAreas)
        {
            if (null == walkAreas || 0 == walkAreas.Length)
            {
                EB.Debug.LogWarning("GenerateTilesForZones: walkAreas is empty");
                return;
            }

            LevelHelper levelHelper = GameObject.FindObjectOfType(typeof(LevelHelper)) as LevelHelper;

            if (null == levelHelper)
            {
                EB.Debug.LogWarning("GenerateTilesForZones: LevelHelper not found");
                return;
            }

            Vector3 NavMeshBoundingBoxMin;
            Vector3 NavMeshBoundingBoxMax;

            levelHelper.CalculateAllZonesMinMax(out NavMeshBoundingBoxMin, out NavMeshBoundingBoxMax);

            // set the entire bounds and center of the recast graph
            forcedBoundsSize   = NavMeshBoundingBoxMax - NavMeshBoundingBoxMin;
            forcedBoundsCenter = NavMeshBoundingBoxMin + (forcedBoundsSize * 0.5f);

            tileSizeX = tileSizeZ = (int)(EditorVars.GridSize / cellSize);             // this line sets the tile size so that each tile will hold the size of a zone
            CalculateNumberOfTiles(ref tileXCount, ref tileZCount);

#if DEBUG
            int correctTilesXCount = (Mathf.CeilToInt(forcedBoundsSize.x / EditorVars.GridSize));             // this would fail if GridSize is less than 1f
            int correctTilesZCount = (Mathf.CeilToInt(forcedBoundsSize.z / EditorVars.GridSize));             // this would fail if GridSize is less than 1f
            if (correctTilesXCount != tileXCount || correctTilesZCount != tileZCount)
            {
                EB.Debug.LogError("Incorrect number of tiles generated");
            }
#endif
            tiles = new NavmeshTile[tileXCount * tileZCount];

            // ignore this setting
            scanEmptyGraph = false;

            Vector3 tempZoneMin = new Vector3();
            Vector3 tempZoneMax = new Vector3();

            // go over all the walkable areas and put there mesh into a tile
            foreach (AStarPathfindingWalkableArea walk in walkAreas)
            {
                ZoneDescriptor zoneDescriptor = (ZoneDescriptor)GameUtils.FindFirstComponentUpwards <ZoneDescriptor>(walk.transform);
                if (zoneDescriptor != null)
                {
                    ZoneDescriptor.CalculateZoneMinAndMax(ref tempZoneMin, ref tempZoneMax, zoneDescriptor.gameObject.transform);

                    // 1f is added to avoid floating point inacuracy (avoids 63.999/64 = 0, 64.99/64=1 which is correct)
                    int z = (int)(((tempZoneMin.z + 1f) - NavMeshBoundingBoxMin.z) / EditorVars.GridSize);
                    int x = (int)(((tempZoneMin.x + 1f) - NavMeshBoundingBoxMin.x) / EditorVars.GridSize);

                    MeshFilter meshFilter = walk.gameObject.GetComponent <MeshFilter>();
                    if (null != meshFilter.sharedMesh)
                    {
                        // the Vector3 vertices in the mesh need to be converted to the APP Int3 format
                        Int3[] Int3Verts = new Int3[meshFilter.sharedMesh.vertices.Length];
                        for (int i = 0; i < Int3Verts.Length; ++i)
                        {
                            Vector3 tempVert = new Vector3(meshFilter.sharedMesh.vertices[i].x, meshFilter.sharedMesh.vertices[i].y, meshFilter.sharedMesh.vertices[i].z);
                            tempVert = walk.transform.TransformPoint(tempVert);                             // get the world space position, rather than local space

                            // clamp the verts to the edges of the zone boundaries if they are close, this is so that the different tiles are linked together accurately
                            const float Tol = 0.01f;
                            tempVert.x = (tempVert.x <= tempZoneMin.x + Tol) ? tempZoneMin.x : tempVert.x;
                            tempVert.x = (tempVert.x >= tempZoneMax.x - Tol) ? tempZoneMax.x : tempVert.x;

                            tempVert.z = (tempVert.z <= tempZoneMin.z + Tol) ? tempZoneMin.z : tempVert.z;
                            tempVert.z = (tempVert.z >= tempZoneMax.z - Tol) ? tempZoneMax.z : tempVert.z;

                            Int3Verts[i] = (Int3)tempVert;
                        }
                        NavmeshTile tile = CreateTile(meshFilter.sharedMesh.triangles, Int3Verts, x, z);
                        tiles[Convert2DArrayCoordTo1DArrayCoord(x, z, tileXCount)] = tile;
                    }
                }
            }

            //Assign graph index to nodes
            uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex(this);
            GraphNodeDelegateCancelable del = delegate(GraphNode n)
            {
                n.GraphIndex = graphIndex;
                return(true);
            };
            GetNodes(del);

            // connect each tile to one and other
            for (int z = 0; z < tileZCount; z++)
            {
                for (int x = 0; x < tileXCount; x++)
                {
                    // make sure all the tiles which might be considered, have tiles created
                    CreateAndAddEmptyTileIfNonExists(x, z);
                    CreateAndAddEmptyTileIfNonExists(x + 1, z);
                    CreateAndAddEmptyTileIfNonExists(x, z + 1);

                    if (x < tileXCount - 1)
                    {
                        ConnectTiles(tiles[Convert2DArrayCoordTo1DArrayCoord(x, z, tileXCount)], tiles[Convert2DArrayCoordTo1DArrayCoord(x + 1, z, tileXCount)]);
                    }
                    if (z < tileZCount - 1)
                    {
                        ConnectTiles(tiles[Convert2DArrayCoordTo1DArrayCoord(x, z, tileXCount)], tiles[Convert2DArrayCoordTo1DArrayCoord(x, z + 1, tileXCount)]);
                    }
                }
            }
        }
예제 #27
0
 /** Calls a delegate with all nodes in the graph.
  * This is the primary way of "looping" through all nodes in a graph.
  *
  * This function should not change anything in the graph structure.
  */
 public abstract void GetNodes(GraphNodeDelegateCancelable del);
예제 #28
0
        public void FloodFill()
        {
                        #if ASTARDEBUG
            System.DateTime startTime = System.DateTime.UtcNow;
                        #endif

            var graphs = astar.graphs;

            if (graphs == null)
            {
                return;
            }

            // Iterate through all nodes in all graphs
            // and reset their Area field
            for (int i = 0; i < graphs.Length; i++)
            {
                var graph = graphs[i];

                if (graph != null)
                {
                    graph.GetNodes(node => {
                        node.Area = 0;
                        return(true);
                    });
                }
            }

            lastUniqueAreaIndex = 0;
            uint area             = 0;
            int  forcedSmallAreas = 0;

            // Get a temporary stack from a pool
            var stack = Pathfinding.Util.StackPool <GraphNode> .Claim();

            for (int i = 0; i < graphs.Length; i++)
            {
                NavGraph graph = graphs[i];

                if (graph == null)
                {
                    continue;
                }

                GraphNodeDelegateCancelable del = node => {
                    if (node.Walkable && node.Area == 0)
                    {
                        area++;

                        uint thisArea = area;

                        if (area > GraphNode.MaxAreaIndex)
                        {
                            // Forced to consider this a small area
                            area--;
                            thisArea = area;

                            // Make sure the first small area is also counted
                            if (forcedSmallAreas == 0)
                            {
                                forcedSmallAreas = 1;
                            }

                            forcedSmallAreas++;
                        }

                        stack.Clear();
                        stack.Push(node);

                        int counter = 1;
                        node.Area = thisArea;

                        while (stack.Count > 0)
                        {
                            counter++;
                            stack.Pop().FloodFill(stack, thisArea);
                        }
                    }
                    return(true);
                };

                graph.GetNodes(del);
            }

            lastUniqueAreaIndex = area;

            if (forcedSmallAreas > 0)
            {
                Debug.LogError(forcedSmallAreas + " areas had to share IDs. " +
                               "This usually doesn't affect pathfinding in any significant way (you might get 'Searched whole area but could not find target' as a reason for path failure) " +
                               "however some path requests may take longer to calculate (specifically those that fail with the 'Searched whole area' error)." +
                               "The maximum number of areas is " + GraphNode.MaxAreaIndex + ".");
            }

            // Put back into the pool
            Pathfinding.Util.StackPool <GraphNode> .Release(stack);

                        #if ASTARDEBUG
            Debug.Log("Flood fill complete, " + area + " area" + (area > 1 ? "s" : "") + " found - " + ((System.DateTime.UtcNow.Ticks - startTime.Ticks) * 0.0001).ToString("0.00") + " ms");
                        #endif
        }
예제 #29
0
        public void FloodFill()
        {
            NavGraph[] graphs = this.astar.graphs;
            if (graphs == null)
            {
                return;
            }
            foreach (NavGraph navGraph in graphs)
            {
                if (navGraph != null)
                {
                    navGraph.GetNodes(delegate(GraphNode node)
                    {
                        node.Area = 0u;
                        return(true);
                    });
                }
            }
            this.lastUniqueAreaIndex = 0u;
            uint area               = 0u;
            int  forcedSmallAreas   = 0;
            Stack <GraphNode> stack = StackPool <GraphNode> .Claim();

            foreach (NavGraph navGraph2 in graphs)
            {
                if (navGraph2 != null)
                {
                    GraphNodeDelegateCancelable del = delegate(GraphNode node)
                    {
                        if (node.Walkable && node.Area == 0u)
                        {
                            uint area;
                            area += 1u;
                            area  = area;
                            if (area > 131071u)
                            {
                                area -= 1u;
                                area  = area;
                                if (forcedSmallAreas == 0)
                                {
                                    forcedSmallAreas = 1;
                                }
                                forcedSmallAreas++;
                            }
                            stack.Clear();
                            stack.Push(node);
                            int num = 1;
                            node.Area = area;
                            while (stack.Count > 0)
                            {
                                num++;
                                stack.Pop().FloodFill(stack, area);
                            }
                        }
                        return(true);
                    };
                    navGraph2.GetNodes(del);
                }
            }
            this.lastUniqueAreaIndex = area;
            if (forcedSmallAreas > 0)
            {
                Debug.LogError(string.Concat(new object[]
                {
                    forcedSmallAreas,
                    " areas had to share IDs. This usually doesn't affect pathfinding in any significant way (you might get 'Searched whole area but could not find target' as a reason for path failure) however some path requests may take longer to calculate (specifically those that fail with the 'Searched whole area' error).The maximum number of areas is ",
                    131071u,
                    "."
                }));
            }
            StackPool <GraphNode> .Release(stack);
        }
예제 #30
0
		public override void GetNodes (GraphNodeDelegateCancelable del) {
			if (root == null) return;
			root.GetNodes (del);
		}