/// <summary>
        /// Converts a distance to a TF value
        /// </summary>
        /// <param name="distance">distance in the range 0..Length</param>
        /// <param name="clamping">Clamping to use</param>
        /// <returns>a TF value in the range 0..1</returns>
        public override float DistanceToTF(float distance, CurvyClamping clamping)
        {
            float       localDistance;
            CurvySpline spl = DistanceToSpline(distance, out localDistance, clamping);

            return((spl) ? SplineToTF(spl, spl.DistanceToTF(localDistance)) : 0);
        }
        /// <summary>
        /// Gets the segment and the local F for a certain TF
        /// </summary>
        /// <param name="tf">the TF value in the range 0..1</param>
        /// <param name="localF">gets the remaining localF in the range 0..1</param>
        /// <param name="clamping">Clamping to use</param>
        /// <returns>the segment the given TF is inside</returns>
        public override CurvySplineSegment TFToSegment(float tf, out float localF, CurvyClamping clamping)
        {
            float localTF;

            localF = 0;
            int idx = TFToSplineIndex(tf, out localTF, clamping);

            return((idx == -1) ? null : this[idx].TFToSegment(localTF, out localF));
        }
        /// <summary>
        /// Converts a group TF value to a group distance
        /// </summary>
        /// <param name="tf">a TF value in the range 0..1</param>
        /// <param name="clamping">Clamping to use</param>
        /// <returns>distance from the first spline's first segment's Control Point</returns>
        public override float TFToDistance(float tf, CurvyClamping clamping)
        {
            if (Count == 0)
            {
                return(0);
            }
            float localTF;
            int   idx = TFToSplineIndex(tf, out localTF);

            return(Distances[idx] + this[idx].TFToDistance(localTF));
        }
Beispiel #4
0
 /// <summary>
 /// Clamps relative position
 /// </summary>
 public static float ClampTF(float tf, CurvyClamping clamping)
 {
     switch (clamping)
     {
         case CurvyClamping.Loop:
             return Mathf.Repeat(tf, 1);
         case CurvyClamping.PingPong:
             return Mathf.PingPong(tf, 1);
         default:
             return Mathf.Clamp01(tf);
     }
 }
Beispiel #5
0
    /// <summary>
    /// Alter TF to move until the curvation reached angle.
    /// </summary>
    /// <param name="tf">the current TF value</param>
    /// <param name="direction">the current direction, 1 or -1</param>
    /// <param name="angle">the angle in degrees</param>
    /// <param name="clamping">the clamping mode. CurvyClamping.PingPong isn't supported!</param>
    /// <param name="stepSize">stepSize defines the accuracy</param>
    /// <returns>the interpolated position</returns>
    public virtual Vector3 MoveByAngle(ref float tf, ref int direction, float angle, CurvyClamping clamping, float stepSize)
    {
        if (clamping == CurvyClamping.PingPong)
        {
            Debug.LogError("CurvySplineBase.MoveByAngle: PingPong clamping isn't supported!");
            return(Vector3.zero);
        }
        stepSize = Mathf.Max(0.0001f, stepSize);
        float   initialTF = tf;
        Vector3 initialP  = Interpolate(tf);
        Vector3 initialT  = GetTangent(tf, initialP);
        Vector3 P2        = Vector3.zero;
        Vector3 T2;
        int     deadlock = 10000;

        while (deadlock-- > 0)
        {
            tf += stepSize * direction;
            if (tf > 1)
            {
                if (clamping == CurvyClamping.Loop)
                {
                    tf -= 1;
                }
                else
                {
                    tf = 1;
                    return(Interpolate(1));
                }
            }
            else if (tf < 0)
            {
                if (clamping == CurvyClamping.Loop)
                {
                    tf += 1;
                }
                else
                {
                    tf = 0;
                    return(Interpolate(0));
                }
            }
            P2 = Interpolate(tf);
            T2 = P2 - initialP;
            float accAngle = Vector3.Angle(initialT, T2);
            if (accAngle >= angle)
            {
                tf = initialTF + (tf - initialTF) * angle / accAngle;
                return(Interpolate(tf));
            }
        }
        return(P2);
    }
Beispiel #6
0
        /// <summary>
        /// Clamps relative position
        /// </summary>
        public static float ClampTF(float tf, CurvyClamping clamping)
        {
            switch (clamping)
            {
            case CurvyClamping.Loop:
                return(Mathf.Repeat(tf, 1));

            case CurvyClamping.PingPong:
                return(Mathf.PingPong(tf, 1));

            default:
                return(Mathf.Clamp01(tf));
            }
        }
Beispiel #7
0
 /// <summary>
 /// Clamps relative position and sets new direction
 /// </summary>
 public static float ClampTF(float tf, ref int dir, CurvyClamping clamping)
 {
     switch (clamping)
     {
         case CurvyClamping.Loop:
             return Mathf.Repeat(tf, 1);
         case CurvyClamping.PingPong:
             if (Mathf.FloorToInt(tf) % 2 != 0)
                 dir *= -1;
             return Mathf.PingPong(tf, 1);
         default:
             return Mathf.Clamp01(tf);
     }
 }
Beispiel #8
0
 public override void Reset()
 {
     base.Reset();
     GameObject     = null;
     Spline         = null;
     SetOrientation = true;
     UseCache       = false;
     Position       = 0;
     Space          = Space.World;
     PositionMode   = CurvyPositionMode.Relative;
     Clamping       = CurvyClamping.Clamp;
     everyFrame     = false;
     updateType     = PlayMakerActionsUtils.EveryFrameUpdateSelector.OnUpdate;
 }
