示例#1
0
 public ArcData(ArcRaw arc)
 {
     this.start       = Conversion.GetWorldPos(math.float2(arc.startX, arc.startY));
     this.end         = Conversion.GetWorldPos(math.float2(arc.endX, arc.endY));
     this.easing      = arc.easing;
     this.startTiming = arc.timing;
     this.endTiming   = arc.endTiming;
 }
示例#2
0
        private static Vector3 EaseSinus(Vector3 p1, Vector3 p2, float t, ArcEasing easing)
        {
            var y = MathHelper.Lerp(p1.Y, p2.Y, t);

            float sx, sz;

            switch (easing)
            {
            case ArcEasing.Si:
            case ArcEasing.SiSi:
            case ArcEasing.SiSo:
                sx = MathF.Sin(t * MathHelper.PiOver2);
                break;

            case ArcEasing.So:
            case ArcEasing.SoSi:
            case ArcEasing.SoSo:
                sx = 1 - MathF.Cos(t * MathHelper.PiOver2);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(easing), easing, null);
            }

            switch (easing)
            {
            case ArcEasing.Si:
            case ArcEasing.So:
                // Credit: @18111398
                sz = t;
                break;

            case ArcEasing.SoSi:
            case ArcEasing.SiSi:
                sz = MathF.Sin(t * MathHelper.PiOver2);
                break;

            case ArcEasing.SiSo:
            case ArcEasing.SoSo:
                sz = 1 - MathF.Cos(t * MathHelper.PiOver2);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(easing), easing, null);
            }

            var dx = p2.X - p1.X;
            var x  = p1.X + dx * sx;

            var dz = p2.Z - p1.Z;
            var z  = p1.Z + dz * sz;

            return(new Vector3(x, y, z));
        }
示例#3
0
        public static float GetYAt(float t, float startY, float endY, ArcEasing easing)
        {
            switch (easing)
            {
            case ArcEasing.s:
            case ArcEasing.si:
            case ArcEasing.so:
                return(math.lerp(startY, endY, t));

            case ArcEasing.b:
                return(B(startY, endY, t));

            case ArcEasing.sisi:
            case ArcEasing.sosi:
                return(I(startY, endY, t));

            case ArcEasing.siso:
            case ArcEasing.soso:
                return(O(startY, endY, t));
            }
            //Not possible, just here to make the compiler smile
            return(float.PositiveInfinity);
        }
示例#4
0
        /// <summary>
        /// Calculates the eased value of a pair of coordinates.
        /// </summary>
        /// <param name="start">Start position.</param>
        /// <param name="end">End position.</param>
        /// <param name="t">A value increasing from 0 to 1 while moving from <see cref="start"/> to <see cref="end"/>.</param>
        /// <param name="easing">Easing method.</param>
        /// <returns>Eased coordinate.</returns>
        public static Vector3 Ease(Vector3 start, Vector3 end, float t, ArcEasing easing)
        {
            t = MathHelper.Clamp(t, 0, 1);

            switch (easing)
            {
            case ArcEasing.S:
                return(EaseLinear(start, end, t));

            case ArcEasing.CubicBezier:
                return(EaseCubicBezier(start, end, t));

            case ArcEasing.Si:
            case ArcEasing.So:
            case ArcEasing.SiSo:
            case ArcEasing.SoSi:
            case ArcEasing.SoSo:
            case ArcEasing.SiSi:
                return(EaseSinus(start, end, t, easing));

            default:
                throw new ArgumentOutOfRangeException(nameof(easing), easing, null);
            }
        }
        private void DrawArc([NotNull] BasicEffect effect, int segmentCount, Vector3 start, Vector3 end, ArcEasing easing, Color color, float alpha, Vector2 arcSectionSize, bool castShadow)
        {
            var lastPoint = start;
            var zeroY     = _metrics.FinishLineY;
            var trackEndY = _metrics.TrackLength;

            for (var i = 1; i <= segmentCount; ++i)
            {
                if (lastPoint.Y > trackEndY)
                {
                    // This segment and later segments have not entered the track yet.
                    break;
                }

                Vector3 currentPoint;

                if (i == segmentCount)
                {
                    currentPoint = end;
                }
                else
                {
                    var ratio = (float)i / segmentCount;
                    currentPoint = ArcEasingHelper.Ease(start, end, ratio, easing);
                }

                if (lastPoint.Y < zeroY && currentPoint.Y < zeroY)
                {
                    // This segment has passed.
                    continue;
                }

                Vector3 fixedLastPoint, fixedCurrentPoint;

                // Recalculate the segment's start and end if needed.
                // However, we must ensure that the movement of the intersection of the arc and XoZ plane is always continuous,
                // therefore we must call the easing function again to retrieve its precise new location, instead of learping
                // inside the segment's start and end (shows recognizable "shaking" effect).
                // Credit: @18111398
                if (lastPoint.Y < zeroY)
                {
                    var ratio = (zeroY - start.Y) / (end.Y - start.Y);
                    fixedLastPoint = ArcEasingHelper.Ease(start, end, ratio, easing);
                }
                else
                {
                    fixedLastPoint = lastPoint;
                }

                if (currentPoint.Y > trackEndY)
                {
                    var ratio = (trackEndY - start.Y) / (end.Y - start.Y);
                    fixedCurrentPoint = ArcEasingHelper.Ease(start, end, ratio, easing);
                }
                else
                {
                    fixedCurrentPoint = currentPoint;
                }

                _arcMesh.SetVerticesXY(fixedLastPoint, fixedCurrentPoint, color, arcSectionSize.X);

                effect.TextureEnabled     = false;
                effect.VertexColorEnabled = true;

                effect.Alpha = alpha;

                _arcMesh.Draw(effect.CurrentTechnique);

                // Draw shadow if needed.
                if (castShadow)
                {
                    _shadow.SetVerticesXYParallel(fixedLastPoint.XY(), fixedCurrentPoint.XY(), arcSectionSize.X, Color.Gray, ShadowZ);

                    effect.TextureEnabled     = false;
                    effect.VertexColorEnabled = true;

                    effect.Alpha = 0.5f;

                    _shadow.Draw(effect.CurrentTechnique);
                }

                // Update the point.
                lastPoint = currentPoint;
            }
        }
示例#6
0
 public static float2 GetPosAt(float t, float2 start, float2 end, ArcEasing easing)
 => new float2(GetXAt(t, start.x, end.x, easing), GetYAt(t, start.y, end.y, easing));