示例#1
0
        Vector3 calculate(float percentage)
        {
            var low  = 0;
            var high = points.Length - 2;

            while (low < high)
            {
                var mid = (low + high) / 2;
                if (points[mid + 1].percentageOfPathTraveled < percentage)
                {
                    low = mid + 1;
                }
                else
                {
                    high = mid;
                }
            }

            var segmentPercentage =
                (percentage - points[low].percentageOfPathTraveled)
                / (points[low + 1].percentageOfPathTraveled - points[low].percentageOfPathTraveled);

            switch (method)
            {
            case InterpolationMethod.Linear:
                return(Vector3.Lerp(
                           points[low].point, points[low + 1].point,
                           segmentPercentage
                           ));

            case InterpolationMethod.Cubic:
                return(InterpolationUtils.cubicGetPt(
                           idx => points[idx].point, points.Length, low,
                           segmentPercentage,
                           closed
                           ));

            case InterpolationMethod.Hermite:
                return(InterpolationUtils.hermiteGetPt(
                           idx => points[idx].point, points.Length, low,
                           segmentPercentage,
                           closed
                           ));

            case InterpolationMethod.CatmullRom:
                return(InterpolationUtils.catmullRomGetPt(
                           idx => points[idx].point, points.Length, low,
                           segmentPercentage,
                           closed
                           ));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#2
0
        public Vector3Path(
            InterpolationMethod method, bool closed, ImmutableArray <Vector3> positions, Option <Transform> relativeTo,
            int pathResolution
            )
        {
            this.method     = method;
            this.closed     = closed;
            this.relativeTo = relativeTo;
            resolution      = pathResolution;
            points          = segmentLengthRatios();

            //Distance to the last node is the whole path distance
            realLength         = points[points.Length - 1].realDistanceToThisPoint;
            constantSpeedTable = new ConstantSpeedTable(resolution, calculate);

            // Returns list of Points with Vector3 coordinates,
            // length and segment length ratios added to prev element ratio and
            // distance from the start to this point
            ImmutableArray <Point> segmentLengthRatios()
            {
                switch (method)
                {
                case InterpolationMethod.Linear: {
                    var builder = ImmutableArray.CreateBuilder <Point>(positions.Length);
                    var length  = positions.Aggregate(0f, (node, current, idx) =>
                                                      idx == 0
                ? current
                : current + Vector3.Distance(positions[idx - 1], node)
                                                      );
                    builder.Add(new Point(positions[0], 0f, 0f));
                    for (var idx = 1; idx < positions.Length; idx++)
                    {
                        var distanceBetweenPositions = Vector3.Distance(positions[idx - 1], positions[idx]);
                        var previousPoint            = builder[idx - 1];
                        builder.Add(new Point(
                                        positions[idx],
                                        distanceBetweenPositions / length + previousPoint.percentageOfPathTraveled,
                                        distanceBetweenPositions + previousPoint.realDistanceToThisPoint
                                        ));
                    }

                    return(builder.MoveToImmutable());
                }

                case InterpolationMethod.Hermite: {
                    return(getSegmentRatios(
                               positions,
                               (segmentIndex, percentageOfPath) => InterpolationUtils.hermiteGetPt(
                                   idx => positions[idx], positions.Length, segmentIndex, percentageOfPath, closed
                                   )));
                }

                case InterpolationMethod.Cubic: {
                    return(getSegmentRatios(
                               positions,
                               (segmentIndex, percentageOfPath) => InterpolationUtils.cubicGetPt(
                                   idx => positions[idx], positions.Length, segmentIndex, percentageOfPath, closed
                                   )));
                }

                case InterpolationMethod.CatmullRom: {
                    return(getSegmentRatios(
                               positions,
                               (segmentIndex, percentageOfPath) => InterpolationUtils.catmullRomGetPt(
                                   idx => positions[idx], positions.Length, segmentIndex, percentageOfPath, closed
                                   )));
                }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }