Inheritance: GraphNode
        /** Add a node with the specified type to the graph at the specified position.
         *
         * \param node This must be a node created using T(AstarPath.active) right before the call to this method.
         * The node parameter is only there because there is no new(AstarPath) constraint on
         * generic type parameters.
         * \param position The node will be set to this position.
         * \note Vector3 can be casted to Int3 using (Int3)myVector.
         *
         * \note This needs to be called when it is safe to update nodes, which is
         * - when scanning
         * - during a graph update
         * - inside a callback registered using AstarPath.RegisterSafeUpdate
         *
         * \see AstarPath.RegisterSafeUpdate
         */
        public T AddNode <T>(T node, Int3 position) where T : PointNode
        {
            if (nodes == null || nodeCount == nodes.Length)
            {
                var newNodes = new PointNode[nodes != null ? System.Math.Max(nodes.Length + 4, nodes.Length * 2) : 4];
                if (nodes != null)
                {
                    nodes.CopyTo(newNodes, 0);
                }
                nodes = newNodes;
            }

            node.SetPosition(position);
            node.GraphIndex = graphIndex;
            node.Walkable   = true;

            nodes[nodeCount] = node;
            nodeCount++;

            AddToLookup(node);

            return(node);
        }
Exemplo n.º 2
0
        public override void DeserializeExtraInfo(GraphSerializationContext ctx)
        {
            int count = ctx.reader.ReadInt32();

            if (count == -1)
            {
                nodes = null;
                return;
            }

            nodes     = new PointNode[count];
            nodeCount = count;

            for (int i = 0; i < nodes.Length; i++)
            {
                if (ctx.reader.ReadInt32() == -1)
                {
                    continue;
                }
                nodes[i] = new PointNode(active);
                nodes[i].DeserializeNode(ctx);
            }
        }
Exemplo n.º 3
0
        /** Add a node with the specified type to the graph at the specified position.
         *
         * \param node This must be a node created using T(AstarPath.active) right before the call to this method.
         * The node parameter is only there because there is no new(AstarPath) constraint on
         * generic type parameters.
         * \param position The node will be set to this position.
         * \note Vector3 can be casted to Int3 using (Int3)myVector.
         *
         * \note This needs to be called when it is safe to update nodes, which is
         * - when scanning
         * - during a graph update
         * - inside a callback registered using AstarPath.RegisterSafeUpdate
         *
         * \see AstarPath.RegisterSafeUpdate
         */
        public T AddNode <T>(T node, Int3 position) where T : PointNode
        {
            if (nodes == null || nodeCount == nodes.Length)
            {
                var nds = new PointNode[nodes != null ? System.Math.Max(nodes.Length + 4, nodes.Length * 2) : 4];
                for (int i = 0; i < nodeCount; i++)
                {
                    nds[i] = nodes[i];
                }
                nodes = nds;
            }

            node.SetPosition(position);
            node.GraphIndex = graphIndex;
            node.Walkable   = true;

            nodes[nodeCount] = node;
            nodeCount++;

            AddToLookup(node);

            return(node);
        }
Exemplo n.º 4
0
        /** Add a node with the specified type to the graph at the specified position.
         * \note Vector3 can be casted to Int3 using (Int3)myVector.
         *
         * \param nd This must be a node created using T(AstarPath.active) right before the call to this method.
         * The node parameter is only there because there is no new(AstarPath) constraint on
         * generic type parameters.
         */
        public T AddNode <T> (T nd, Int3 position) where T : PointNode
        {
            if (nodes == null || nodeCount == nodes.Length)
            {
                var nds = new PointNode[nodes != null ? Math.Max(nodes.Length + 4, nodes.Length * 2) : 4];
                for (var i = 0; i < nodeCount; i++)
                {
                    nds[i] = nodes[i];
                }
                nodes = nds;
            }
            //T nd = new T( active );//new PointNode ( active );
            nd.SetPosition(position);
            nd.GraphIndex = graphIndex;
            nd.Walkable   = true;

            nodes[nodeCount] = nd;
            nodeCount++;

            AddToLookup(nd);

            return(nd);
        }
Exemplo n.º 5
0
        public void InternalOnPostScan()
        {
            if (this.EndTransform == null || this.StartTransform == null)
            {
                return;
            }
            if (AstarPath.active.astarData.pointGraph == null)
            {
                AstarPath.active.astarData.AddGraph(new PointGraph());
            }
            NodeLink2 x;

            if (this.startNode != null && NodeLink2.reference.TryGetValue(this.startNode, out x) && x == this)
            {
                NodeLink2.reference.Remove(this.startNode);
            }
            NodeLink2 x2;

            if (this.endNode != null && NodeLink2.reference.TryGetValue(this.endNode, out x2) && x2 == this)
            {
                NodeLink2.reference.Remove(this.endNode);
            }
            this.startNode      = AstarPath.active.astarData.pointGraph.AddNode((Int3)this.StartTransform.position);
            this.endNode        = AstarPath.active.astarData.pointGraph.AddNode((Int3)this.EndTransform.position);
            this.connectedNode1 = null;
            this.connectedNode2 = null;
            if (this.startNode == null || this.endNode == null)
            {
                this.startNode = null;
                this.endNode   = null;
                return;
            }
            this.postScanCalled = true;
            NodeLink2.reference[this.startNode] = this;
            NodeLink2.reference[this.endNode]   = this;
            this.Apply(true);
        }
        // Token: 0x060025B4 RID: 9652 RVA: 0x001A1470 File Offset: 0x0019F670
        private NNInfoInternal GetNearestInternal(Vector3 position, NNConstraint constraint, bool fastCheck)
        {
            if (this.nodes == null)
            {
                return(default(NNInfoInternal));
            }
            if (this.optimizeForSparseGraph)
            {
                return(new NNInfoInternal(this.lookupTree.GetNearest((Int3)position, fastCheck ? null : constraint)));
            }
            float          num            = (constraint == null || constraint.constrainDistance) ? AstarPath.active.maxNearestNodeDistanceSqr : float.PositiveInfinity;
            NNInfoInternal nninfoInternal = new NNInfoInternal(null);
            float          num2           = float.PositiveInfinity;
            float          num3           = float.PositiveInfinity;

            for (int i = 0; i < this.nodeCount; i++)
            {
                PointNode pointNode    = this.nodes[i];
                float     sqrMagnitude = (position - (Vector3)pointNode.position).sqrMagnitude;
                if (sqrMagnitude < num2)
                {
                    num2 = sqrMagnitude;
                    nninfoInternal.node = pointNode;
                }
                if (sqrMagnitude < num3 && sqrMagnitude < num && (constraint == null || constraint.Suitable(pointNode)))
                {
                    num3 = sqrMagnitude;
                    nninfoInternal.constrainedNode = pointNode;
                }
            }
            if (!fastCheck)
            {
                nninfoInternal.node = nninfoInternal.constrainedNode;
            }
            nninfoInternal.UpdateInfo();
            return(nninfoInternal);
        }
        // Token: 0x060025B6 RID: 9654 RVA: 0x001A1584 File Offset: 0x0019F784
        public T AddNode <T>(T node, Int3 position) where T : PointNode
        {
            if (this.nodes == null || this.nodeCount == this.nodes.Length)
            {
                PointNode[] array = new PointNode[(this.nodes != null) ? Math.Max(this.nodes.Length + 4, this.nodes.Length * 2) : 4];
                if (this.nodes != null)
                {
                    this.nodes.CopyTo(array, 0);
                }
                this.nodes = array;
            }
            node.SetPosition(position);
            node.GraphIndex            = this.graphIndex;
            node.Walkable              = true;
            this.nodes[this.nodeCount] = node;
            int nodeCount = this.nodeCount;

            this.nodeCount = nodeCount + 1;
            if (this.optimizeForSparseGraph)
            {
                this.AddToLookup(node);
            }
            return(node);
        }
