GetInRange() public method

Add all nodes within a squared distance of the point to the buffer.
public GetInRange ( Int3 point, long sqrRadius, List buffer ) : void
point Int3 Nodes around this point will be added to the buffer.
sqrRadius long squared maximum distance in Int3 space. If you are converting from world space you will need to multiply by Int3.Precision: /// var sqrRadius = (worldSpaceRadius * Int3.Precision) * (worldSpaceRadius * Int3.Precision);
buffer List All nodes will be added to this list.
return void
Ejemplo n.º 1
0
        /// <summary>
        /// Calculates connections for all nodes in the graph.
        /// This is an IEnumerable, you can iterate through it using e.g foreach to get progress information.
        /// </summary>
        IEnumerable <Progress> ConnectNodesAsync()
        {
            if (maxDistance >= 0)
            {
                // To avoid too many allocations, these lists are reused for each node
                var connections          = new List <Connection>();
                var candidateConnections = new List <GraphNode>();

                long maxSquaredRange;
                // Max possible squared length of a connection between two nodes
                // This is used to speed up the calculations by skipping a lot of nodes that do not need to be checked
                if (maxDistance == 0 && (limits.x == 0 || limits.y == 0 || limits.z == 0))
                {
                    maxSquaredRange = long.MaxValue;
                }
                else
                {
                    maxSquaredRange  = (long)(Mathf.Max(limits.x, Mathf.Max(limits.y, Mathf.Max(limits.z, maxDistance))) * Int3.Precision) + 1;
                    maxSquaredRange *= maxSquaredRange;
                }

                // Report progress every N nodes
                const int YieldEveryNNodes = 512;

                // Loop through all nodes and add connections to other nodes
                for (int i = 0; i < nodeCount; i++)
                {
                    if (i % YieldEveryNNodes == 0)
                    {
                        yield return(new Progress(i / (float)nodeCount, "Connecting nodes"));
                    }

                    connections.Clear();
                    var node = nodes[i];
                    if (optimizeForSparseGraph)
                    {
                        candidateConnections.Clear();
                        lookupTree.GetInRange(node.position, maxSquaredRange, candidateConnections);
                        for (int j = 0; j < candidateConnections.Count; j++)
                        {
                            var   other = candidateConnections[j] as PointNode;
                            float dist;
                            if (other != node && IsValidConnection(node, other, out dist))
                            {
                                connections.Add(new Connection(
                                                    other,
                                                    /// <summary>TODO: Is this equal to .costMagnitude</summary>
                                                    (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision)
                                                    ));
                            }
                        }
                    }
                    else
                    {
                        // Only brute force is available in the free version
                        for (int j = 0; j < nodeCount; j++)
                        {
                            if (i == j)
                            {
                                continue;
                            }

                            PointNode other = nodes[j];
                            float     dist;
                            if (IsValidConnection(node, other, out dist))
                            {
                                connections.Add(new Connection(
                                                    other,
                                                    /// <summary>TODO: Is this equal to .costMagnitude</summary>
                                                    (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision)
                                                    ));
                            }
                        }
                    }
                    node.connections = connections.ToArray();
                    node.SetConnectivityDirty();
                }
            }
        }
