예제 #1
0
        /// <inheritdoc />
        protected override Node AddOneNodeToTreeAtPosition(Vector3 position)
        {
            var closestNode = Config.Tree.GetClosestNode(position);

            var direction          = position - closestNode.Position;
            var directionMagnitude = direction.magnitude;

            if (directionMagnitude == 0) //the random point already exists in the tree, hence don't add a new one
            {
                return(null);
            }
            var lengthMultiplier = Config.MAXBranchLength < directionMagnitude
                ? Config.MAXBranchLength
                : directionMagnitude;
            var newNode = new Node(closestNode.Position + direction / directionMagnitude * lengthMultiplier);

            if (IsNotCollidingWithObstacle(closestNode.Position, direction, lengthMultiplier))
            {
                var minNode        = closestNode;
                var minCost        = minNode.Cost + (newNode.Position - minNode.Position).magnitude;
                var neighbourNodes = Tree.GetNeighboursInRadius(newNode, _radius);

                // Find closest parent cost wise (within the given radius around the new node).
                // The current minNode which is closest to the newNode might not be the shortest path to reach the new node from the start node, considering the path cost.
                // Hence the new node is added as child to the neighbour node which offers the shortest possible path to the new node, starting from the root node.
                foreach (var n in neighbourNodes)
                {
                    var dir          = newNode.Position - n.Position;
                    var dirMagnitude = dir.magnitude;
                    if (n.Cost + dirMagnitude < minCost && IsNotCollidingWithObstacle(n.Position, dir, dirMagnitude))
                    {
                        minNode = n;
                        minCost = n.Cost + dirMagnitude;
                    }
                }

                Tree.AddChildNodeToParentNodeWithCost(minNode, newNode);

                // Check if neighbours cost might be lower traversing through the new node, if so restructure the tree, by making the neighbour node a child of the new node.
                foreach (var node in
                         from n in neighbourNodes
                         let dir = n.Position - newNode.Position
                                   let dirMagnitude = dir.magnitude
                                                      where newNode.Cost + dirMagnitude < n.Cost &&
                                                      IsNotCollidingWithObstacle(newNode.Position, dir, dirMagnitude)
                                                      select n)
                {
                    // make the neighbour node child of the new node
                    node.Parent.RemoveChild(node);
                    Tree.AddChildNodeToParentNodeWithCost(newNode, node);
                }

                var dir2 = newNode.Position - minNode.Position;
                if (IsCollidingWithTarget(minNode.Position, dir2, dir2.magnitude) && !Tree.HasFoundPath)
                {
                    Debug.Log("Found Path");
                    Tree.TargetNode = newNode.Position == PosTarget ? newNode : AddOneNodeToTreeAtPosition(PosTarget);
                }

                return(newNode);
            }

            return(null);
        }