Beispiel #9
0
 /// <summary>
 /// Clamps a float to a range
 /// </summary>
 public static float ClampValue(float tf, CurvyClamping clamping, float minTF, float maxTF)
 {
     
     switch (clamping)
     {
         case CurvyClamping.Loop:
             float v1 = DTMath.MapValue(0, 1, tf, minTF, maxTF);
             return DTMath.MapValue(minTF,maxTF,Mathf.Repeat(v1, 1),0,1);
         case CurvyClamping.PingPong:
             float v2 = DTMath.MapValue(0, 1, tf, minTF, maxTF);
             return DTMath.MapValue(minTF,maxTF,Mathf.PingPong(v2, 1),0,1);
         default:
             return Mathf.Clamp(tf, minTF, maxTF);
     }
 }
Beispiel #10
0
        /// <summary>
        /// Clamps a float to a range
        /// </summary>
        public static float ClampValue(float tf, CurvyClamping clamping, float minTF, float maxTF)
        {
            switch (clamping)
            {
            case CurvyClamping.Loop:
                float v1 = DTMath.MapValue(0, 1, tf, minTF, maxTF);
                return(DTMath.MapValue(minTF, maxTF, Mathf.Repeat(v1, 1), 0, 1));

            case CurvyClamping.PingPong:
                float v2 = DTMath.MapValue(0, 1, tf, minTF, maxTF);
                return(DTMath.MapValue(minTF, maxTF, Mathf.PingPong(v2, 1), 0, 1));

            default:
                return(Mathf.Clamp(tf, minTF, maxTF));
            }
        }
        /// <summary>
        /// Gets the spline a certain distance lies within
        /// </summary>
        /// <param name="distance">a distance in the range 0..Length</param>
        /// <param name="localDistance">gets the remaining distance inside the spline</param>
        /// <param name="clamping">Clamping to use</param>
        /// <returns>a spline or null</returns>
        public CurvySpline DistanceToSpline(float distance, out float localDistance, CurvyClamping clamping = CurvyClamping.Clamp)
        {
            distance      = CurvyUtility.ClampDistance(distance, clamping, Length);
            localDistance = 0;

            for (int i = 1; i < Count; i++)
            {
                if (Distances[i] >= distance)
                {
                    localDistance = distance - Distances[i - 1];
                    return(this[i - 1]);
                }
            }
            localDistance = distance - Distances[Count - 1];
            return(this[Count - 1]);
        }
Beispiel #12
0
        /// <summary>
        /// Clamps relative position and sets new direction
        /// </summary>
        public static float ClampTF(float tf, ref int dir, CurvyClamping clamping, float minTF, float maxTF)
        {
            minTF = Mathf.Clamp01(minTF);
            maxTF = Mathf.Clamp(maxTF, minTF, 1);

            switch (clamping)
            {
                case CurvyClamping.Loop:
                    return minTF + Mathf.Repeat(tf, maxTF - minTF);
                case CurvyClamping.PingPong:
                    if (Mathf.FloorToInt(tf / (maxTF - minTF)) % 2 != 0)
                        dir *= -1;
                    return minTF + Mathf.PingPong(tf, maxTF - minTF);
                default:
                    return Mathf.Clamp(tf, minTF, maxTF);
            }
        }
Beispiel #13
0
        /// <summary>
        /// Clamps absolute position
        /// </summary>
        public static float ClampDistance(float distance, CurvyClamping clamping, float length)
        {
            if (length == 0)
            {
                return(0);
            }
            switch (clamping)
            {
            case CurvyClamping.Loop:
                return(Mathf.Repeat(distance, length));

            case CurvyClamping.PingPong:
                return(Mathf.PingPong(distance, length));

            default:
                return(Mathf.Clamp(distance, 0, length));
            }
        }
 protected override void Advance(ref float tf, ref int direction, CurvyController.MoveModeEnum mode, float absSpeed, CurvyClamping clamping)
 {
     base.Advance(ref tf, ref direction, mode, absSpeed, clamping);
     // Get directional vector    
     var tan = GetTangent(tf);
     float acc;
     // accelerate when going down, deccelerate when going up
     if (tan.y < 0)
         acc = Down * tan.y * Fric;
     else
         acc = Up * -tan.y * Fric;
     
     // alter speed
     Speed = Mathf.Clamp(Speed + Mass * acc * DeltaTime,MinSpeed,MaxSpeed);
     // stop at spline's end
     if (tf == 1)
         Speed = 0;
 }
Beispiel #15
0
        /// <summary>
        /// Clamps relative position and sets new direction
        /// </summary>
        public static float ClampTF(float tf, ref int dir, CurvyClamping clamping)
        {
            switch (clamping)
            {
            case CurvyClamping.Loop:
                return(Mathf.Repeat(tf, 1));

            case CurvyClamping.PingPong:
                if (Mathf.FloorToInt(tf) % 2 != 0)
                {
                    dir *= -1;
                }
                return(Mathf.PingPong(tf, 1));

            default:
                return(Mathf.Clamp01(tf));
            }
        }
        int TFToSplineIndex(float tf, out float localTF, CurvyClamping clamping = CurvyClamping.Clamp)
        {
            tf      = CurvyUtility.ClampTF(tf, clamping);
            localTF = 0;
            if (Count == 0)
            {
                return(-1);
            }
            float f   = tf * Count;
            int   idx = (int)f;

            localTF = f - idx;
            if (idx == Count)
            {
                idx--; localTF = 1;
            }

            return(idx);
        }