Ejemplo n.º 2
0
        public override IEnumerable <Progress> ScanInternal()
        {
            yield return(new Progress(0, "Searching for GameObjects"));

            if (root == null)
            {
                //If there is no root object, try to find nodes with the specified tag instead
                GameObject[] gos = searchTag != null?GameObject.FindGameObjectsWithTag(searchTag) : null;

                if (gos == null)
                {
                    nodes     = new PointNode[0];
                    nodeCount = 0;
                    yield break;
                }

                yield return(new Progress(0.1f, "Creating nodes"));

                //Create and set up the found nodes
                nodes     = new PointNode[gos.Length];
                nodeCount = nodes.Length;

                for (int i = 0; i < nodes.Length; i++)
                {
                    nodes[i] = new PointNode(active);
                }

                for (int i = 0; i < gos.Length; i++)
                {
                    nodes[i].SetPosition((Int3)gos[i].transform.position);
                    nodes[i].Walkable   = true;
                    nodes[i].gameObject = gos[i].gameObject;
                }
            }
            else
            {
                //Search the root for children and create nodes for them
                if (!recursive)
                {
                    nodes     = new PointNode[root.childCount];
                    nodeCount = nodes.Length;

                    for (int i = 0; i < nodes.Length; i++)
                    {
                        nodes[i] = new PointNode(active);
                    }

                    int c = 0;
                    foreach (Transform child in root)
                    {
                        nodes[c].SetPosition((Int3)child.position);
                        nodes[c].Walkable   = true;
                        nodes[c].gameObject = child.gameObject;

                        c++;
                    }
                }
                else
                {
                    nodes     = new PointNode[CountChildren(root)];
                    nodeCount = nodes.Length;

                    for (int i = 0; i < nodes.Length; i++)
                    {
                        nodes[i] = new PointNode(active);
                    }

                    int startID = 0;
                    AddChildren(ref startID, root);
                }
            }

            if (optimizeForSparseGraph)
            {
                yield return(new Progress(0.15f, "Building node lookup"));

                RebuildNodeLookup();
            }

            if (maxDistance >= 0)
            {
                // To avoid too many allocations, these lists are reused for each node
                var connections          = new List <PointNode>();
                var costs                = new List <uint>();
                var candidateConnections = new List <GraphNode>();

                // Max possible squared length of a connection between two nodes
                // This is used to speed up the calculations by skipping a lot of nodes that do not need to be checked
                long maxPossibleSqrRange;
                if (maxDistance == 0 && (limits.x == 0 || limits.y == 0 || limits.z == 0))
                {
                    maxPossibleSqrRange = long.MaxValue;
                }
                else
                {
                    maxPossibleSqrRange  = (long)(Mathf.Max(limits.x, Mathf.Max(limits.y, Mathf.Max(limits.z, maxDistance))) * Int3.Precision) + 1;
                    maxPossibleSqrRange *= maxPossibleSqrRange;
                }

                // Report progress every N nodes
                const int YieldEveryNNodes = 512;

                // Loop through all nodes and add connections to other nodes
                for (int i = 0; i < nodes.Length; i++)
                {
                    if (i % YieldEveryNNodes == 0)
                    {
                        yield return(new Progress(Mathf.Lerp(0.15f, 1, i / (float)nodes.Length), "Connecting nodes"));
                    }

                    connections.Clear();
                    costs.Clear();

                    PointNode node = nodes[i];
                    if (optimizeForSparseGraph)
                    {
                        candidateConnections.Clear();
                        lookupTree.GetInRange(node.position, maxPossibleSqrRange, candidateConnections);
                        System.Console.WriteLine(i + " " + candidateConnections.Count);
                        for (int j = 0; j < candidateConnections.Count; j++)
                        {
                            var   other = candidateConnections[j] as PointNode;
                            float dist;
                            if (other != node && IsValidConnection(node, other, out dist))
                            {
                                connections.Add(other);
                                /** \todo Is this equal to .costMagnitude */
                                costs.Add((uint)Mathf.RoundToInt(dist * Int3.FloatPrecision));
                            }
                        }
                    }
                    else
                    {
                        // Only brute force is available in the free version
                        for (int j = 0; j < nodes.Length; j++)
                        {
                            if (i == j)
                            {
                                continue;
                            }

                            PointNode other = nodes[j];
                            float     dist;
                            if (IsValidConnection(node, other, out dist))
                            {
                                connections.Add(other);
                                /** \todo Is this equal to .costMagnitude */
                                costs.Add((uint)Mathf.RoundToInt(dist * Int3.FloatPrecision));
                            }
                        }
                    }
                    node.connections     = connections.ToArray();
                    node.connectionCosts = costs.ToArray();
                }
            }
        }