예제 #1
0
        //Good Game
        //Vector3 Snap (ABPath path, Exactness mode, bool start, out bool forceAddPoint) {
        VInt3 Snap(ABPath path, Exactness mode, bool start, out bool forceAddPoint)
        {
            var index = start ? 0 : path.path.Count - 1;
            var node  = path.path[index];
            //Good Game
            //var nodePos = (Vector3)node.position;
            var nodePos = node.position;

            forceAddPoint = false;

            switch (mode)
            {
            case Exactness.ClosestOnNode:
                return(start ? path.startPoint : path.endPoint);

            case Exactness.SnapToNode:
                return(nodePos);

            case Exactness.Original:
            case Exactness.Interpolate:
            case Exactness.NodeConnection:
                //Good Game
                //Vector3 relevantPoint;
                VInt3 relevantPoint;
                if (start)
                {
                    relevantPoint = adjustStartPoint != null?adjustStartPoint() : path.originalStartPoint;
                }
                else
                {
                    relevantPoint = path.originalEndPoint;
                }

                switch (mode)
                {
                case Exactness.Original:
                    return(GetClampedPoint(nodePos, relevantPoint, node));

                case Exactness.Interpolate:
                    // Adjacent node to either the start node or the end node in the path
                    var adjacentNode = path.path[Mathf.Clamp(index + (start ? 1 : -1), 0, path.path.Count - 1)];
                    //Good Game
                    //return VectorMath.ClosestPointOnSegment(nodePos, (Vector3)adjacentNode.position, relevantPoint);
                    return(IntMath.NearestPointStrict(nodePos, adjacentNode.position, relevantPoint));

                case Exactness.NodeConnection:
                    // This code uses some tricks to avoid allocations
                    // even though it uses delegates heavily
                    // The connectionBufferAddDelegate delegate simply adds whatever node
                    // it is called with to the connectionBuffer
                    connectionBuffer            = connectionBuffer ?? new List <GraphNode>();
                    connectionBufferAddDelegate = connectionBufferAddDelegate ?? (System.Action <GraphNode>)connectionBuffer.Add;

                    // Adjacent node to either the start node or the end node in the path
                    adjacentNode = path.path[Mathf.Clamp(index + (start ? 1 : -1), 0, path.path.Count - 1)];

                    // Add all neighbours of #node to the connectionBuffer
                    node.GetConnections(connectionBufferAddDelegate);
                    var bestPos  = nodePos;
                    var bestDist = float.PositiveInfinity;

                    // Loop through all neighbours
                    // Do it in reverse order because the length of the connectionBuffer
                    // will change during iteration
                    for (int i = connectionBuffer.Count - 1; i >= 0; i--)
                    {
                        var neighbour = connectionBuffer[i];

                        // Find the closest point on the connection between the nodes
                        // and check if the distance to that point is lower than the previous best
                        //Good Game
                        //var closest = VectorMath.ClosestPointOnSegment(nodePos, (Vector3)neighbour.position, relevantPoint);
                        var closest = IntMath.NearestPointStrict(nodePos, neighbour.position, relevantPoint);

                        var dist = (closest - relevantPoint).sqrMagnitude;
                        if (dist < bestDist)
                        {
                            bestPos  = closest;
                            bestDist = dist;

                            // If this node is not the adjacent node
                            // then the path should go through the start node as well
                            forceAddPoint = neighbour != adjacentNode;
                        }
                    }

                    connectionBuffer.Clear();
                    return(bestPos);

                default:
                    throw new System.ArgumentException("Cannot reach this point, but the compiler is not smart enough to realize that.");
                }

            default:
                throw new System.ArgumentException("Invalid mode");
            }
        }