Exemplo n.º 8
0
        /** Rebuilds the lookup structure for nodes.
         *
         * This is used when #optimizeForSparseGraph is enabled.
         *
         * You should call this method every time you move a node in the graph manually and
         * you are using #optimizeForSparseGraph, otherwise pathfinding might not work correctly.
         *
         * \astarpro
         */
        public void RebuildNodeLookup()
        {
            if (!optimizeForSparseGraph)
            {
                return;
            }

            if (maxDistance == 0)
            {
                lookupCellSize = (Int3)limits;
            }
            else
            {
                lookupCellSize.x = Mathf.CeilToInt(Int3.Precision * (limits.x != 0 ? Mathf.Min(maxDistance, limits.x) : maxDistance));
                lookupCellSize.y = Mathf.CeilToInt(Int3.Precision * (limits.y != 0 ? Mathf.Min(maxDistance, limits.y) : maxDistance));
                lookupCellSize.z = Mathf.CeilToInt(Int3.Precision * (limits.z != 0 ? Mathf.Min(maxDistance, limits.z) : maxDistance));
            }

            if (optimizeFor2D)
            {
                lookupCellSize.y = 0;
            }

            if (nodeLookup == null)
            {
                nodeLookup = new Dictionary <Int3, PointNode>();
            }

            nodeLookup.Clear();

            for (int i = 0; i < nodeCount; i++)
            {
                PointNode node = nodes[i];
                AddToLookup(node);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Updates an area in the list graph.
        /// Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the guo will be recalculated
        /// </summary>
        void IUpdatableGraph.UpdateArea(GraphUpdateObject guo)
        {
            if (nodes == null)
            {
                return;
            }

            for (int i = 0; i < nodeCount; i++)
            {
                var node = nodes[i];
                if (guo.bounds.Contains((Vector3)node.position))
                {
                    guo.WillUpdateNode(node);
                    guo.Apply(node);
                }
            }

            if (guo.updatePhysics)
            {
                // Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates
                Bounds bounds = guo.bounds;

                if (thickRaycast)
                {
                    // Expand the bounding box to account for the thick raycast
                    bounds.Expand(thickRaycastRadius * 2);
                }

                // Create a temporary list used for holding connection data
                List <Connection> tmpList = Pathfinding.Util.ListPool <Connection> .Claim();

                for (int i = 0; i < nodeCount; i++)
                {
                    PointNode node    = nodes[i];
                    var       nodePos = (Vector3)node.position;

                    List <Connection> conn = null;

                    for (int j = 0; j < nodeCount; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }

                        var otherNodePos = (Vector3)nodes[j].position;
                        // Check if this connection intersects the bounding box.
                        // If it does we need to recalculate that connection.
                        if (VectorMath.SegmentIntersectsBounds(bounds, nodePos, otherNodePos))
                        {
                            float     dist;
                            PointNode other           = nodes[j];
                            bool      contains        = node.ContainsConnection(other);
                            bool      validConnection = IsValidConnection(node, other, out dist);

                            // Fill the 'conn' list when we need to change a connection
                            if (conn == null && (contains != validConnection))
                            {
                                tmpList.Clear();
                                conn = tmpList;
                                conn.AddRange(node.connections);
                            }

                            if (!contains && validConnection)
                            {
                                // A new connection should be added
                                uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision);
                                conn.Add(new Connection(other, cost));
                                RegisterConnectionLength((other.position - node.position).sqrMagnitudeLong);
                            }
                            else if (contains && !validConnection)
                            {
                                // A connection should be removed
                                for (int q = 0; q < conn.Count; q++)
                                {
                                    if (conn[q].node == other)
                                    {
                                        conn.RemoveAt(q);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    // Save the new connections if any were changed
                    if (conn != null)
                    {
                        node.connections = conn.ToArray();
                        node.SetConnectivityDirty();
                    }
                }

                // Release buffers back to the pool
                Pathfinding.Util.ListPool <Connection> .Release(ref tmpList);
            }
        }
Exemplo n.º 10
0
 void AddToLookup(PointNode node)
 {
     lookupTree.Add(node);
 }
Exemplo n.º 11
0
        /** Updates an area in the list graph.
         * Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the \a guo will be recalculated
         * \astarpro */
        public void UpdateArea(GraphUpdateObject guo)
        {
            if (nodes == null)
            {
                return;
            }

            for (int i = 0; i < nodeCount; i++)
            {
                if (guo.bounds.Contains((Vector3)nodes[i].position))
                {
                    guo.WillUpdateNode(nodes[i]);
                    guo.Apply(nodes[i]);
                }
            }

            if (guo.updatePhysics)
            {
                //Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates
                Bounds bounds = guo.bounds;

                if (thickRaycast)
                {
                    //Expand the bounding box to account for the thick raycast
                    bounds.Expand(thickRaycastRadius * 2);
                }

                //Create two temporary arrays used for holding new connections and costs
                List <GraphNode> tmp_arr = Pathfinding.Util.ListPool <GraphNode> .Claim();

                List <uint> tmp_arr2 = Pathfinding.Util.ListPool <uint> .Claim();

                for (int i = 0; i < nodeCount; i++)
                {
                    PointNode node = nodes[i];
                    var       a    = (Vector3)node.position;

                    List <GraphNode> conn  = null;
                    List <uint>      costs = null;

                    for (int j = 0; j < nodeCount; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }

                        var b = (Vector3)nodes[j].position;
                        if (VectorMath.SegmentIntersectsBounds(bounds, a, b))
                        {
                            float     dist;
                            PointNode other           = nodes[j];
                            bool      contains        = node.ContainsConnection(other);
                            bool      validConnection = IsValidConnection(node, other, out dist);

                            if (!contains && validConnection)
                            {
                                // A new connection should be added

                                if (conn == null)
                                {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear();
                                    conn  = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange(node.connections);
                                    costs.AddRange(node.connectionCosts);
                                }

                                uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision);
                                conn.Add(other);
                                costs.Add(cost);
                            }
                            else if (contains && !validConnection)
                            {
                                // A connection should be removed

                                if (conn == null)
                                {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear();
                                    conn  = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange(node.connections);
                                    costs.AddRange(node.connectionCosts);
                                }

                                int p = conn.IndexOf(other);

                                //Shouldn't have to check for it, but who knows what might go wrong
                                if (p != -1)
                                {
                                    conn.RemoveAt(p);
                                    costs.RemoveAt(p);
                                }
                            }
                        }
                    }

                    // Save the new connections if any were changed
                    if (conn != null)
                    {
                        node.connections     = conn.ToArray();
                        node.connectionCosts = costs.ToArray();
                    }
                }

                // Release buffers back to the pool
                Pathfinding.Util.ListPool <GraphNode> .Release(tmp_arr);

                Pathfinding.Util.ListPool <uint> .Release(tmp_arr2);
            }
        }
Exemplo n.º 12
0
        public override void ScanInternal(OnScanStatus statusCallback)
        {
            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;
                    return;
                }

                //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);
                    }
                    //CreateNodes (CountChildren (root));

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


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

                //Loop through all nodes and add connections to other nodes
                for (int i = 0; i < nodes.Length; i++)
                {
                    connections.Clear();
                    costs.Clear();

                    PointNode node = nodes[i];

                    // 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();
                }
            }
        }
Exemplo n.º 13
0
		public void InternalOnPostScan () {

			if ( EndTransform == null || StartTransform == null ) return;

#if !ASTAR_NO_POINT_GRAPH
			if ( AstarPath.active.astarData.pointGraph == null ) {
				AstarPath.active.astarData.AddGraph ( new PointGraph () );
			}
#endif


			if ( startNode != null) {
				NodeLink2 tmp;
				if (reference.TryGetValue (startNode, out tmp) && tmp == this) reference.Remove (startNode);
			}
	
			if ( endNode != null) {
				NodeLink2 tmp;
				if (reference.TryGetValue (endNode, out tmp) && tmp == this) reference.Remove (endNode);
			}
	
#if !ASTAR_NO_POINT_GRAPH	
			//Get nearest nodes from the first point graph, assuming both start and end transforms are nodes
			startNode = AstarPath.active.astarData.pointGraph.AddNode ( (Int3)StartTransform.position );//AstarPath.active.astarData.pointGraph.GetNearest(StartTransform.position).node as PointNode;
			endNode = AstarPath.active.astarData.pointGraph.AddNode ( (Int3)EndTransform.position ); //AstarPath.active.astarData.pointGraph.GetNearest(EndTransform.position).node as PointNode;
#else
			throw new System.Exception ("Point graph is not included. Check your A* optimization settings.");
#endif

			connectedNode1 = null;
			connectedNode2 = null;
			
			if (startNode == null || endNode == null) {
				startNode = null;
				endNode = null;
				return;
			}
			
			postScanCalled = true;
			reference[startNode] = this;
			reference[endNode] = this;
			Apply( true );
		}