Beispiel #17
0
        /// <summary>
        /// Clamps absolute position
        /// </summary>
        public static float ClampDistance(float distance, CurvyClamping clamping, float length, float min, float max)
        {
            if (length == 0)
            {
                return(0);
            }
            min = Mathf.Clamp(min, 0, length);
            max = Mathf.Clamp(max, min, length);
            switch (clamping)
            {
            case CurvyClamping.Loop:
                return(min + Mathf.Repeat(distance, max - min));

            case CurvyClamping.PingPong:
                return(min + Mathf.PingPong(distance, max - min));

            default:
                return(Mathf.Clamp(distance, min, max));
            }
        }
Beispiel #18
0
        /// <summary>
        /// Clamps relative position and sets new direction
        /// </summary>
        public static float ClampTF(float tf, ref int dir, CurvyClamping clamping, float minTF, float maxTF)
        {
            minTF = Mathf.Clamp01(minTF);
            maxTF = Mathf.Clamp(maxTF, minTF, 1);

            switch (clamping)
            {
            case CurvyClamping.Loop:
                return(minTF + Mathf.Repeat(tf, maxTF - minTF));

            case CurvyClamping.PingPong:
                if (Mathf.FloorToInt(tf / (maxTF - minTF)) % 2 != 0)
                {
                    dir *= -1;
                }
                return(minTF + Mathf.PingPong(tf, maxTF - minTF));

            default:
                return(Mathf.Clamp(tf, minTF, maxTF));
            }
        }
Beispiel #19
0
        /// <summary>
        /// Clamps absolute position and sets new direction
        /// </summary>
        public static float ClampDistance(float distance, ref int dir, CurvyClamping clamping, float length)
        {
            if (length == 0)
            {
                return(0);
            }
            switch (clamping)
            {
            case CurvyClamping.Loop:
                return(Mathf.Repeat(distance, length));

            case CurvyClamping.PingPong:
                if (Mathf.FloorToInt(distance / length) % 2 != 0)
                {
                    dir *= -1;
                }
                return(Mathf.PingPong(distance, length));

            default:
                return(Mathf.Clamp(distance, 0, length));
            }
        }
Beispiel #20
0
    /*! \cond PRIVATE */

    /*! @name Internal Public
     *  Don't use them unless you know what you're doing!
     */
    //@{

    protected virtual bool ClampTF(ref float tf, ref int dir, CurvyClamping clamping)
    {
        switch (clamping)
        {
        case CurvyClamping.Loop:
            if (tf < 0)
            {
                tf = 1 - Mathf.Abs(tf % 1);
                return(true);
            }
            else if (tf > 1)
            {
                tf = tf % 1;
                return(true);
            }
            break;

        case CurvyClamping.PingPong:
            if (tf < 0)
            {
                tf   = (tf % 1) * -1;
                dir *= -1;
                return(true);
            }
            else if (tf > 1)
            {
                tf   = 1 - tf % 1;
                dir *= -1;
                return(true);
            }
            break;

        default:     // Clamp
            tf = Mathf.Clamp01(tf);
            break;
        }
        return(false);
    }
 /// <summary>
 /// Advance the controller and return the new position
 /// </summary>
 /// <param name="virtualPosition">the current virtual position (either TF or World Units) </param>
 /// <param name="direction">the current direction</param>
 /// <param name="mode">movement mode</param>
 /// <param name="absSpeed">speed, always positive</param>
 /// <param name="clamping">clamping mode</param>
 protected override void Advance(ref float virtualPosition, ref int direction, MoveModeEnum mode, float absSpeed, CurvyClamping clamping)
 {
     switch (mode)
     {
         case MoveModeEnum.Relative:
             VolumeData.Move(ref virtualPosition, ref direction, absSpeed, clamping);
             break;
         default:
             VolumeData.MoveBy(ref virtualPosition, ref direction, absSpeed, clamping);
             break;
     }
 }
Beispiel #22
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain distance. Unlike MoveBy, a linear approximation will be used
 /// </summary>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="distance">the distance in world units to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <returns>the interpolated position</returns>
 public virtual Vector3 MoveByFast(ref float tf, ref int direction, float distance, CurvyClamping clamping)
 {
     return(MoveByFast(ref tf, ref direction, distance, clamping, 0.002f));
 }
