Beispiel #1
0
        public void ScaleAndRotate(OsbEasing easing, double startTime, double endTime, double scaleFactor, Vector2 origin, double rotation = 0, double delta = 1000.0 / 60)
        {
            if (endTime - startTime <= 0 || (scaleFactor == 1 && rotation == 0) || delta == 0)
            {
                return;
            }
            foreach (var sprite in Sprites)
            {
                Movement movement = new Movement(
                    easing,
                    startTime,
                    endTime,
                    sprite.PositionAt(startTime),
                    Vector2.Lerp(origin, sprite.PositionAt(startTime), (float)scaleFactor)
                    );
                if (scaleFactor != 1)
                {
                    Vector2 originalScale = sprite.ScaleAt(startTime);
                    if (originalScale.X == originalScale.Y)
                    {
                        sprite.Scale(easing, startTime, endTime, originalScale.X, originalScale.X * scaleFactor);
                    }
                    else
                    {
                        sprite.ScaleVec(easing, startTime, endTime, originalScale, originalScale * (float)scaleFactor);
                    }
                }

                if (rotation != 0)
                {
                    Movement split = movement.ResampledSection(startTime, endTime, delta);
                    foreach (var command in split.Commands)
                    {
                        var ease = easing.ToEasingFunction();
                        command.StartValue = ((Vector2)command.StartValue)
                                             .rotated(rotation * ease((command.StartTime - startTime) / (endTime - startTime)), origin);
                        command.EndValue = ((Vector2)command.EndValue)
                                           .rotated(rotation * ease((command.EndTime - startTime) / (endTime - startTime)), origin);
                    }
                    sprite.Move(split);
                    sprite.Rotate(easing, startTime, endTime, sprite.RotationAt(startTime), sprite.RotationAt(startTime) + rotation);
                    continue;
                }
                sprite.Move(movement);
            }
        }