Exemplo n.º 14
0
 // Token: 0x06000526 RID: 1318 RVA: 0x0002CF88 File Offset: 0x0002B388
 public override void ScanInternal(OnScanStatus statusCallback)
 {
     if (this.root == null)
     {
         GameObject[] array = GameObject.FindGameObjectsWithTag(this.searchTag);
         if (array == null)
         {
             this.nodes     = new PointNode[0];
             this.nodeCount = 0;
             return;
         }
         this.nodes     = new PointNode[array.Length];
         this.nodeCount = this.nodes.Length;
         for (int i = 0; i < this.nodes.Length; i++)
         {
             this.nodes[i] = new PointNode(this.active);
         }
         for (int j = 0; j < array.Length; j++)
         {
             this.nodes[j].SetPosition((Int3)array[j].transform.position);
             this.nodes[j].Walkable   = true;
             this.nodes[j].gameObject = array[j].gameObject;
         }
     }
     else if (!this.recursive)
     {
         this.nodes     = new PointNode[this.root.childCount];
         this.nodeCount = this.nodes.Length;
         for (int k = 0; k < this.nodes.Length; k++)
         {
             this.nodes[k] = new PointNode(this.active);
         }
         int         num        = 0;
         IEnumerator enumerator = this.root.GetEnumerator();
         try
         {
             while (enumerator.MoveNext())
             {
                 object    obj       = enumerator.Current;
                 Transform transform = (Transform)obj;
                 this.nodes[num].SetPosition((Int3)transform.position);
                 this.nodes[num].Walkable   = true;
                 this.nodes[num].gameObject = transform.gameObject;
                 num++;
             }
         }
         finally
         {
             IDisposable disposable;
             if ((disposable = (enumerator as IDisposable)) != null)
             {
                 disposable.Dispose();
             }
         }
     }
     else
     {
         this.nodes     = new PointNode[PointGraph.CountChildren(this.root)];
         this.nodeCount = this.nodes.Length;
         for (int l = 0; l < this.nodes.Length; l++)
         {
             this.nodes[l] = new PointNode(this.active);
         }
         int num2 = 0;
         this.AddChildren(ref num2, this.root);
     }
     if (this.optimizeForSparseGraph)
     {
         this.RebuildNodeLookup();
     }
     if (this.maxDistance >= 0f)
     {
         List <PointNode> list  = new List <PointNode>(3);
         List <uint>      list2 = new List <uint>(3);
         for (int m = 0; m < this.nodes.Length; m++)
         {
             list.Clear();
             list2.Clear();
             PointNode pointNode = this.nodes[m];
             if (this.optimizeForSparseGraph)
             {
                 Int3 lhs  = this.WorldToLookupSpace(pointNode.position);
                 int  num3 = (this.lookupCellSize.y != 0) ? PointGraph.ThreeDNeighbours.Length : 9;
                 for (int n = 0; n < num3; n++)
                 {
                     Int3      key = lhs + PointGraph.ThreeDNeighbours[n];
                     PointNode next;
                     if (this.nodeLookup.TryGetValue(key, out next))
                     {
                         while (next != null)
                         {
                             float num4 = 0f;
                             if (this.IsValidConnection(pointNode, next, out num4))
                             {
                                 list.Add(next);
                                 list2.Add((uint)Mathf.RoundToInt(num4 * 1000f));
                             }
                             next = next.next;
                         }
                     }
                 }
             }
             else
             {
                 for (int num5 = 0; num5 < this.nodes.Length; num5++)
                 {
                     if (m != num5)
                     {
                         PointNode pointNode2 = this.nodes[num5];
                         float     num6       = 0f;
                         if (this.IsValidConnection(pointNode, pointNode2, out num6))
                         {
                             list.Add(pointNode2);
                             list2.Add((uint)Mathf.RoundToInt(num6 * 1000f));
                         }
                     }
                 }
             }
             pointNode.connections     = list.ToArray();
             pointNode.connectionCosts = list2.ToArray();
         }
     }
 }
Exemplo n.º 15
0
 private void PopulateNodes(IList<Vector3> waypoints, int tag, bool isWalkable, ref int nextNodeIndex) {
     int lastNodeIndex = nextNodeIndex + waypoints.Count;
     for (int index = nextNodeIndex; index < lastNodeIndex; index++) {
         PointNode node = new PointNode(active);
         node.SetPosition((Int3)waypoints[index - nextNodeIndex]);
         node.Walkable = isWalkable;
         node.Tag = (uint)tag;
         nodes[index] = node;
     }
     nextNodeIndex = lastNodeIndex;
 }
        /** Updates an area in the list graph.
         * Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the \a guo will be recalculated
         * \astarpro */
        public void UpdateArea(GraphUpdateObject guo)
        {
            if (nodes == null)
            {
                return;
            }

            for (int i = 0; i < nodeCount; i++)
            {
                if (guo.bounds.Contains((Vector3)nodes[i].position))
                {
                    guo.WillUpdateNode(nodes[i]);
                    guo.Apply(nodes[i]);
                }
            }

            if (guo.updatePhysics)
            {
                //Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates
                Bounds bounds = guo.bounds;

                if (thickRaycast)
                {
                    //Expand the bounding box to account for the thick raycast
                    bounds.Expand(thickRaycastRadius * 2);
                }

                //Create two temporary arrays used for holding new connections and costs
                List <GraphNode> tmp_arr = Pathfinding.Util.ListPool <GraphNode> .Claim();

                List <uint> tmp_arr2 = Pathfinding.Util.ListPool <uint> .Claim();

                for (int i = 0; i < nodeCount; i++)
                {
                    PointNode node = nodes[i] as PointNode;
                    Vector3   a    = (Vector3)node.position;

                    List <GraphNode> conn  = null;
                    List <uint>      costs = null;

                    for (int j = 0; j < nodeCount; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }

                        Vector3 b = (Vector3)nodes[j].position;
                        if (Polygon.LineIntersectsBounds(bounds, a, b))
                        {
                            float     dist;
                            PointNode other    = nodes[j] as PointNode;
                            bool      contains = node.ContainsConnection(other);

                            //Note, the IsValidConnection test will actually only be done once
                            //no matter what,so there is no performance penalty there
                            if (!contains && IsValidConnection(node, other, out dist))
                            {
                                //Debug.DrawLine (a+Vector3.up*0.1F,b+Vector3.up*0.1F,Color.green);
                                if (conn == null)
                                {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear();
                                    conn  = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange(node.connections);
                                    costs.AddRange(node.connectionCosts);
                                }

                                uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision);
                                conn.Add(other);
                                costs.Add(cost);
                            }
                            else if (contains && !IsValidConnection(node, other, out dist))
                            {
                                //Debug.DrawLine (a+Vector3.up*0.5F*Random.value,b+Vector3.up*0.5F*Random.value,Color.red);
                                if (conn == null)
                                {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear();
                                    conn  = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange(node.connections);
                                    costs.AddRange(node.connectionCosts);
                                }

                                int p = conn.IndexOf(other);

                                //Shouldn't have to check for it, but who knows what might go wrong
                                if (p != -1)
                                {
                                    conn.RemoveAt(p);
                                    costs.RemoveAt(p);
                                }
                            }
                        }
                    }

                    if (conn != null)
                    {
                        node.connections     = conn.ToArray();
                        node.connectionCosts = costs.ToArray();
                    }
                }

                Pathfinding.Util.ListPool <GraphNode> .Release(tmp_arr);

                Pathfinding.Util.ListPool <uint> .Release(tmp_arr2);
            }
        }
        public override void ScanInternal(OnScanStatus statusCallback)
        {
            if (root == null)
            {
                //If there is no root object, try to find nodes with the specified tag instead
                GameObject[] gos = GameObject.FindGameObjectsWithTag(searchTag);
                nodeGameObjects = gos;

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

                //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);
                }

                //CreateNodes (gos.Length);
                for (int i = 0; i < gos.Length; i++)
                {
                    (nodes[i] as PointNode).SetPosition((Int3)gos[i].transform.position);
                    nodes[i].Walkable = true;

#if !AstarRelease && FALSE
                    NodeObject nobj = gos[i].GetComponent <NodeObject>();
                    if (nobj != null)
                    {
                        nodes[i].Walkable = nobj.walkable;
                    }
#endif
                }
            }
            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);
                    }

                    nodeGameObjects = new GameObject[nodes.Length];

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

                        nodeGameObjects[c] = child.gameObject;

#if !AstarRelease && FALSE
                        NodeObject nobj = child.GetComponent <NodeObject>();
                        if (nobj != null)
                        {
                            nodes[c].Walkable = nobj.walkable;
                        }
#endif

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

                    for (int i = 0; i < nodes.Length; i++)
                    {
                        nodes[i] = new PointNode(active);
                    }
                    //CreateNodes (CountChildren (root));
                    nodeGameObjects = new GameObject[nodes.Length];

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

            if (optimizeForSparseGraph)
            {
                RebuildNodeLookup();
            }

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

                //Loop through all nodes and add connections to other nodes
                for (int i = 0; i < nodes.Length; i++)
                {
                    connections.Clear();
                    costs.Clear();

                    PointNode node = nodes[i];


                    if (optimizeForSparseGraph)
                    {
                        Int3 p = WorldToLookupSpace(node.position);

                        int l = lookupCellSize.y == 0 ? 9 : ThreeDNeighbours.Length;

                        for (int j = 0; j < l; j++)
                        {
                            Int3 np = p + ThreeDNeighbours[j];

                            PointNode other;
                            if (nodeLookup.TryGetValue(np, out other))
                            {
                                while (other != null)
                                {
                                    float dist = 0;
                                    if (IsValidConnection(node, other, out dist))
                                    {
                                        connections.Add(other);
                                        /** \todo Is this equal to .costMagnitude */
                                        costs.Add((uint)Mathf.RoundToInt(dist * Int3.FloatPrecision));
                                    }

                                    other = other.next;
                                }
                            }
                        }
                    }
                    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 = 0;
                            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();
                }
            }

            //GC can clear this up now.
            nodeGameObjects = null;
        }