Beispiel #23
0
        /// <summary>
        /// Alter TF to reflect a movement over a certain distance.
        /// </summary>
        /// <remarks>MoveByLengthFast works by using actual lengths</remarks>
        /// <param name="tf">the current TF value</param>
        /// <param name="direction">the current direction, 1 or -1</param>
        /// <param name="distance">the distance in world units to move</param>
        /// <param name="clamping">clamping mode</param>
        /// <returns>the interpolated position</returns>
        public virtual Vector3 MoveByLengthFast(ref float tf, ref int direction, float distance, CurvyClamping clamping)
        {
            float dist = ClampDistance(TFToDistance(tf) + distance * direction, ref direction, clamping);

            tf = DistanceToTF(dist);
            return(InterpolateFast(tf));
        }
        /// <summary>
        /// Advance the controller and return the new position
        /// </summary>
        /// <param name="tf">the current virtual position (either TF or World Units)</param>
        /// <param name="direction">the current direction</param>
        /// <param name="mode">movement mode</param>
        /// <param name="absSpeed">speed, always positive</param>
        /// <param name="clamping">clamping mode</param>
        protected override void Advance(ref float tf, ref int direction, MoveModeEnum mode, float absSpeed, CurvyClamping clamping)
        {
            _active = this;
            switch (mode)
            {
                case MoveModeEnum.AbsoluteExtrapolate:
                    if (UseCache)
                    {
                        Spline.MoveByFast(ref tf, ref direction, absSpeed, Clamping);
                        if (IsSwitching)
                        {
                            mSwitchEventArgs.Spline.MoveByFast(ref mSwitchEventArgs.TF, ref mSwitchEventArgs.Direction, absSpeed, Clamping);
                            onSwitchEvent(mSwitchEventArgs);
                        }
                    }
                    else
                    {
                        Spline.MoveBy(ref tf, ref direction, absSpeed, Clamping);
                        if (IsSwitching)
                        {
                            mSwitchEventArgs.Spline.MoveBy(ref mSwitchEventArgs.TF, ref mSwitchEventArgs.Direction, absSpeed, Clamping);
                            onSwitchEvent(mSwitchEventArgs);
                        }
                    }
                    break;
                case MoveModeEnum.AbsolutePrecise:
                    Spline.MoveByLengthFast(ref tf, ref direction, absSpeed, Clamping);
                    if (IsSwitching)
                    {
                        mSwitchEventArgs.Spline.MoveByLengthFast(ref mSwitchEventArgs.TF, ref mSwitchEventArgs.Direction, absSpeed, Clamping);
                        onSwitchEvent(mSwitchEventArgs);
                    }
                    break;
                default: // Relative
                    if (UseCache)
                    {
                        Spline.MoveFast(ref tf, ref direction, absSpeed, Clamping);
                        if (IsSwitching)
                        {
                            mSwitchEventArgs.Spline.MoveFast(ref mSwitchEventArgs.TF, ref mSwitchEventArgs.Direction, absSpeed, Clamping);
                            onSwitchEvent(mSwitchEventArgs);
                        }
                    }
                    else
                    {
                        Spline.Move(ref tf, ref direction, absSpeed, Clamping);
                        if (IsSwitching)
                        {
                            mSwitchEventArgs.Spline.Move(ref mSwitchEventArgs.TF, ref mSwitchEventArgs.Direction, absSpeed, Clamping);
                            onSwitchEvent(mSwitchEventArgs);
                        }
                    }
                    break;
            }
            _active = null;

        }
Beispiel #25
0
 /// <summary>
 /// Converts a distance to a TF value
 /// </summary>
 /// <param name="distance">distance</param>
 /// <param name="clamping">Clamping to use</param>
 /// <returns>a TF value in the range 0..1</returns>
 public virtual float DistanceToTF(float distance, CurvyClamping clamping)
 {
     return(0);
 }
Beispiel #26
0
        /// <summary>
        /// Gets the segment for a certain TF
        /// </summary>
        /// <param name="tf">the TF value</param>
        /// <param name="clamping">Clamping to use</param>
        /// <returns>the segment the given TF is inside</returns>
        public CurvySplineSegment TFToSegment(float tf, CurvyClamping clamping)
        {
            float f;

            return(TFToSegment(tf, out f, clamping));
        }