Beispiel #2
0
 public static double Ease(this OsbEasing easing, double value)
 => easing.ToEasingFunction().Invoke(value);
 public static Func <Vector2, double> RadialGradient(OsbEasing easing, Vector2 centre, float radius, double centreValue, double perimiterValue)
 => RadialGradient(easing.ToEasingFunction(), centre, radius, centreValue, perimiterValue);
 public static Func <Vector2, Color4> RadialColorGradient(OsbEasing easing, Vector2 centre, float radius, Color4 centreColor, Color4 perimiterColor)
 => RadialColorGradient(easing.ToEasingFunction(), centre, radius, centreColor, perimiterColor);
        //Creates one element of a circle chain
        public void oneCircle(String path, String blurredPath, int startTime, int endTime, int fadeOffset, Vector2 position, double radius, double startAngle, double initialAngle, double endAngle, double scale, double steps, bool up, bool big, int beatsToMove, int cpt, double scaleDistance)
        {
            double angleOffset = (startAngle - endAngle) / steps;

            double angle = initialAngle;

            double radius1 = radius;
            double radius2 = radius;

            Vector2 initialPosition = new Vector2((float)(position.X + radius * Math.Cos(initialAngle)), (float)(position.Y + radius * Math.Sin(initialAngle)));

            var circle = layer.CreateSprite(path, OsbOrigin.Centre, initialPosition);

            circle.Color(startTime, Color);

            //var blurredCircle = layer.CreateSprite(blurredPath, OsbOrigin.Centre, initialPosition);
            //blurredCircle.Color(startTime, BlurColor);

            double fadeStart = startTime + fadeOffset - 70;
            double fadeEnd   = startTime + fadeOffset + 500;

            circle.Fade(
                fadeStart,
                fadeEnd,
                0, Color.A
                );
            circle.Fade(endTime - 2 * beatduration, endTime, Color.A, 0);

            /*
             * // crossfade command overlap untanglement logic
             * if (fadeStart < ScaleStart)
             * {
             *  circle.Fade(
             *      fadeStart,
             *      fadeEnd >= ScaleStart ? ScaleStart : fadeEnd,
             *      0, fadeEnd >= ScaleStart ? Color.A * (ScaleStart - fadeStart) / (fadeEnd - fadeStart) : Color.A
             *  );
             *  circle.Fade(
             *      ScaleEasing,
             *      fadeEnd >= ScaleStart ? ScaleStart : fadeEnd,
             *      ScaleEnd,
             *      fadeEnd >= ScaleStart ? Color.A * (ScaleStart - fadeStart) / (fadeEnd - fadeStart) : Color.A, 0
             *  );
             * }
             * else
             * {
             *  circle.Fade(
             *      ScaleEasing,
             *      fadeStart,
             *      (fadeStart + fadeEnd) / 2,
             *      Color.A / 2, 0
             *  );
             *  circle.Fade(
             *      ScaleEasing,
             *      (fadeStart + fadeEnd) / 2,
             *      fadeEnd,
             *      Color.A / 2, 0
             *  );
             * }
             */

            /*
             * blurredCircle.Fade(
             *  ScaleEasing,
             *  ScaleStart < fadeStart ? fadeStart : ScaleStart,
             *  ScaleEnd,
             *  0, Color.A
             * );
             * blurredCircle.Fade(endTime, 0);
             */

            if (Additive)
            {
                circle.Additive(fadeStart, endTime);
            }

            double delta = beatsToMove * beatduration;

            for (double time = startTime; time < endTime - 5; time += delta)
            {
                // some logic for the scaling part
                if (time >= ScaleStart - 2 * beatduration - 5 && time < ScaleEnd)
                {
                    // movement resolution is increased so the easing can feel natural.
                    // this is done 2 beats earlier, because the different rings start
                    // at different times and would be misaligned when the scaling starts
                    delta       = beatsToMove * beatduration / 8.0;
                    angleOffset = (startAngle - endAngle) / steps / 8.0;

                    if (time >= ScaleStart - 5)
                    {
                        double t1 = (time - ScaleStart) / (ScaleEnd - ScaleStart);
                        double t2 = (time + delta - ScaleStart) / (ScaleEnd - ScaleStart);
                        t1 = ScaleEasing.ToEasingFunction()(t1);
                        t2 = ScaleEasing.ToEasingFunction()(t2);
                        if (t1 <= 0.00001)
                        {
                            t1 = 0;
                        }
                        if (t2 >= 0.99999)
                        {
                            t2 = 1;
                        }
                        radius1 = radius + scaleDistance * t1;
                        radius2 = radius + scaleDistance * t2;
                    }
                }
                else if (time >= ScaleEnd)
                {
                    radius1     = radius2;
                    delta       = beatsToMove * beatduration;
                    angleOffset = (startAngle - endAngle) / steps;
                }

                int     dir = up ? 1 : -1;
                Vector2 p1  = new Vector2(
                    (float)(position.X + radius1 * Math.Cos(angle)),
                    (float)(position.Y + radius1 * Math.Sin(angle))
                    );
                Vector2 p2 = new Vector2(
                    (float)(position.X + radius2 * Math.Cos(angle + dir * angleOffset)),
                    (float)(position.Y + radius2 * Math.Sin(angle + dir * angleOffset))
                    );

                circle.Move(MovementEasing, time, time + delta, p1, p2);
                //if (blurredCircle.OpacityAt(time) > 0) blurredCircle.Move(MovementEasing, time, time + delta, p1, p2);

                angle += dir * angleOffset;
            }

            circle.Scale(ScaleEasing, ScaleStart, ScaleEnd, scale, scale * radius2 / radius);
            circle.Rotate(startTime, endTime, initialAngle - Math.PI / 2, angle - Math.PI / 2);

            double blurredScale = scale * GetMapsetBitmap(path).Width / (double)GetMapsetBitmap(blurredPath).Width;
            //blurredCircle.Scale(ScaleEasing, ScaleStart, ScaleEnd, blurredScale, blurredScale * radius2 / radius);
        }