Exemplo n.º 18
0
        public override NNInfoInternal GetNearestForce(Vector3 position, NNConstraint constraint)
        {
            if (this.nodes == null)
            {
                return(new NNInfoInternal());
            }
            float     num = !constraint.constrainDistance ? float.PositiveInfinity : AstarPath.active.maxNearestNodeDistanceSqr;
            float     positiveInfinity = float.PositiveInfinity;
            GraphNode node             = null;
            float     num3             = float.PositiveInfinity;
            GraphNode node2            = null;

            if (this.optimizeForSparseGraph)
            {
                PointNode next;
                Int3      key          = this.WorldToLookupSpace((Int3)position);
                Int3      num5         = key - this.minLookup;
                int       num6         = 0;
                int       introduced48 = Math.Max(num6, Math.Abs(num5.x));
                int       introduced49 = Math.Max(introduced48, Math.Abs(num5.y));
                num6 = Math.Max(introduced49, Math.Abs(num5.z));
                num5 = key - this.maxLookup;
                int introduced50 = Math.Max(num6, Math.Abs(num5.x));
                int introduced51 = Math.Max(introduced50, Math.Abs(num5.y));
                num6 = Math.Max(introduced51, Math.Abs(num5.z));
                if (this.nodeLookup.TryGetValue(key, out next))
                {
                    while (next != null)
                    {
                        Vector3 vector       = position - ((Vector3)next.position);
                        float   sqrMagnitude = vector.sqrMagnitude;
                        if (sqrMagnitude < positiveInfinity)
                        {
                            positiveInfinity = sqrMagnitude;
                            node             = next;
                        }
                        if ((constraint == null) || (((sqrMagnitude < num3) && (sqrMagnitude < num)) && constraint.Suitable(next)))
                        {
                            num3  = sqrMagnitude;
                            node2 = next;
                        }
                        next = next.next;
                    }
                }
                for (int i = 1; i <= num6; i++)
                {
                    if (i >= 20)
                    {
                        UnityEngine.Debug.LogWarning("Aborting GetNearest call at maximum distance because it has iterated too many times.\nIf you get this regularly, check your settings for PointGraph -> <b>Optimize For Sparse Graph</b> and PointGraph -> <b>Optimize For 2D</b>.\nThis happens when the closest node was very far away (20*link distance between nodes). When optimizing for sparse graphs, getting the nearest node from far away positions is <b>very slow</b>.\n");
                        break;
                    }
                    if (this.lookupCellSize.y == 0)
                    {
                        Int3 num9 = key + new Int3(-i, 0, -i);
                        for (int j = 0; j <= (2 * i); j++)
                        {
                            if (this.nodeLookup.TryGetValue(num9 + new Int3(j, 0, 0), out next))
                            {
                                while (next != null)
                                {
                                    Vector3 vector2 = position - ((Vector3)next.position);
                                    float   num11   = vector2.sqrMagnitude;
                                    if (num11 < positiveInfinity)
                                    {
                                        positiveInfinity = num11;
                                        node             = next;
                                    }
                                    if ((constraint == null) || (((num11 < num3) && (num11 < num)) && constraint.Suitable(next)))
                                    {
                                        num3  = num11;
                                        node2 = next;
                                    }
                                    next = next.next;
                                }
                            }
                            if (this.nodeLookup.TryGetValue(num9 + new Int3(j, 0, 2 * i), out next))
                            {
                                while (next != null)
                                {
                                    Vector3 vector3 = position - ((Vector3)next.position);
                                    float   num12   = vector3.sqrMagnitude;
                                    if (num12 < positiveInfinity)
                                    {
                                        positiveInfinity = num12;
                                        node             = next;
                                    }
                                    if ((constraint == null) || (((num12 < num3) && (num12 < num)) && constraint.Suitable(next)))
                                    {
                                        num3  = num12;
                                        node2 = next;
                                    }
                                    next = next.next;
                                }
                            }
                        }
                        for (int k = 1; k < (2 * i); k++)
                        {
                            if (this.nodeLookup.TryGetValue(num9 + new Int3(0, 0, k), out next))
                            {
                                while (next != null)
                                {
                                    Vector3 vector4 = position - ((Vector3)next.position);
                                    float   num14   = vector4.sqrMagnitude;
                                    if (num14 < positiveInfinity)
                                    {
                                        positiveInfinity = num14;
                                        node             = next;
                                    }
                                    if ((constraint == null) || (((num14 < num3) && (num14 < num)) && constraint.Suitable(next)))
                                    {
                                        num3  = num14;
                                        node2 = next;
                                    }
                                    next = next.next;
                                }
                            }
                            if (this.nodeLookup.TryGetValue(num9 + new Int3(2 * i, 0, k), out next))
                            {
                                while (next != null)
                                {
                                    Vector3 vector5 = position - ((Vector3)next.position);
                                    float   num15   = vector5.sqrMagnitude;
                                    if (num15 < positiveInfinity)
                                    {
                                        positiveInfinity = num15;
                                        node             = next;
                                    }
                                    if ((constraint == null) || (((num15 < num3) && (num15 < num)) && constraint.Suitable(next)))
                                    {
                                        num3  = num15;
                                        node2 = next;
                                    }
                                    next = next.next;
                                }
                            }
                        }
                    }
                    else
                    {
                        Int3 num16 = key + new Int3(-i, -i, -i);
                        for (int m = 0; m <= (2 * i); m++)
                        {
                            for (int num18 = 0; num18 <= (2 * i); num18++)
                            {
                                if (this.nodeLookup.TryGetValue(num16 + new Int3(m, num18, 0), out next))
                                {
                                    while (next != null)
                                    {
                                        Vector3 vector6 = position - ((Vector3)next.position);
                                        float   num19   = vector6.sqrMagnitude;
                                        if (num19 < positiveInfinity)
                                        {
                                            positiveInfinity = num19;
                                            node             = next;
                                        }
                                        if ((constraint == null) || (((num19 < num3) && (num19 < num)) && constraint.Suitable(next)))
                                        {
                                            num3  = num19;
                                            node2 = next;
                                        }
                                        next = next.next;
                                    }
                                }
                                if (this.nodeLookup.TryGetValue(num16 + new Int3(m, num18, 2 * i), out next))
                                {
                                    while (next != null)
                                    {
                                        Vector3 vector7 = position - ((Vector3)next.position);
                                        float   num20   = vector7.sqrMagnitude;
                                        if (num20 < positiveInfinity)
                                        {
                                            positiveInfinity = num20;
                                            node             = next;
                                        }
                                        if ((constraint == null) || (((num20 < num3) && (num20 < num)) && constraint.Suitable(next)))
                                        {
                                            num3  = num20;
                                            node2 = next;
                                        }
                                        next = next.next;
                                    }
                                }
                            }
                        }
                        for (int n = 1; n < (2 * i); n++)
                        {
                            for (int num22 = 0; num22 <= (2 * i); num22++)
                            {
                                if (this.nodeLookup.TryGetValue(num16 + new Int3(0, num22, n), out next))
                                {
                                    while (next != null)
                                    {
                                        Vector3 vector8 = position - ((Vector3)next.position);
                                        float   num23   = vector8.sqrMagnitude;
                                        if (num23 < positiveInfinity)
                                        {
                                            positiveInfinity = num23;
                                            node             = next;
                                        }
                                        if ((constraint == null) || (((num23 < num3) && (num23 < num)) && constraint.Suitable(next)))
                                        {
                                            num3  = num23;
                                            node2 = next;
                                        }
                                        next = next.next;
                                    }
                                }
                                if (this.nodeLookup.TryGetValue(num16 + new Int3(2 * i, num22, n), out next))
                                {
                                    while (next != null)
                                    {
                                        Vector3 vector9 = position - ((Vector3)next.position);
                                        float   num24   = vector9.sqrMagnitude;
                                        if (num24 < positiveInfinity)
                                        {
                                            positiveInfinity = num24;
                                            node             = next;
                                        }
                                        if ((constraint == null) || (((num24 < num3) && (num24 < num)) && constraint.Suitable(next)))
                                        {
                                            num3  = num24;
                                            node2 = next;
                                        }
                                        next = next.next;
                                    }
                                }
                            }
                        }
                        for (int num25 = 1; num25 < (2 * i); num25++)
                        {
                            for (int num26 = 1; num26 < (2 * i); num26++)
                            {
                                if (this.nodeLookup.TryGetValue(num16 + new Int3(num25, 0, num26), out next))
                                {
                                    while (next != null)
                                    {
                                        Vector3 vector10 = position - ((Vector3)next.position);
                                        float   num27    = vector10.sqrMagnitude;
                                        if (num27 < positiveInfinity)
                                        {
                                            positiveInfinity = num27;
                                            node             = next;
                                        }
                                        if ((constraint == null) || (((num27 < num3) && (num27 < num)) && constraint.Suitable(next)))
                                        {
                                            num3  = num27;
                                            node2 = next;
                                        }
                                        next = next.next;
                                    }
                                }
                                if (this.nodeLookup.TryGetValue(num16 + new Int3(num25, 2 * i, num26), out next))
                                {
                                    while (next != null)
                                    {
                                        Vector3 vector11 = position - ((Vector3)next.position);
                                        float   num28    = vector11.sqrMagnitude;
                                        if (num28 < positiveInfinity)
                                        {
                                            positiveInfinity = num28;
                                            node             = next;
                                        }
                                        if ((constraint == null) || (((num28 < num3) && (num28 < num)) && constraint.Suitable(next)))
                                        {
                                            num3  = num28;
                                            node2 = next;
                                        }
                                        next = next.next;
                                    }
                                }
                            }
                        }
                    }
                    if (node2 != null)
                    {
                        num6 = Math.Min(num6, i + 1);
                    }
                }
            }
            else
            {
                for (int num29 = 0; num29 < this.nodeCount; num29++)
                {
                    PointNode node4    = this.nodes[num29];
                    Vector3   vector12 = position - ((Vector3)node4.position);
                    float     num30    = vector12.sqrMagnitude;
                    if (num30 < positiveInfinity)
                    {
                        positiveInfinity = num30;
                        node             = node4;
                    }
                    if ((constraint == null) || (((num30 < num3) && (num30 < num)) && constraint.Suitable(node4)))
                    {
                        num3  = num30;
                        node2 = node4;
                    }
                }
            }
            NNInfoInternal internal2 = new NNInfoInternal(node);

            internal2.constrainedNode = node2;
            if (node2 != null)
            {
                internal2.constClampedPosition = (Vector3)node2.position;
                return(internal2);
            }
            if (node != null)
            {
                internal2.constrainedNode      = node;
                internal2.constClampedPosition = (Vector3)node.position;
            }
            return(internal2);
        }