Beispiel #27
0
 /// <summary>
 /// Clamps absolute position
 /// </summary>
 public static float ClampDistance(float distance, CurvyClamping clamping, float length)
 {
     if (length == 0)
         return 0;
     switch (clamping)
     {
         case CurvyClamping.Loop:
             return Mathf.Repeat(distance, length);
         case CurvyClamping.PingPong:
             return Mathf.PingPong(distance, length);
         default:
             return Mathf.Clamp(distance, 0, length);
     }
 }
 bool ClampTF(ref float tf, ref int dir, CurvyClamping clamping)
 {
     switch (clamping) {
         case CurvyClamping.Loop:
             if (tf < 0) {
                 tf = 1 - tf;
                 return true;
             }
             else if (tf > 1) {
                 tf -= 1;
                 return true;
             }
             break;
         case CurvyClamping.PingPong:
             if (tf < 0) {
                 tf *= -1;
                 dir *= -1;
                 return true;
             }
             else if (tf > 1) {
                 tf = 2 - tf;
                 dir *= -1;
                 return true;
             }
             break;
         default: // Clamp
             tf = Mathf.Clamp01(tf);
             break;
     }
     return false;
 }
 /// <summary>
 /// Alter TF to move until the curvation reached angle. Unlike MoveByAngle, a linear approximation will be used
 /// </summary>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="angle">the angle in degrees</param>
 /// <param name="clamping">the clamping mode. CurvyClamping.PingPong isn't supported!</param>
 /// <param name="stepSize">stepSize defines the accuracy</param>
 /// <returns>the interpolated position</returns>
 public Vector3 MoveByAngleFast(ref float tf, ref int direction, float angle, CurvyClamping clamping, float stepSize)
 {
     if (clamping == CurvyClamping.PingPong) {
         Debug.LogError("CurvySpline.MoveByAngle: PingPong clamping isn't supported!");
         return Vector3.zero;
     }
     stepSize = Mathf.Max(0.0001f, stepSize);
     Vector3 initialP = InterpolateFast(tf);
     Vector3 initialT = GetTangentFast(tf);
     Vector3 P2 = Vector3.zero;
     Vector3 T2;
     int deadlock = 10000;
     while (deadlock-- > 0) {
         tf += stepSize * direction;
         if (tf > 1) {
             if (clamping == CurvyClamping.Loop)
                 tf -= 1;
             else {
                 tf = 1;
                 return InterpolateFast(1);
             }
         }
         else if (tf < 0) {
             if (clamping == CurvyClamping.Loop)
                 tf += 1;
             else {
                 tf = 0;
                 return InterpolateFast(0);
             }
         }
         P2 = InterpolateFast(tf);
         T2 = P2 - initialP;
         if (Vector3.Angle(initialT, T2) >= angle)
             return P2;
     }
     return P2;
 }
    /// <summary>
    /// Alter TF to move until the curvation reached angle.
    /// </summary>
    /// <param name="tf">the current TF value</param>
    /// <param name="direction">the current direction, 1 or -1</param>
    /// <param name="angle">the angle in degrees</param>
    /// <param name="clamping">the clamping mode. CurvyClamping.PingPong isn't supported!</param>
    /// <param name="stepSize">stepSize defines the accuracy</param>
    /// <returns>the interpolated position</returns>
    public virtual Vector3 MoveByAngle(ref float tf, ref int direction, float angle, CurvyClamping clamping, float stepSize)
    {
        if (clamping == CurvyClamping.PingPong) {
            Debug.LogError("CurvySplineBase.MoveByAngle: PingPong clamping isn't supported!");
            return Vector3.zero;
        }
        stepSize = Mathf.Max(0.0001f, stepSize);
        float initialTF = tf;
        Vector3 initialP = Interpolate(tf);
        Vector3 initialT = GetTangent(tf, initialP);
        Vector3 P2 = Vector3.zero;
        Vector3 T2;
        int deadlock = 10000;
        while (deadlock-- > 0) {
            tf += stepSize * direction;
            if (tf > 1) {
                if (clamping == CurvyClamping.Loop)
                    tf -= 1;
                else {
                    tf = 1;
                    return Interpolate(1);
                }
            }
            else if (tf < 0) {
                if (clamping == CurvyClamping.Loop)
                    tf += 1;
                else {
                    tf = 0;
                    return Interpolate(0);
                }
            }
            P2 = Interpolate(tf);
            T2 = P2 - initialP;
            float accAngle = Vector3.Angle(initialT, T2);
            if (accAngle >= angle) {
                tf = initialTF + (tf - initialTF) * angle / accAngle;
                return Interpolate(tf);
            }
        }
        return P2;

    }
    /// <summary>
    /// Alter TF to reflect a movement over a certain distance. Unlike MoveBy, a linear approximation will be used
    /// </summary>
    /// <param name="tf">the current TF value</param>
    /// <param name="direction">the current direction, 1 or -1</param>
    /// <param name="distance">the distance in world units to move</param>
    /// <param name="clamping">clamping mode</param>
    /// <param name="stepSize">stepSize defines the accuracy</param>
    /// <returns>the interpolated position</returns>
    public Vector3 MoveByFast(ref float tf, ref int direction, float distance, CurvyClamping clamping, float stepSize)
    {
        stepSize = Mathf.Max(0.0001f, stepSize);
        Vector3 p = InterpolateFast(tf);
        if (Mathf.Approximately(distance, 0)) return p;
        float tf1 = tf + stepSize * direction;

        // Handle Clamping when end of spline is reached
        if (tf1 < 0) {
            float magpart;
            switch (clamping) {
                case CurvyClamping.Clamp:
                    tf = 0;
                    return InterpolateFast(0);
                case CurvyClamping.PingPong:
                    magpart = (Interpolate(0) - p).magnitude;
                    direction *= -1;
                    tf = 0;
                    return MoveByFast(ref tf, ref direction, distance - magpart, clamping);
                case CurvyClamping.Loop:
                    magpart = (Interpolate(0) - p).magnitude;
                    tf = 1;
                    return MoveByFast(ref tf, ref direction, distance - magpart, clamping);
            }

        }
        else if (tf1 > 1) {
            float magpart;
            switch (clamping) {
                case CurvyClamping.Clamp:
                    tf = 1;
                    return InterpolateFast(1);
                case CurvyClamping.PingPong:
                    magpart = (InterpolateFast(1) - p).magnitude;
                    direction *= -1;
                    tf = 1;
                    return MoveByFast(ref tf, ref direction, distance - magpart, clamping);
                case CurvyClamping.Loop:
                    magpart = (InterpolateFast(1) - p).magnitude;
                    tf = 0;
                    return MoveByFast(ref tf, ref direction, distance - magpart, clamping);

            }
        }
        // inside spline, calculate normal
        Vector3 p1 = InterpolateFast(tf1);
        float mag = (p1 - p).magnitude;
        if (mag != 0)
            tf += (1 / mag) * stepSize * distance * direction;

        return InterpolateFast(tf);
    }
 /// <summary>
 /// Alter TF to reflect a movement over a certain distance. Unlike MoveBy, a linear approximation will be used
 /// </summary>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="distance">the distance in world units to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <returns>the interpolated position</returns>
 public Vector3 MoveByFast(ref float tf, ref int direction, float distance, CurvyClamping clamping)
 {
     return MoveByFast(ref tf, ref direction, distance, clamping, 0.002f);
 }
 /// <summary>
 /// Alter TF to reflect a movement over a certain portion of the spline, respecting Clamping. Unlike Move() a linear approximation will be used
 /// </summary>
 /// <remarks>fDistance relates to the total spline, so longer splines will result in faster movement for constant fDistance</remarks>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="fDistance">the percentage of the spline to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <returns>the interpolated position</returns>
 public Vector3 MoveFast(ref float tf, ref int direction, float fDistance, CurvyClamping clamping)
 {
     tf += fDistance * direction;
     ClampTF(ref tf, ref direction,clamping);
     return InterpolateFast(tf);
 }