Exemplo n.º 19
0
        public override IEnumerable <Progress> ScanInternal()
        {
            yield return(new Progress(0f, "Searching for GameObjects"));

            if (this.root == null)
            {
                GameObject[] gos = (this.searchTag == null) ? null : GameObject.FindGameObjectsWithTag(this.searchTag);
                if (gos == null)
                {
                    this.nodes     = new PointNode[0];
                    this.nodeCount = 0;
                    yield break;
                }
                yield return(new Progress(0.1f, "Creating nodes"));

                this.nodes     = new PointNode[gos.Length];
                this.nodeCount = this.nodes.Length;
                for (int j = 0; j < this.nodes.Length; j++)
                {
                    this.nodes[j] = new PointNode(this.active);
                }
                for (int k = 0; k < gos.Length; k++)
                {
                    this.nodes[k].SetPosition((Int3)gos[k].transform.position);
                    this.nodes[k].Walkable   = true;
                    this.nodes[k].gameObject = gos[k].gameObject;
                }
            }
            else if (!this.recursive)
            {
                this.nodes     = new PointNode[this.root.childCount];
                this.nodeCount = this.nodes.Length;
                for (int l = 0; l < this.nodes.Length; l++)
                {
                    this.nodes[l] = new PointNode(this.active);
                }
                int         num        = 0;
                IEnumerator enumerator = this.root.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        object    obj       = enumerator.Current;
                        Transform transform = (Transform)obj;
                        this.nodes[num].SetPosition((Int3)transform.position);
                        this.nodes[num].Walkable   = true;
                        this.nodes[num].gameObject = transform.gameObject;
                        num++;
                    }
                }
                finally
                {
                    IDisposable disposable;
                    if ((disposable = (enumerator as IDisposable)) != null)
                    {
                        disposable.Dispose();
                    }
                }
            }
            else
            {
                this.nodes     = new PointNode[PointGraph.CountChildren(this.root)];
                this.nodeCount = this.nodes.Length;
                for (int m = 0; m < this.nodes.Length; m++)
                {
                    this.nodes[m] = new PointNode(this.active);
                }
                int num2 = 0;
                this.AddChildren(ref num2, this.root);
            }
            if (this.optimizeForSparseGraph)
            {
                yield return(new Progress(0.15f, "Building node lookup"));

                this.RebuildNodeLookup();
            }
            if (this.maxDistance >= 0f)
            {
                List <PointNode> connections          = new List <PointNode>();
                List <uint>      costs                = new List <uint>();
                List <GraphNode> candidateConnections = new List <GraphNode>();
                long             maxPossibleSqrRange;
                if (this.maxDistance == 0f && (this.limits.x == 0f || this.limits.y == 0f || this.limits.z == 0f))
                {
                    maxPossibleSqrRange = long.MaxValue;
                }
                else
                {
                    maxPossibleSqrRange  = (long)(Mathf.Max(this.limits.x, Mathf.Max(this.limits.y, Mathf.Max(this.limits.z, this.maxDistance))) * 1000f) + 1L;
                    maxPossibleSqrRange *= maxPossibleSqrRange;
                }
                for (int i = 0; i < this.nodes.Length; i++)
                {
                    if (i % 512 == 0)
                    {
                        yield return(new Progress(Mathf.Lerp(0.15f, 1f, (float)i / (float)this.nodes.Length), "Connecting nodes"));
                    }
                    connections.Clear();
                    costs.Clear();
                    PointNode node = this.nodes[i];
                    if (this.optimizeForSparseGraph)
                    {
                        candidateConnections.Clear();
                        this.lookupTree.GetInRange(node.position, maxPossibleSqrRange, candidateConnections);
                        Console.WriteLine(i + " " + candidateConnections.Count);
                        for (int n = 0; n < candidateConnections.Count; n++)
                        {
                            PointNode pointNode = candidateConnections[n] as PointNode;
                            float     num3;
                            if (pointNode != node && this.IsValidConnection(node, pointNode, out num3))
                            {
                                connections.Add(pointNode);
                                costs.Add((uint)Mathf.RoundToInt(num3 * 1000f));
                            }
                        }
                    }
                    else
                    {
                        for (int num4 = 0; num4 < this.nodes.Length; num4++)
                        {
                            if (i != num4)
                            {
                                PointNode pointNode2 = this.nodes[num4];
                                float     num5;
                                if (this.IsValidConnection(node, pointNode2, out num5))
                                {
                                    connections.Add(pointNode2);
                                    costs.Add((uint)Mathf.RoundToInt(num5 * 1000f));
                                }
                            }
                        }
                    }
                    node.connections     = connections.ToArray();
                    node.connectionCosts = costs.ToArray();
                }
            }
            yield break;
        }
Exemplo n.º 20
0
 private void AddToLookup(PointNode node)
 {
     this.lookupTree.Add(node);
 }
Exemplo n.º 21
0
        // Scan() has been deprecated, replaced by ScanInternal. 
        public override void ScanInternal(OnScanStatus statusCallback) {
            // ********************************************************************
            // NOTE: removed all code that derived nodes from GameObjects and Tags
            // ********************************************************************

            //D.Log("ScanInternal called.");
            var walkableOpenSpaceWaypoints = GetWalkableOpenSpaceWaypoints();
            var unwalkableOpenSpaceWaypoints = GetUnWalkableOpenSpaceWaypoints();
            var walkableSystemWaypoints = GetWalkableInteriorSystemWaypoints();

            int waypointCount = walkableOpenSpaceWaypoints.Count + unwalkableOpenSpaceWaypoints.Count + walkableSystemWaypoints.Count;

            // Make the Nodes array
            nodes = new PointNode[waypointCount];
            nodeCount = waypointCount;
            //for (int nodeIndex = 0; nodeIndex < waypointCount; nodeIndex++) {
            //    nodes[nodeIndex] = new PointNode(active);
            //}

            int nextNodeIndex = Constants.Zero;
            bool isWalkable = true;
            PopulateNodes(walkableOpenSpaceWaypoints, openSpaceTagMask, isWalkable, ref nextNodeIndex);
            //D.Log("NextNodeIndex = {0}.", nextNodeIndex);
            PopulateNodes(walkableSystemWaypoints, systemTagMask, isWalkable, ref nextNodeIndex);
            //D.Log("NextNodeIndex = {0}.", nextNodeIndex);

            isWalkable = false;
            PopulateNodes(unwalkableOpenSpaceWaypoints, openSpaceTagMask, isWalkable, ref nextNodeIndex);
            //D.Log("NextNodeIndex = {0}.", nextNodeIndex);

            D.Log("{0} Pathfinding nodes.", nodeCount);

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

                //Loop through all nodes and add connections to other nodes
                int connectionCount = 0;
                int invalidConnectionCount = 0;
                for (int i = 0; i < nodes.Length; i++) {
                    connections.Clear();
                    costs.Clear();

                    PointNode node = nodes[i];

                    // OPTIMIZE 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 = 0;
                        if (IsValidConnection(node, other, out dist)) {
                            connections.Add(other);
                            /** \todo Is this equal to .costMagnitude */
                            costs.Add((uint)Mathf.RoundToInt(dist * Int3.FloatPrecision));
                        }
                        else {
                            invalidConnectionCount++;
                        }
                        //else if (dist <= maxDistance) { // maxDistance is currently 700
                        //    invalidConnectionCount++;
                        //    D.Warn("Connection from Node at {0} to Node at {1} is invalid.", (Vector3)node.position, (Vector3)other.position);
                        //    D.AssertException(false);
                        //}
                    }
                    node.connections = connections.ToArray();
                    connectionCount += connections.Count;
                    node.connectionCosts = costs.ToArray();
                }
                int totalConnectionsAttempted = connectionCount + invalidConnectionCount;
                D.Log("{0}/{1} valid connections.", connectionCount, totalConnectionsAttempted);
            }
        }
Exemplo n.º 22
0
        public override NNInfo GetNearestForce(Vector3 position, NNConstraint constraint)
        {
            if (nodes == null)
            {
                return(new NNInfo());
            }

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

            float     minDist = float.PositiveInfinity;
            GraphNode minNode = null;

            float     minConstDist = float.PositiveInfinity;
            GraphNode minConstNode = null;

            if (optimizeForSparseGraph)
            {
                Int3 lookupStart = WorldToLookupSpace((Int3)position);

                Int3 size = lookupStart - minLookup;

                int mw = 0;
                mw = System.Math.Max(mw, System.Math.Abs(size.x));
                mw = System.Math.Max(mw, System.Math.Abs(size.y));
                mw = System.Math.Max(mw, System.Math.Abs(size.z));

                size = lookupStart - maxLookup;
                mw   = System.Math.Max(mw, System.Math.Abs(size.x));
                mw   = System.Math.Max(mw, System.Math.Abs(size.y));
                mw   = System.Math.Max(mw, System.Math.Abs(size.z));

                PointNode node;

                var searcher = new GetNearestHelper(position, maxDistSqr, constraint, nodeLookup);
                searcher.Search(lookupStart);

                for (int w = 1; w <= mw; w++)
                {
                    if (w >= 20)
                    {
                        Debug.LogWarning("Aborting GetNearest call at maximum distance because it has iterated too many times.\n" +
                                         "If you get this regularly, check your settings for PointGraph -> <b>Optimize For Sparse Graph</b> and " +
                                         "PointGraph -> <b>Optimize For 2D</b>.\nThis happens when the closest node was very far away (20*link distance between nodes). " +
                                         "When optimizing for sparse graphs, getting the nearest node from far away positions is <b>very slow</b>.\n");
                        break;
                    }

                    if (lookupCellSize.y == 0)
                    {
                        Int3 reference = lookupStart + new Int3(-w, 0, -w);

                        for (int x = 0; x <= 2 * w; x++)
                        {
                            searcher.Search(reference + new Int3(x, 0, 0));
                            searcher.Search(reference + new Int3(x, 0, 2 * w));
                        }

                        for (int z = 1; z < 2 * w; z++)
                        {
                            searcher.Search(reference + new Int3(0, 0, z));
                            searcher.Search(reference + new Int3(2 * w, 0, z));
                        }
                    }
                    else
                    {
                        Int3 reference = lookupStart + new Int3(-w, -w, -w);

                        for (int x = 0; x <= 2 * w; x++)
                        {
                            for (int y = 0; y <= 2 * w; y++)
                            {
                                searcher.Search(reference + new Int3(x, y, 0));
                                searcher.Search(reference + new Int3(x, y, 2 * w));
                            }
                        }

                        for (int z = 1; z < 2 * w; z++)
                        {
                            for (int y = 0; y <= 2 * w; y++)
                            {
                                searcher.Search(reference + new Int3(0, y, z));
                                searcher.Search(reference + new Int3(2 * w, y, z));
                            }
                        }

                        for (int x = 1; x < 2 * w; x++)
                        {
                            for (int z = 1; z < 2 * w; z++)
                            {
                                searcher.Search(reference + new Int3(x, 0, z));
                                searcher.Search(reference + new Int3(x, 2 * w, z));
                            }
                        }
                    }

                    minConstNode = searcher.minConstNode;
                    minNode      = searcher.minNode;
                    minDist      = searcher.minDist;
                    minConstDist = searcher.minConstDist;

                    if (minConstNode != null)
                    {
                        // Only search one more layer
                        mw = System.Math.Min(mw, w + 1);
                    }
                }
            }
            else
            {
                for (int i = 0; i < nodeCount; i++)
                {
                    PointNode node = nodes[i];
                    float     dist = (position - (Vector3)node.position).sqrMagnitude;

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

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

            var nnInfo = new NNInfo(minNode);

            nnInfo.constrainedNode = minConstNode;

            if (minConstNode != null)
            {
                nnInfo.constClampedPosition = (Vector3)minConstNode.position;
            }
            else if (minNode != null)
            {
                nnInfo.constrainedNode      = minNode;
                nnInfo.constClampedPosition = (Vector3)minNode.position;
            }

            return(nnInfo);
        }
Exemplo n.º 23
0
        // Token: 0x0600051F RID: 1311 RVA: 0x0002C174 File Offset: 0x0002A574
        public override NNInfo GetNearestForce(Vector3 position, NNConstraint constraint)
        {
            if (this.nodes == null)
            {
                return(default(NNInfo));
            }
            float     num        = (!constraint.constrainDistance) ? float.PositiveInfinity : AstarPath.active.maxNearestNodeDistanceSqr;
            float     num2       = float.PositiveInfinity;
            GraphNode graphNode  = null;
            float     num3       = float.PositiveInfinity;
            GraphNode graphNode2 = null;

            if (this.optimizeForSparseGraph)
            {
                Int3 @int = this.WorldToLookupSpace((Int3)position);
                Int3 int2 = @int - this.minLookup;
                int  num4 = 0;
                num4 = Math.Max(num4, Math.Abs(int2.x));
                num4 = Math.Max(num4, Math.Abs(int2.y));
                num4 = Math.Max(num4, Math.Abs(int2.z));
                int2 = @int - this.maxLookup;
                num4 = Math.Max(num4, Math.Abs(int2.x));
                num4 = Math.Max(num4, Math.Abs(int2.y));
                num4 = Math.Max(num4, Math.Abs(int2.z));
                PointNode pointNode = null;
                if (this.nodeLookup.TryGetValue(@int, out pointNode))
                {
                    while (pointNode != null)
                    {
                        float sqrMagnitude = (position - (Vector3)pointNode.position).sqrMagnitude;
                        if (sqrMagnitude < num2)
                        {
                            num2      = sqrMagnitude;
                            graphNode = pointNode;
                        }
                        if (constraint == null || (sqrMagnitude < num3 && sqrMagnitude < num && constraint.Suitable(pointNode)))
                        {
                            num3       = sqrMagnitude;
                            graphNode2 = pointNode;
                        }
                        pointNode = pointNode.next;
                    }
                }
                for (int i = 1; i <= num4; i++)
                {
                    if (i >= 20)
                    {
                        Debug.LogWarning("Aborting GetNearest call at maximum distance because it has iterated too many times.\nIf you get this regularly, check your settings for PointGraph -> <b>Optimize For Sparse Graph</b> and PointGraph -> <b>Optimize For 2D</b>.\nThis happens when the closest node was very far away (20*link distance between nodes). When optimizing for sparse graphs, getting the nearest node from far away positions is <b>very slow</b>.\n");
                        break;
                    }
                    if (this.lookupCellSize.y == 0)
                    {
                        Int3 lhs = @int + new Int3(-i, 0, -i);
                        for (int j = 0; j <= 2 * i; j++)
                        {
                            if (this.nodeLookup.TryGetValue(lhs + new Int3(j, 0, 0), out pointNode))
                            {
                                while (pointNode != null)
                                {
                                    float sqrMagnitude2 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                    if (sqrMagnitude2 < num2)
                                    {
                                        num2      = sqrMagnitude2;
                                        graphNode = pointNode;
                                    }
                                    if (constraint == null || (sqrMagnitude2 < num3 && sqrMagnitude2 < num && constraint.Suitable(pointNode)))
                                    {
                                        num3       = sqrMagnitude2;
                                        graphNode2 = pointNode;
                                    }
                                    pointNode = pointNode.next;
                                }
                            }
                            if (this.nodeLookup.TryGetValue(lhs + new Int3(j, 0, 2 * i), out pointNode))
                            {
                                while (pointNode != null)
                                {
                                    float sqrMagnitude3 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                    if (sqrMagnitude3 < num2)
                                    {
                                        num2      = sqrMagnitude3;
                                        graphNode = pointNode;
                                    }
                                    if (constraint == null || (sqrMagnitude3 < num3 && sqrMagnitude3 < num && constraint.Suitable(pointNode)))
                                    {
                                        num3       = sqrMagnitude3;
                                        graphNode2 = pointNode;
                                    }
                                    pointNode = pointNode.next;
                                }
                            }
                        }
                        for (int k = 1; k < 2 * i; k++)
                        {
                            if (this.nodeLookup.TryGetValue(lhs + new Int3(0, 0, k), out pointNode))
                            {
                                while (pointNode != null)
                                {
                                    float sqrMagnitude4 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                    if (sqrMagnitude4 < num2)
                                    {
                                        num2      = sqrMagnitude4;
                                        graphNode = pointNode;
                                    }
                                    if (constraint == null || (sqrMagnitude4 < num3 && sqrMagnitude4 < num && constraint.Suitable(pointNode)))
                                    {
                                        num3       = sqrMagnitude4;
                                        graphNode2 = pointNode;
                                    }
                                    pointNode = pointNode.next;
                                }
                            }
                            if (this.nodeLookup.TryGetValue(lhs + new Int3(2 * i, 0, k), out pointNode))
                            {
                                while (pointNode != null)
                                {
                                    float sqrMagnitude5 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                    if (sqrMagnitude5 < num2)
                                    {
                                        num2      = sqrMagnitude5;
                                        graphNode = pointNode;
                                    }
                                    if (constraint == null || (sqrMagnitude5 < num3 && sqrMagnitude5 < num && constraint.Suitable(pointNode)))
                                    {
                                        num3       = sqrMagnitude5;
                                        graphNode2 = pointNode;
                                    }
                                    pointNode = pointNode.next;
                                }
                            }
                        }
                    }
                    else
                    {
                        Int3 lhs2 = @int + new Int3(-i, -i, -i);
                        for (int l = 0; l <= 2 * i; l++)
                        {
                            for (int m = 0; m <= 2 * i; m++)
                            {
                                if (this.nodeLookup.TryGetValue(lhs2 + new Int3(l, m, 0), out pointNode))
                                {
                                    while (pointNode != null)
                                    {
                                        float sqrMagnitude6 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                        if (sqrMagnitude6 < num2)
                                        {
                                            num2      = sqrMagnitude6;
                                            graphNode = pointNode;
                                        }
                                        if (constraint == null || (sqrMagnitude6 < num3 && sqrMagnitude6 < num && constraint.Suitable(pointNode)))
                                        {
                                            num3       = sqrMagnitude6;
                                            graphNode2 = pointNode;
                                        }
                                        pointNode = pointNode.next;
                                    }
                                }
                                if (this.nodeLookup.TryGetValue(lhs2 + new Int3(l, m, 2 * i), out pointNode))
                                {
                                    while (pointNode != null)
                                    {
                                        float sqrMagnitude7 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                        if (sqrMagnitude7 < num2)
                                        {
                                            num2      = sqrMagnitude7;
                                            graphNode = pointNode;
                                        }
                                        if (constraint == null || (sqrMagnitude7 < num3 && sqrMagnitude7 < num && constraint.Suitable(pointNode)))
                                        {
                                            num3       = sqrMagnitude7;
                                            graphNode2 = pointNode;
                                        }
                                        pointNode = pointNode.next;
                                    }
                                }
                            }
                        }
                        for (int n = 1; n < 2 * i; n++)
                        {
                            for (int num5 = 0; num5 <= 2 * i; num5++)
                            {
                                if (this.nodeLookup.TryGetValue(lhs2 + new Int3(0, num5, n), out pointNode))
                                {
                                    while (pointNode != null)
                                    {
                                        float sqrMagnitude8 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                        if (sqrMagnitude8 < num2)
                                        {
                                            num2      = sqrMagnitude8;
                                            graphNode = pointNode;
                                        }
                                        if (constraint == null || (sqrMagnitude8 < num3 && sqrMagnitude8 < num && constraint.Suitable(pointNode)))
                                        {
                                            num3       = sqrMagnitude8;
                                            graphNode2 = pointNode;
                                        }
                                        pointNode = pointNode.next;
                                    }
                                }
                                if (this.nodeLookup.TryGetValue(lhs2 + new Int3(2 * i, num5, n), out pointNode))
                                {
                                    while (pointNode != null)
                                    {
                                        float sqrMagnitude9 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                        if (sqrMagnitude9 < num2)
                                        {
                                            num2      = sqrMagnitude9;
                                            graphNode = pointNode;
                                        }
                                        if (constraint == null || (sqrMagnitude9 < num3 && sqrMagnitude9 < num && constraint.Suitable(pointNode)))
                                        {
                                            num3       = sqrMagnitude9;
                                            graphNode2 = pointNode;
                                        }
                                        pointNode = pointNode.next;
                                    }
                                }
                            }
                        }
                        for (int num6 = 1; num6 < 2 * i; num6++)
                        {
                            for (int num7 = 1; num7 < 2 * i; num7++)
                            {
                                if (this.nodeLookup.TryGetValue(lhs2 + new Int3(num6, 0, num7), out pointNode))
                                {
                                    while (pointNode != null)
                                    {
                                        float sqrMagnitude10 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                        if (sqrMagnitude10 < num2)
                                        {
                                            num2      = sqrMagnitude10;
                                            graphNode = pointNode;
                                        }
                                        if (constraint == null || (sqrMagnitude10 < num3 && sqrMagnitude10 < num && constraint.Suitable(pointNode)))
                                        {
                                            num3       = sqrMagnitude10;
                                            graphNode2 = pointNode;
                                        }
                                        pointNode = pointNode.next;
                                    }
                                }
                                if (this.nodeLookup.TryGetValue(lhs2 + new Int3(num6, 2 * i, num7), out pointNode))
                                {
                                    while (pointNode != null)
                                    {
                                        float sqrMagnitude11 = (position - (Vector3)pointNode.position).sqrMagnitude;
                                        if (sqrMagnitude11 < num2)
                                        {
                                            num2      = sqrMagnitude11;
                                            graphNode = pointNode;
                                        }
                                        if (constraint == null || (sqrMagnitude11 < num3 && sqrMagnitude11 < num && constraint.Suitable(pointNode)))
                                        {
                                            num3       = sqrMagnitude11;
                                            graphNode2 = pointNode;
                                        }
                                        pointNode = pointNode.next;
                                    }
                                }
                            }
                        }
                    }
                    if (graphNode2 != null)
                    {
                        num4 = Math.Min(num4, i + 1);
                    }
                }
            }
            else
            {
                for (int num8 = 0; num8 < this.nodeCount; num8++)
                {
                    PointNode pointNode2     = this.nodes[num8];
                    float     sqrMagnitude12 = (position - (Vector3)pointNode2.position).sqrMagnitude;
                    if (sqrMagnitude12 < num2)
                    {
                        num2      = sqrMagnitude12;
                        graphNode = pointNode2;
                    }
                    if (constraint == null || (sqrMagnitude12 < num3 && sqrMagnitude12 < num && constraint.Suitable(pointNode2)))
                    {
                        num3       = sqrMagnitude12;
                        graphNode2 = pointNode2;
                    }
                }
            }
            NNInfo result = new NNInfo(graphNode);

            result.constrainedNode = graphNode2;
            if (graphNode2 != null)
            {
                result.constClampedPosition = (Vector3)graphNode2.position;
            }
            else if (graphNode != null)
            {
                result.constrainedNode      = graphNode;
                result.constClampedPosition = (Vector3)graphNode.position;
            }
            return(result);
        }
Exemplo n.º 24
0
        public void AddToLookup(PointNode node) {
            if (_nodeLookup == null) { return; }

            Int3 lookupPosition = WorldToLookupSpace(node.position);

            if (_nodeLookup.Count == 0) {
                _minLookup = lookupPosition;
                _maxLookup = lookupPosition;
            }
            else {
                _minLookup = new Int3(System.Math.Min(_minLookup.x, lookupPosition.x), System.Math.Min(_minLookup.y, lookupPosition.y), System.Math.Min(_minLookup.z, lookupPosition.z));
                _maxLookup = new Int3(System.Math.Max(_minLookup.x, lookupPosition.x), System.Math.Max(_minLookup.y, lookupPosition.y), System.Math.Max(_minLookup.z, lookupPosition.z));
            }

            // Does not cover all cases, but at least some of them
            if (node.next != null) {
                throw new System.Exception("This node has already been added to the lookup structure.");
            }

            PointNode linkedListRoot;
            if (_nodeLookup.TryGetValue(lookupPosition, out linkedListRoot)) {
                // Insert in between
                node.next = linkedListRoot.next;
                linkedListRoot.next = node;
            }
            else {
                _nodeLookup[lookupPosition] = node;
            }
        }
Exemplo n.º 25
0
        // Token: 0x0600052A RID: 1322 RVA: 0x0002D6B8 File Offset: 0x0002BAB8
        public void UpdateArea(GraphUpdateObject guo)
        {
            if (this.nodes == null)
            {
                return;
            }
            for (int i = 0; i < this.nodeCount; i++)
            {
                if (guo.bounds.Contains((Vector3)this.nodes[i].position))
                {
                    guo.WillUpdateNode(this.nodes[i]);
                    guo.Apply(this.nodes[i]);
                }
            }
            if (guo.updatePhysics)
            {
                Bounds bounds = guo.bounds;
                if (this.thickRaycast)
                {
                    bounds.Expand(this.thickRaycastRadius * 2f);
                }
                List <GraphNode> list = ListPool <GraphNode> .Claim();

                List <uint> list2 = ListPool <uint> .Claim();

                for (int j = 0; j < this.nodeCount; j++)
                {
                    PointNode        pointNode = this.nodes[j];
                    Vector3          a         = (Vector3)pointNode.position;
                    List <GraphNode> list3     = null;
                    List <uint>      list4     = null;
                    for (int k = 0; k < this.nodeCount; k++)
                    {
                        if (k != j)
                        {
                            Vector3 b = (Vector3)this.nodes[k].position;
                            if (Polygon.LineIntersectsBounds(bounds, a, b))
                            {
                                PointNode pointNode2 = this.nodes[k];
                                bool      flag       = pointNode.ContainsConnection(pointNode2);
                                float     num;
                                if (!flag && this.IsValidConnection(pointNode, pointNode2, out num))
                                {
                                    if (list3 == null)
                                    {
                                        list.Clear();
                                        list2.Clear();
                                        list3 = list;
                                        list4 = list2;
                                        list3.AddRange(pointNode.connections);
                                        list4.AddRange(pointNode.connectionCosts);
                                    }
                                    uint item = (uint)Mathf.RoundToInt(num * 1000f);
                                    list3.Add(pointNode2);
                                    list4.Add(item);
                                }
                                else if (flag && !this.IsValidConnection(pointNode, pointNode2, out num))
                                {
                                    if (list3 == null)
                                    {
                                        list.Clear();
                                        list2.Clear();
                                        list3 = list;
                                        list4 = list2;
                                        list3.AddRange(pointNode.connections);
                                        list4.AddRange(pointNode.connectionCosts);
                                    }
                                    int num2 = list3.IndexOf(pointNode2);
                                    if (num2 != -1)
                                    {
                                        list3.RemoveAt(num2);
                                        list4.RemoveAt(num2);
                                    }
                                }
                            }
                        }
                    }
                    if (list3 != null)
                    {
                        pointNode.connections     = list3.ToArray();
                        pointNode.connectionCosts = list4.ToArray();
                    }
                }
                ListPool <GraphNode> .Release(list);

                ListPool <uint> .Release(list2);
            }
        }
Exemplo n.º 26
0
        private void AddNodes(IList<Vector3> waypoints, uint tag, ref int nextNodeIndex) {
            CheckAndAdjustNodesSize(waypoints.Count);

            int indexAfterLastNode = nextNodeIndex + waypoints.Count;
            for (int index = nextNodeIndex; index < indexAfterLastNode; index++) {
                PointNode node = new PointNode(active);
                node.SetPosition((Int3)waypoints[index - nextNodeIndex]);
                node.Walkable = true;
                node.GraphIndex = graphIndex;
                node.Tag = tag;
                nodes[index] = node;

                nodeCount++;
                AddToLookup(node);
            }
            D.AssertEqual(nodes.Length, nodeCount);
            nextNodeIndex = indexAfterLastNode;
        }
Exemplo n.º 27
0
 void AddToLookup(PointNode node)
 {
     // A* Pathfinding Project Pro Only
 }
Exemplo n.º 28
0
 private void CheckAndAdjustNodesSize(int additionalNodes) {
     if (nodes == null || nodeCount == nodes.Length) {
         //var startTime = Utility.SystemTime;
         var nds = new PointNode[nodes != null ? nodes.Length + additionalNodes : additionalNodes];
         for (int i = 0; i < nodeCount; i++) {
             nds[i] = nodes[i];
         }
         nodes = nds;
         //D.Log("{0}.CheckAndAdjustNodesSize({1}) took {2:0.00} seconds.", GetType().Name, additionalNodes, (Utility.SystemTime - startTime).TotalSeconds);
     }
 }
Exemplo n.º 29
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();
                }
            }
        }
 // Token: 0x060025BE RID: 9662 RVA: 0x001A1828 File Offset: 0x0019FA28
 private IEnumerable <Progress> ConnectNodesAsync()
 {
     if (this.maxDistance >= 0f)
     {
         List <Connection> connections          = new List <Connection>();
         List <GraphNode>  candidateConnections = new List <GraphNode>();
         long maxSquaredRange;
         if (this.maxDistance == 0f && (this.limits.x == 0f || this.limits.y == 0f || this.limits.z == 0f))
         {
             maxSquaredRange = long.MaxValue;
         }
         else
         {
             maxSquaredRange  = (long)(Mathf.Max(this.limits.x, Mathf.Max(this.limits.y, Mathf.Max(this.limits.z, this.maxDistance))) * 1000f) + 1L;
             maxSquaredRange *= maxSquaredRange;
         }
         int num3;
         for (int i = 0; i < this.nodeCount; i = num3 + 1)
         {
             if (i % 512 == 0)
             {
                 yield return(new Progress((float)i / (float)this.nodes.Length, "Connecting nodes"));
             }
             connections.Clear();
             PointNode pointNode = this.nodes[i];
             if (this.optimizeForSparseGraph)
             {
                 candidateConnections.Clear();
                 this.lookupTree.GetInRange(pointNode.position, maxSquaredRange, candidateConnections);
                 for (int j = 0; j < candidateConnections.Count; j++)
                 {
                     PointNode pointNode2 = candidateConnections[j] as PointNode;
                     float     num;
                     if (pointNode2 != pointNode && this.IsValidConnection(pointNode, pointNode2, out num))
                     {
                         connections.Add(new Connection(pointNode2, (uint)Mathf.RoundToInt(num * 1000f), byte.MaxValue));
                     }
                 }
             }
             else
             {
                 for (int k = 0; k < this.nodeCount; k++)
                 {
                     if (i != k)
                     {
                         PointNode pointNode3 = this.nodes[k];
                         float     num2;
                         if (this.IsValidConnection(pointNode, pointNode3, out num2))
                         {
                             connections.Add(new Connection(pointNode3, (uint)Mathf.RoundToInt(num2 * 1000f), byte.MaxValue));
                         }
                     }
                 }
             }
             pointNode.connections = connections.ToArray();
             num3 = i;
         }
         connections          = null;
         candidateConnections = null;
     }
     yield break;
 }