Beispiel #34
0
    /// <summary>
    /// Alter TF to reflect a movement over a certain distance.
    /// </summary>
    /// <remarks>MoveByLengthFast works by using actual lengths</remarks>
    /// <param name="tf">the current TF value</param>
    /// <param name="direction">the current direction, 1 or -1</param>
    /// <param name="distance">the distance in world units to move</param>
    /// <param name="clamping">clamping mode</param>
    /// <returns>the interpolated position</returns>
    public virtual Vector3 MoveByLengthFast(ref float tf, ref int direction, float distance, CurvyClamping clamping)
    {
        float dist    = TFToDistance(tf);
        float delta   = (clamping != CurvyClamping.Clamp) ? (distance % Length) * direction : distance * direction;
        float newDist = dist + delta;

        if (newDist > Length || newDist < 0)
        {
            switch (clamping)
            {
            case CurvyClamping.Clamp:
                tf = (delta < 0) ? 0 : 1;
                break;

            case CurvyClamping.PingPong:
                if (delta < 0)
                {
                    newDist *= -1;
                }
                else
                {
                    newDist -= delta - Length;
                }
                direction *= -1;
                tf         = DistanceToTF(newDist);
                break;

            case CurvyClamping.Loop:
                if (newDist < 0)
                {
                    newDist += Length;
                }
                else
                {
                    newDist -= Length;
                }
                tf = DistanceToTF(newDist);
                break;
            }
        }
        else
        {
            tf = DistanceToTF(newDist);
        }

        return(InterpolateFast(tf));
    }
    /// <summary>
    /// Alter TF to reflect a movement over a certain distance.
    /// </summary>
    /// <remarks>MoveByLengthFast works by using actual lengths</remarks>
    /// <param name="tf">the current TF value</param>
    /// <param name="direction">the current direction, 1 or -1</param>
    /// <param name="distance">the distance in world units to move</param>
    /// <param name="clamping">clamping mode</param>
    /// <returns>the interpolated position</returns>
    public virtual Vector3 MoveByLengthFast(ref float tf, ref int direction, float distance, CurvyClamping clamping)
    {
        float dist = TFToDistance(tf);
        float delta = (clamping != CurvyClamping.Clamp) ? (distance % Length) * direction : distance * direction;
        float newDist = dist + delta;
        if (newDist > Length || newDist < 0) {
            switch (clamping) {
                case CurvyClamping.Clamp:
                    tf = (delta < 0) ? 0 : 1;
                    break;
                case CurvyClamping.PingPong:
                    if (delta < 0)
                        newDist *= -1;
                    else
                        newDist -= delta - Length;
                    direction *= -1;
                    tf = DistanceToTF(newDist);
                    break;
                case CurvyClamping.Loop:
                    if (newDist < 0)
                        newDist += Length;
                    else
                        newDist -= Length;
                    tf = DistanceToTF(newDist);
                    break;
            }
        }
        else
            tf = DistanceToTF(newDist);

        return InterpolateFast(tf);
    }
Beispiel #36
0
 /// <summary>
 /// Clamps absolute position and sets new direction
 /// </summary>
 public static float ClampDistance(float distance, ref int dir, CurvyClamping clamping, float length)
 {
     if (length == 0)
         return 0;
     switch (clamping)
     {
         case CurvyClamping.Loop:
             return Mathf.Repeat(distance, length);
         case CurvyClamping.PingPong:
             if (Mathf.FloorToInt(distance / length) % 2 != 0)
                 dir *= -1;
             return Mathf.PingPong(distance, length);
         default:
             return Mathf.Clamp(distance, 0, length);
     }
 }
 /// <summary>
 /// Alter TF to reflect a movement over a certain distance. Unlike MoveBy, a linear approximation will be used
 /// </summary>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="distance">the distance in world units to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <param name="stepSize">stepSize defines the accuracy</param>
 /// <returns>the interpolated position</returns>
 public virtual Vector3 MoveByFast(ref float tf, ref int direction, float distance, CurvyClamping clamping, float stepSize)
 {
     return MoveFast(ref tf, ref direction, ExtrapolateDistanceToTFFast(tf, distance, stepSize), clamping);
 }
Beispiel #38
0
 /// <summary>
 /// Converts a TF value to a distance
 /// </summary>
 /// <param name="tf">a TF value</param>
 /// <param name="clamping">Clamping to use</param>
 /// <returns>distance from the first segment's Control Point</returns>
 public virtual float TFToDistance(float tf, CurvyClamping clamping)
 {
     return(0);
 }
 /// <summary>
 /// Advance the controller and return the new position
 /// </summary>
 /// <param name="tf">the current virtual position (either TF or World Units) </param>
 /// <param name="direction">the current direction</param>
 /// <param name="mode">movement mode</param>
 /// <param name="absSpeed">speed, always positive</param>
 /// <param name="clamping">clamping mode</param>
 protected virtual void Advance(ref float tf, ref int direction, MoveModeEnum mode, float absSpeed, CurvyClamping clamping)
 {
 }