Exemplo n.º 31
0
		public void InternalOnPostScan () {

			if ( EndTransform == null || StartTransform == null ) return;

			if ( AstarPath.active.astarData.pointGraph == null ) {
				AstarPath.active.astarData.AddGraph ( new PointGraph () );
			}


			if ( startNode != null) {
				NodeLink2 tmp;
				if (reference.TryGetValue (startNode, out tmp) && tmp == this) reference.Remove (startNode);
			}
	
			if ( endNode != null) {
				NodeLink2 tmp;
				if (reference.TryGetValue (endNode, out tmp) && tmp == this) reference.Remove (endNode);
			}
	
			//Get nearest nodes from the first point graph, assuming both start and end transforms are nodes
			startNode = AstarPath.active.astarData.pointGraph.AddNode ( (Int3)StartTransform.position );//AstarPath.active.astarData.pointGraph.GetNearest(StartTransform.position).node as PointNode;
			endNode = AstarPath.active.astarData.pointGraph.AddNode ( (Int3)EndTransform.position ); //AstarPath.active.astarData.pointGraph.GetNearest(EndTransform.position).node as PointNode;

			connectedNode1 = null;
			connectedNode2 = null;
			
			if (startNode == null || endNode == null) {
				startNode = null;
				endNode = null;
				return;
			}
			
			postScanCalled = true;
			reference[startNode] = this;
			reference[endNode] = this;
			Apply( true );
		}
Exemplo n.º 32
0
        [Obsolete]  // 8.17.16 use my AddNodes(waypoints)
        public PointNode AddNode(Int3 position) {
            if (nodes == null || nodeCount == nodes.Length) {
                var nds = new PointNode[nodes != null ? System.Math.Max(nodes.Length + 4, nodes.Length * 2) : 4];
                for (int i = 0; i < nodeCount; i++) nds[i] = nodes[i];
                nodes = nds;
            }

            PointNode node = new PointNode(active);

            node.SetPosition(position);
            node.GraphIndex = graphIndex;
            node.Walkable = true;

            nodes[nodeCount] = node;
            nodeCount++;

            AddToLookup(node);

            return node;
        }
Exemplo n.º 33
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();
                }
            }
        }
Exemplo n.º 34
0
        public override void DeserializeExtraInfo(GraphSerializationContext ctx) {
            int count = ctx.reader.ReadInt32();

            if (count == -1) {
                nodes = null;
                return;
            }

            nodes = new PointNode[count];
            nodeCount = count;

            for (int i = 0; i < nodes.Length; i++) {
                if (ctx.reader.ReadInt32() == -1) continue;
                nodes[i] = new PointNode(active);
                nodes[i].DeserializeNode(ctx);
            }
        }
Exemplo n.º 35
0
        /** Returns if the connection between \a a and \a b is valid.
 * Checks for obstructions using raycasts (if enabled) and checks for height differences.\n
 * As a bonus, it outputs the distance between the nodes too if the connection is valid
 */
        private bool IsValidConnection(PointNode a, PointNode b, out float dist) {
            dist = Constants.ZeroF;

            if (a.Walkable && b.Walkable) {
                var dir = (Vector3)(a.position - b.position);

                dist = dir.magnitude;
                if (maxDistance == 0 || dist < maxDistance) {
                    return true;
                }
            }
            return false;
        }
        // Token: 0x060025C3 RID: 9667 RVA: 0x001A1AF0 File Offset: 0x0019FCF0
        void IUpdatableGraph.UpdateArea(GraphUpdateObject guo)
        {
            if (this.nodes == null)
            {
                return;
            }
            for (int i = 0; i < this.nodeCount; i++)
            {
                PointNode pointNode = this.nodes[i];
                if (guo.bounds.Contains((Vector3)pointNode.position))
                {
                    guo.WillUpdateNode(pointNode);
                    guo.Apply(pointNode);
                }
            }
            if (guo.updatePhysics)
            {
                Bounds bounds = guo.bounds;
                if (this.thickRaycast)
                {
                    bounds.Expand(this.thickRaycastRadius * 2f);
                }
                List <Connection> list = ListPool <Connection> .Claim();

                for (int j = 0; j < this.nodeCount; j++)
                {
                    PointNode         pointNode2 = this.nodes[j];
                    Vector3           a          = (Vector3)pointNode2.position;
                    List <Connection> list2      = null;
                    for (int k = 0; k < this.nodeCount; k++)
                    {
                        if (k != j)
                        {
                            Vector3 b = (Vector3)this.nodes[k].position;
                            if (VectorMath.SegmentIntersectsBounds(bounds, a, b))
                            {
                                PointNode pointNode3 = this.nodes[k];
                                bool      flag       = pointNode2.ContainsConnection(pointNode3);
                                float     num;
                                bool      flag2 = this.IsValidConnection(pointNode2, pointNode3, out num);
                                if (list2 == null && flag != flag2)
                                {
                                    list.Clear();
                                    list2 = list;
                                    list2.AddRange(pointNode2.connections);
                                }
                                if (!flag && flag2)
                                {
                                    uint cost = (uint)Mathf.RoundToInt(num * 1000f);
                                    list2.Add(new Connection(pointNode3, cost, byte.MaxValue));
                                }
                                else if (flag && !flag2)
                                {
                                    for (int l = 0; l < list2.Count; l++)
                                    {
                                        if (list2[l].node == pointNode3)
                                        {
                                            list2.RemoveAt(l);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (list2 != null)
                    {
                        pointNode2.connections = list2.ToArray();
                    }
                }
                ListPool <Connection> .Release(ref list);
            }
        }