Beispiel #40
0
 /// <summary>
 /// Gets the segment and the local F for a certain TF
 /// </summary>
 /// <param name="tf">the TF value</param>
 /// <param name="localF">gets the remaining localF in the range 0..1</param>
 /// <param name="clamping">Clamping to use</param>
 /// <returns>the segment the given TF is inside</returns>
 public virtual CurvySplineSegment TFToSegment(float tf, out float localF, CurvyClamping clamping)
 {
     localF = 0; return(null);
 }
Beispiel #41
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain distance.
 /// </summary>
 /// <remarks>MoveByLengthFast is used internally, so stepSize is ignored</remarks>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="distance">the distance in world units to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <param name="stepSize">stepSize defines the accuracy</param>
 /// <returns>the interpolated position</returns>
 public override Vector3 MoveByFast(ref float tf, ref int direction, float distance, CurvyClamping clamping, float stepSize)
 {
     return MoveByLengthFast(ref tf, ref direction, distance, clamping);
 }
Beispiel #42
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain portion of the spline/group
 /// </summary>
 /// <remarks>fDistance relates to the total spline, so longer splines will result in faster movement for constant fDistance</remarks>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="fDistance">the percentage of the spline/group to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <returns>the interpolated position</returns>
 public virtual Vector3 Move(ref float tf, ref int direction, float fDistance, CurvyClamping clamping)
 {
     tf = CurvyUtility.ClampTF(tf + fDistance * direction, ref direction, clamping);
     return(Interpolate(tf));
 }
Beispiel #43
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain distance using a default stepSize of 0.002, using connections if conditions match.
 /// Unlike MoveByConnection() a linear approximation will be used.
 /// </summary>
 /// <param name="spline">the current spline</param>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="distance">the distance in world units to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <param name="minMatchesNeeded">minimum number of tags that must match to use a connection</param>
 /// <param name="tags">list of tags to match</param>
 /// <returns>the interpolated position</returns>
 public Vector3 MoveByConnectionFast(ref CurvySpline spline, ref float tf, ref int direction, float distance, CurvyClamping clamping, int minMatchesNeeded, params string[] tags)
 {
     return MoveByConnectionFast(ref spline, ref tf, ref direction, distance, clamping, minMatchesNeeded, 0.002f, tags);
 }
Beispiel #44
0
        /// <summary>
        /// Advances the specified virtual position.
        /// </summary>
        /// <param name="virtualPosition">The virtual position.</param>
        /// <param name="direction">The direction.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="absSpeed">The abs speed.</param>
        /// <param name="clamping">The clamping.</param>
        protected override void Advance(ref float virtualPosition, ref int direction, MoveModeEnum mode, float absSpeed, CurvyClamping clamping)
        {
            switch (mode)
            {
            case MoveModeEnum.Relative:
                PathData.Move(ref virtualPosition, ref direction, absSpeed, clamping);
                break;

            default:
                PathData.MoveBy(ref virtualPosition, ref direction, absSpeed, clamping);
                break;
            }
        }
Beispiel #45
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain distance, using connections if conditions match. Unlike MoveByConnection() a linear approximation will be used.
 /// </summary>
 /// <param name="spline">the current spline</param>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="distance">the distance in world units to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <param name="minMatchesNeeded">minimum number of tags that must match to use a connection</param>
 /// <param name="stepSize">stepSize defines the accuracy</param>
 /// <param name="tags">list of tags to match</param>
 /// <returns>the interpolated position</returns>
 public Vector3 MoveByConnectionFast(ref CurvySpline spline, ref float tf, ref int direction, float distance, CurvyClamping clamping, int minMatchesNeeded, float stepSize, params string[] tags)
 {
     return MoveConnectionFast(ref spline, ref tf, ref direction, ExtrapolateDistanceToTFFast(tf, distance, stepSize), clamping, minMatchesNeeded, tags);
 }
Beispiel #46
0
 /// <summary>
 /// Clamps absolute position and sets new direction
 /// </summary>
 public static float ClampDistance(float distance, ref int dir, CurvyClamping clamping, float length, float min, float max)
 {
     if (length == 0)
         return 0;
     min = Mathf.Clamp(min, 0, length);
     max = Mathf.Clamp(max, min, length);
     switch (clamping)
     {
         case CurvyClamping.Loop:
             return min + Mathf.Repeat(distance, max - min);
         case CurvyClamping.PingPong:
             if (Mathf.FloorToInt(distance / (max - min)) % 2 != 0)
                 dir *= -1;
             return min + Mathf.PingPong(distance, max - min);
         default:
             return Mathf.Clamp(distance, min, max);
     }
 }
Beispiel #47
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain portion of the spline, using connections if conditions match. Unlike MoveConnection() a linear approximation will be used
 /// </summary>
 /// <param name="spline">the current spline</param>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="fDistance">the percentage of the spline to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <param name="minMatchesNeeded">minimum number of tags that must match to use a connection</param>
 /// <param name="tags">list of tags to match</param>
 /// <returns>the interpolated position</returns>
 public Vector3 MoveConnectionFast(ref CurvySpline spline, ref float tf, ref int direction, float fDistance, CurvyClamping clamping, int minMatchesNeeded, params string[] tags)
 {
     List<CurvyConnection> cons = GetConnectionsWithin(tf, direction, fDistance, minMatchesNeeded,true, tags);
     if (cons.Count > 0) {
         CurvyConnection con;
         if (cons.Count == 1)
             con = cons[0];
         else
             con = CurvyConnection.GetBestMatchingConnection(cons, tags);
         CurvySplineSegment cp = con.GetFromSpline(this);
         float cptf = SegmentToTF(cp);
         fDistance -= cptf - tf;
         CurvySplineSegment counterp = con.GetCounterpart(cp);
         tf = counterp.LocalFToTF(0);
         spline = counterp.Spline;
         return spline.MoveConnectionFast(ref spline, ref tf, ref direction, fDistance, clamping, minMatchesNeeded, tags);
     }
     else
         return MoveFast(ref tf, ref direction, fDistance, clamping);
 }
Beispiel #48
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain portion of the spline/group, respecting Clamping. Unlike Move() a linear approximation will be used
 /// </summary>
 /// <remarks>fDistance relates to the total spline, so longer splines will result in faster movement for constant fDistance</remarks>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="fDistance">the percentage of the spline/group to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <returns>the interpolated position</returns>
 public virtual Vector3 MoveFast(ref float tf, ref int direction, float fDistance, CurvyClamping clamping)
 {
     tf += fDistance * direction;
     ClampTF(ref tf, ref direction, clamping);
     return(InterpolateFast(tf));
 }
Beispiel #49
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain distance.
 /// </summary>
 /// <remarks>MoveByLengthFast is used internally, so stepSize is ignored</remarks>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="distance">the distance in world units to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <param name="stepSize">stepSize defines the accuracy</param>
 /// <returns>the interpolated position</returns>
 public override Vector3 MoveByFast(ref float tf, ref int direction, float distance, CurvyClamping clamping, float stepSize)
 {
     return(MoveByLengthFast(ref tf, ref direction, distance, clamping));
 }
Beispiel #50
0
 /// <summary>
 /// Alter TF to reflect a movement over a certain distance. Unlike MoveBy, a linear approximation will be used
 /// </summary>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="distance">the distance in world units to move</param>
 /// <param name="clamping">clamping mode</param>
 /// <param name="stepSize">stepSize defines the accuracy</param>
 /// <returns>the interpolated position</returns>
 public virtual Vector3 MoveByFast(ref float tf, ref int direction, float distance, CurvyClamping clamping, float stepSize)
 {
     return(MoveFast(ref tf, ref direction, ExtrapolateDistanceToTFFast(tf, distance, stepSize), clamping));
 }
Beispiel #51
0
 /// <summary>
 /// Clamps absolute position
 /// </summary>
 public float ClampDistance(float distance, CurvyClamping clamping)
 {
     return(CurvyUtility.ClampDistance(distance, clamping, Length));
 }
Beispiel #52
0
 /// <summary>
 /// Alter TF to move until the curvation reached angle, using a default stepSize of 0.002f
 /// </summary>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="angle">the angle in degrees</param>
 /// <param name="clamping">the clamping mode. CurvyClamping.PingPong isn't supported!</param>
 /// <returns>the interpolated position</returns>
 public virtual Vector3 MoveByAngle(ref float tf, ref int direction, float angle, CurvyClamping clamping)
 {
     return(MoveByAngle(ref tf, ref direction, angle, clamping, 0.002f));
 }
Beispiel #53
0
 /// <summary>
 /// Clamps absolute position and sets new direction
 /// </summary>
 public float ClampDistance(float distance, ref int dir, CurvyClamping clamping, float min, float max)
 {
     return(CurvyUtility.ClampDistance(distance, ref dir, clamping, Length, min, max));
 }
Beispiel #54
0
 /// <summary>
 /// Alter TF to move until the curvation reached angle, using a default stepSize of 0.002f
 /// </summary>
 /// <param name="tf">the current TF value</param>
 /// <param name="direction">the current direction, 1 or -1</param>
 /// <param name="angle">the angle in degrees</param>
 /// <param name="clamping">the clamping mode. CurvyClamping.PingPong isn't supported!</param>
 /// <returns>the interpolated position</returns>
 public virtual Vector3 MoveByAngle(ref float tf, ref int direction, float angle, CurvyClamping clamping)
 {
     return MoveByAngle(ref tf, ref direction, angle, clamping, 0.002f);
 }
    /*! \cond PRIVATE */
    /*! @name Internal Public
     *  Don't use them unless you know what you're doing!
     */
    //@{

    protected virtual bool ClampTF(ref float tf, ref int dir, CurvyClamping clamping)
    {
        switch (clamping) {
            case CurvyClamping.Loop:
                if (tf < 0) {
                    tf = 1 - Mathf.Abs(tf % 1);
                    return true;
                }
                else if (tf > 1) {
                    tf = tf % 1;
                    return true;
                }
                break;
            case CurvyClamping.PingPong:
                if (tf < 0) {
                    tf = (tf % 1) * -1;
                    dir *= -1;
                    return true;
                }
                else if (tf > 1) {
                    tf = 1 - tf % 1;
                    dir *= -1;
                    return true;
                }
                break;
            default: // Clamp
                tf = Mathf.Clamp01(tf);
                break;
        }
        return false;
    }