示例#1
0
        public void generatePerLine(FontGenerator font, SubtitleSet subtitles, StoryboardLayer layer, bool additive)
        {
            foreach (var line in subtitles.Lines)
            {
                var texture  = font.GetTexture(line.Text);
                var position = new Vector2(320 - texture.BaseWidth * FontScale * 0.5f, SubtitleY)
                               + texture.OffsetFor(Origin) * FontScale;

                var sprite = layer.CreateSprite(texture.Path, Origin, position);
                sprite.Rotate(line.StartTime, -0.4);
                sprite.Scale(line.StartTime, FontScale);
                sprite.Fade(line.StartTime - 200, line.StartTime, 0, 1);
                sprite.Fade(line.EndTime - 200, line.EndTime, 1, 0);
                double posx      = -25;
                double posxAfter = -25;
                double posy      = 260;
                double posyAfter = 260;
                sprite.MoveX(OsbEasing.Out, line.StartTime - 500, line.StartTime, posx - 500, posx);
                sprite.MoveY(OsbEasing.Out, line.StartTime - 500, line.StartTime, posy + 200, posy);

                for (double i = line.StartTime; i <= line.EndTime; i += 75)
                {
                    posxAfter += 1;
                    posyAfter -= 0.5;
                    sprite.MoveX(i, i + 75, posx, posxAfter);
                    sprite.MoveY(i, i + 75, posy, posyAfter);
                    posx = posxAfter;
                    posy = posyAfter;
                }
                sprite.MoveX(OsbEasing.InCubic, line.EndTime - 500, line.EndTime + 250, posxAfter - 6, posx + 475);
                sprite.MoveY(OsbEasing.InCubic, line.EndTime - 500, line.EndTime + 250, posyAfter + 3, posy - 200);
                if (additive)
                {
                    sprite.Additive(line.StartTime - 200, line.EndTime);
                }
            }
        }
示例#2
0
        public override void Generate()
        {
            bgLayer   = GetLayer("Background");
            mainLayer = GetLayer("Main");

            using (spritePools = new OsbSpritePools(mainLayer))
            {
                Intro(TimeIntro, TimePart1);

                // Background
                var bg = bgLayer.CreateSprite("bg.jpg", OsbOrigin.Centre);
                bg.Scale(TimeSbStart, BgScaling);
                bg.Fade(TimePart1 - BeatDuration * 2, TimePart1, 0, 1);
                bg.ColorHsb(TimeSbStart, 0, 0, 0.3);
                bg.ColorHsb(TimePart2 - BeatDuration * 3 / 2, TimePart2 - BeatDuration / 2, 0, 0, 0.3, 0, 0, 0.6);
                bg.ColorHsb(OsbEasing.In, TimePart6 - BeatDuration * 4, TimePart6, 0, 0, 0.3, 0, 0, 0.3);
                bg.Fade(OsbEasing.In, TimePart3 - BeatDuration * 4, TimePart3, 1, 0);
                bg.ColorHsb(OsbEasing.In, TimePart4 - BeatDuration * 2, TimePart4, 0, 0, 0.6, 0, 0, 0.3);
                bg.Fade(OsbEasing.Out, TimePart4 - BeatDuration * 2, TimePart4, 0, 1);
                bg.Fade(OsbEasing.In, TimePart5 - BeatDuration * 4, TimePart5, 1, 0);
                bg.Fade(OsbEasing.Out, TimePart6, TimePart7, 0, 1);
                bg.Fade(OsbEasing.In, TimePart10 - BeatDuration * 4, TimePart10, 1, 0);

                Part1(TimePart1, TimePart2);
                Part2(TimePart2, TimePart3);
                Part3(TimePart3, TimePart4);
                Part4(TimePart4, TimePart5);
                Part5(TimePart5, TimePart6);
                Part6(TimePart6, TimePart7);
                Part7(TimePart7, TimePart8);
                Part8(TimePart8, TimePart9);
                Part9(TimePart9, TimePart10);
                Part10(TimePart10, TimePart11);
                Part11(TimePart11, TimeEnd);
                Outro(TimeEnd, TimeSbEnd);
            }
        }
        //Creates one element of a circle chain
        public void oneCircle(String path, int startTime, int endTime, int fadeOffset, Vector2 position, int radius, double startAngle, double initialAngle, double endAngle, double scale, double steps, bool up, bool wiggle, bool big, int beatsToMove)
        {
            double angleOffset = (startAngle - endAngle) / steps;


            var circle = layer.CreateSprite(path, OsbOrigin.Centre, new Vector2((float)(position.X + radius * Math.Cos(initialAngle)), (float)(position.Y + radius * Math.Sin(initialAngle))));

            circle.Fade(startTime - fadeOffset - 70, startTime - fadeOffset, 0, 1);
            circle.Fade(endTime, 0);
            circle.Scale(startTime + fadeOffset, scale);

            for (double time = startTime; time < endTime - 5; time += beatsToMove * beatduration)
            {
                if ((initialAngle <= startAngle) && (initialAngle > endAngle))
                {
                    if (up)
                    {
                        circle.Move(outEase, time, time + 150, (position.X + radius * Math.Cos(initialAngle)), (float)(position.Y + radius * Math.Sin(initialAngle)), (position.X + radius * Math.Cos(initialAngle + angleOffset)), (float)(position.Y + radius * Math.Sin(initialAngle + angleOffset)));
                    }
                    else
                    {
                        circle.Move(outEase, time, time + 150, (position.X + radius * Math.Cos(initialAngle)), (float)(position.Y + radius * Math.Sin(initialAngle)), (position.X + radius * Math.Cos(initialAngle - angleOffset)), (float)(position.Y + radius * Math.Sin(initialAngle - angleOffset)));
                    }
                    if (wiggle)
                    {
                        if (big)
                        {
                            circle.Scale(outEase, time, time + 150, 0.75 * scale, 1.25 * scale);
                        }
                        else
                        {
                            circle.Scale(outEase, time, time + 150, 1.25 * scale, 0.75 * scale);
                        }
                    }
                }
            }
        }
示例#4
0
        private void slideShow(StoryboardLayer layer, string path, double startTime, double endTime, OsbOrigin origin, double moveBy, bool fadeIn, bool fadeOut)
        {
            Vector2 pos = new Vector2();

            if (origin == OsbOrigin.CentreLeft) // Check if i want to slide to left
            {
                pos = new Vector2(-107, 240);
            }
            else if (origin == OsbOrigin.CentreRight) // Check if i want to slide to right
            {
                pos = new Vector2(747, 240);
            }

            var sprite = layer.CreateSprite(path, origin, pos);

            sprite.Scale(startTime, Constants.screenScale);
            sprite.MoveX(startTime, endTime, sprite.PositionAt(startTime).X, sprite.PositionAt(startTime).X + moveBy * Constants.screenScale);

            if (fadeIn) // Check if i want to have a slow fade or instant
            {
                sprite.Fade(easing, startTime - Constants.beatLength * fadeby, startTime, 0, 1);
            }
            else if (!fadeIn)
            {
                sprite.Fade(startTime, 1);
            }

            if (fadeOut) // Check if i want to have a slow fadeout or instant
            {
                sprite.Fade(endTime - Constants.beatLength * 3, endTime, 1, 0);
            }
            else if (!fadeOut)
            {
                sprite.Fade(endTime, 0);
            }
        }
示例#5
0
        public override void Generate()
        {
            layer        = GetLayer("Main");
            beatduration = Beatmap.GetTimingPointAt(13).BeatDuration;

            // Loading the big notes

            ArrayList beeg = new ArrayList();

            for (int i = 0; i < 6; i++)
            {
                if (i == 2)
                {
                    continue;
                }
                Vector2 position = new Vector2(320 - 150 + i * 60, 260);
                var     top      = layer.CreateSprite("sb/piano/top.png", OsbOrigin.BottomCentre, position);
                var     bottom   = layer.CreateSprite("sb/piano/bottom.png", OsbOrigin.TopCentre, position + new Vector2(0, 0.1f * 200));
                var     body     = layer.CreateSprite("sb/piano/body.png", OsbOrigin.BottomCentre, position);

                top.Scale(2369, 0.2);
                bottom.Scale(2369, 0.2);
                body.ScaleVec(2369, 0.2, 0.1);
                body.Rotate(2369, Math.PI);

                PianoNote pn1 = new PianoNote(top, bottom, body, position, false, 0.2f);
                pn1.fadeIn(2369);
                pn1.fadeOut(20117);

                beeg.Add(pn1);
            }

            // Loading the small notes

            ArrayList smol = new ArrayList();

            for (int i = 0; i < 7; i++)
            {
                Vector2 position = new Vector2(320 - 180 + i * 60, 220);
                var     top      = layer.CreateSprite("sb/piano/top-fill.png", OsbOrigin.BottomCentre, position - new Vector2(0, 0.075f * 200));
                var     bottom   = layer.CreateSprite("sb/piano/bottom-fill.png", OsbOrigin.TopCentre, position);
                var     body     = layer.CreateSprite("sb/piano/body-fill.png", OsbOrigin.BottomCentre, position);

                top.Scale(2369, 0.15);
                bottom.Scale(2369, 0.15);
                body.ScaleVec(2369, 0.15, 0.075);

                PianoNote pn1 = new PianoNote(top, bottom, body, position, true, 0.15f);
                pn1.fadeIn(2369);
                pn1.fadeOut(20117);

                smol.Add(pn1);
            }


            // Setting font

            font = LoadFont("sb/PianoNotesRegular", new FontDescription()
            {
                FontPath         = "fonts/Altero-Regular.otf",
                FontSize         = 72,
                Color            = Color4.White,
                Padding          = new Vector2(5, 5),
                FontStyle        = FontStyle.Regular,
                TrimTransparency = true,
                EffectsOnly      = false,
                Debug            = false,
            },
                            new FontOutline()
            {
                Thickness = 0,
                Color     = Color.Transparent,
            },
                            new FontShadow()
            {
                Thickness = 0,
                Color     = Color.Transparent,
            });

            Tuple <int, string>[] noteList =
            {
                Tuple.Create(3, "A#3"),
                Tuple.Create(0, "C4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(0, "C3"),
                Tuple.Create(1, "D3"),
                Tuple.Create(1, "D#3"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "A#3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "G4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "A#4"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(3, "A#3"),
                Tuple.Create(0, "C4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(0, "C3"),
                Tuple.Create(1, "D3"),
                Tuple.Create(1, "D#3"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "A#3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "G4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "A#4"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(3, "A#3"),
                Tuple.Create(0, "C4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(0, "C3"),
                Tuple.Create(1, "D3"),
                Tuple.Create(1, "D#3"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "A#3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "G4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "A#4"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(3, "A#3"),
                Tuple.Create(0, "C4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(0, "C3"),
                Tuple.Create(1, "D3"),
                Tuple.Create(1, "D#3"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "A#3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "G4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "A#4"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(3, "A#3"),
                Tuple.Create(0, "C4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(0, "C3"),
                Tuple.Create(1, "D3"),
                Tuple.Create(1, "D#3"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "A#3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "G4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "A#4"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(3, "A#3"),
                Tuple.Create(0, "C4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(0, "C3"),
                Tuple.Create(1, "D3"),
                Tuple.Create(1, "D#3"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "A#3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "G4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "A#4"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(3, "A#3"),
                Tuple.Create(0, "C4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(0, "C3"),
                Tuple.Create(1, "D3"),
                Tuple.Create(1, "D#3"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "A#3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "G4"),
                Tuple.Create(0, "C2"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3"),
                Tuple.Create(4, "A#4"),
                Tuple.Create(3, "F3"),
                Tuple.Create(4, "G3")
            };

            double run = StartTime;

            foreach (var note in noteList)
            {
                if (note.Item2.Contains('#'))
                {
                    clickNoteBottom((PianoNote)(beeg[note.Item1]), (int)run, note.Item2);
                }
                else
                {
                    clickNoteTop((PianoNote)(smol[note.Item1]), (int)run, note.Item2);
                }
                run += tick(0, 2);
            }
        }
示例#6
0
        public void GenerateBackground(double startTime, double endTime)
        {
            var bgBlur = layer.CreateSprite("sb/bgKiaiBlur.jpg");

            bgBlur.Scale(startTime, 480.0f / 1093 + 0.07f);
            bgBlur.Fade(startTime, 1);
            bgBlur.Fade(endTime, 0);

            var bgOverlay = layer.CreateSprite("sb/bgKiai.jpg");

            bgOverlay.Fade(startTime, 0.2f);
            bgOverlay.Scale(startTime, (480.0f / 1093) + 0.07f);
            bgOverlay.Fade(endTime - beatduration * 4, 0f);

            var movement = 3f;
            var rotate   = .01f;

            for (var time = startTime; time < endTime - beatduration * 5; time += beatduration)
            {
                if (time > 313864 && time < 314922) //This is a silent part in the second kiai. No movement wanted
                {
                    continue;
                }

                var position = new Vector2(320, 240) + new Vector2((float)Random(-movement, movement), (float)Random(-movement, movement)) * (IsStrongHit(time) ? 10f : 1f);
                var rotation = (float)Random(-rotate, rotate) * (IsStrongHit(time) ? 5f : 1f);

                bgOverlay.Move(OsbEasing.OutExpo, time, time + beatduration, bgOverlay.PositionAt(time), position);
                bgBlur.Move(OsbEasing.InCirc, time, time + beatduration, bgOverlay.PositionAt(time), position);

                bgOverlay.Rotate(OsbEasing.OutExpo, time, time + beatduration, bgOverlay.RotationAt(time), rotation);
                bgBlur.Rotate(OsbEasing.InCirc, time, time + beatduration, bgOverlay.RotationAt(time), rotation);
            }
            bgOverlay.Additive(bgOverlay.CommandsStartTime, bgOverlay.CommandsEndTime);
        }
示例#7
0
文件: Lyrics.cs 项目: Shmiklak/lilith
        public void generatePerCharacter(FontGenerator font, SubtitleSet subtitles, StoryboardLayer layer, bool additive)
        {
            var squaresLayer = GetLayer("lyricsSquares");

            foreach (var subtitleLine in subtitles.Lines)
            {
                var letterY    = SubtitleY;
                var i          = 0;
                var lineOffset = 0;
                foreach (var line in subtitleLine.Text.Split('\n'))
                {
                    var lineWidth  = 0f;
                    var lineHeight = 0f;
                    foreach (var letter in line)
                    {
                        var texture = font.GetTexture(letter.ToString());
                        lineWidth += texture.BaseWidth * FontScale;
                        lineHeight = Math.Max(lineHeight, texture.BaseHeight * FontScale);
                    }

                    var letterX = 320 - lineWidth * 0.5f + lineOffset;
                    foreach (var letter in line)
                    {
                        var texture = font.GetTexture(letter.ToString());
                        if (!texture.IsEmpty)
                        {
                            var initialPosition = new Vector2(letterX + 40, letterY) + texture.OffsetFor(Origin) * FontScale;

                            var position = new Vector2(letterX, letterY)
                                           + texture.OffsetFor(Origin) * FontScale;

                            var finalPosition = new Vector2(letterX + Random(-15, 15), letterY + Random(-15, 15)) + texture.OffsetFor(Origin) * FontScale;

                            if (squares)
                            {
                                for (int f = 0; f < 3; f++)
                                {
                                    var color = Color;
                                    if (ColorVariance > 0)
                                    {
                                        ColorVariance = MathHelper.Clamp(ColorVariance, 0, 1);

                                        var hsba = Color4.ToHsl(color);
                                        var sMin = Math.Max(0, hsba.Y - ColorVariance * 0.5f);
                                        var sMax = Math.Min(sMin + ColorVariance, 1);
                                        var vMin = Math.Max(0, hsba.Z - ColorVariance * 0.5f);
                                        var vMax = Math.Min(vMin + ColorVariance, 1);

                                        color = Color4.FromHsl(new Vector4(
                                                                   hsba.X,
                                                                   (float)Random(sMin, sMax),
                                                                   (float)Random(vMin, vMax),
                                                                   hsba.W));
                                    }


                                    var initiialRotation = Random(0, MathHelper.DegreesToRadians(360));
                                    var endRotation      = Random(0, MathHelper.DegreesToRadians(360));

                                    var sqaureIinitPos = new Vector2(letterX + Random(-30, 30), letterY + Random(-30, 30)) + texture.OffsetFor(Origin) * FontScale;

                                    var squarePosition = new Vector2(letterX + Random(-15, 15), letterY + Random(-15, 15)) + texture.OffsetFor(Origin) * FontScale;

                                    var square = squaresLayer.CreateSprite("sb/etc/p.png", Origin, squarePosition);
                                    square.Move(subtitleLine.StartTime - 400 + i, subtitleLine.StartTime + i, sqaureIinitPos, squarePosition);
                                    square.Scale(subtitleLine.StartTime - 400 + i, subtitleLine.EndTime, 20, 20);
                                    square.Additive(subtitleLine.StartTime - 400 + i, subtitleLine.EndTime);
                                    square.Fade(subtitleLine.StartTime - 400 + i, subtitleLine.StartTime + i, 0, 0.1);
                                    square.Rotate(subtitleLine.StartTime - 400 + i, subtitleLine.EndTime, initiialRotation, endRotation);
                                    square.Color(subtitleLine.StartTime - 400 + i, color);
                                    square.Fade(subtitleLine.EndTime - 400, subtitleLine.EndTime, 0.1, 0);
                                }
                            }

                            var sprite = layer.CreateSprite(texture.Path, Origin, position);
                            sprite.Move(OsbEasing.Out, subtitleLine.StartTime - 400 + i, subtitleLine.StartTime + i, initialPosition, position);
                            // sprite.Scale(subtitleLine.StartTime - 200 + i, subtitleLine.StartTime + i, 0, FontScale);
                            // sprite.Rotate(OsbEasing.Out, subtitleLine.StartTime - 400 + i, subtitleLine.StartTime + i, MathHelper.DegreesToRadians(Random(0, 360)), MathHelper.DegreesToRadians(0));
                            sprite.Fade(OsbEasing.Out, subtitleLine.StartTime - 400 + i, subtitleLine.StartTime + i, 0, 1);
                            // sprite.MoveY(subtitleLine.StartTime - 200 + i, subtitleLine.StartTime + i, letterY - 15, letterY);
                            sprite.Fade(OsbEasing.In, subtitleLine.EndTime - 400, subtitleLine.EndTime, 1, 0);
                            sprite.Scale(OsbEasing.In, subtitleLine.EndTime - 400, subtitleLine.EndTime, FontScale, 0);
                            sprite.Move(OsbEasing.In, subtitleLine.EndTime - 400, subtitleLine.EndTime, position, finalPosition);

                            if (additive)
                            {
                                sprite.Additive(subtitleLine.StartTime - 400, subtitleLine.EndTime);
                            }
                            i += 65;
                        }
                        letterX += texture.BaseWidth * FontScale;
                    }
                    // lineOffset += 120;
                    letterY += lineHeight;
                }
            }
        }
示例#8
0
 public void Flicker(double time, String newTexturePath)
 {
     sprites.Add(layer.CreateSprite(newTexturePath, origin));
     swapTimes.Add(time);
 }
示例#9
0
        public override void Generate()
        {
            layer = GetLayer("Background");
            //Get colors
            Color4 colorOne = Beatmap.ComboColors.ElementAt(0);
            Color4 colorTwo = Beatmap.ComboColors.ElementAt(1);


            //Section 1 (1583 - 12578), color 1
            //Main White Frame, spawns from left to right
            var pannel1 = layer.CreateSprite("sb/pixel.png", OsbOrigin.CentreRight);

            pannel1.ScaleVec(1583, 1500, 1500);
            pannel1.Rotate(1583, Math.PI / 24);
            pannel1.Move(OsbEasing.OutCubic, 1583, 1583 + 700, -115, 240, 850, 240);
            pannel1.Fade(1583, 2211, 1, 1);

            //Main Color1 Frame, spawns from left to right
            var pannel2 = layer.CreateSprite("sb/pixel.png", OsbOrigin.CentreRight);

            pannel2.ScaleVec(1740, 1500, 1500);
            pannel2.Rotate(1740, Math.PI / 24);
            pannel2.Move(OsbEasing.OutCubic, 1740, 1740 + 700, -115, 240, 830, 240);
            pannel2.Fade(1740, 12264, 1, 1);
            pannel2.Color(1740, colorOne);
            pannel2.ScaleVec(OsbEasing.OutCubic, 2211, 2211 + 500, 1500, 1500, 235, 1500);

            //Additionnal white frames
            var pannel3 = layer.CreateSprite("sb/pixel.png", OsbOrigin.CentreRight);

            pannel3.ScaleVec(2211, 6, 1500);
            pannel3.Rotate(2211, Math.PI / 24);
            pannel3.Move(OsbEasing.OutCubic, 2211, 2211 + 500, -115, 240, 330, 240);
            pannel3.Fade(2211, 12264, 1, 1);

            var pannel4 = layer.CreateSprite("sb/pixel.png", OsbOrigin.CentreRight);

            pannel4.ScaleVec(2211, 23, 1500);
            pannel4.Rotate(2211, Math.PI / 24);
            pannel4.Move(OsbEasing.OutCubic, 2211, 2211 + 500, -115, 240, 420, 240);
            pannel4.Fade(2211, 12264, 1, 1);

            //Section 2 (11950 - 22316)
            var pannel5 = layer.CreateSprite("sb/pixel.png", OsbOrigin.CentreLeft);

            pannel5.ScaleVec(11950, 500, 1500);
            pannel5.Rotate(11950, Math.PI / 24);
            pannel5.Color(11950, colorTwo);
            pannel5.Move(OsbEasing.OutCubic, 11950, 11950 + 500, -900, 240, -140, 240);
            pannel5.Fade(11950, 22316, 1, 1);
            pannel5.ScaleVec(OsbEasing.OutCirc, 12264, 12264 + 420, 500, 1500, 215, 1500);

            var pannel6 = layer.CreateSprite("sb/pixel.png", OsbOrigin.CentreRight);

            pannel6.ScaleVec(12264, 19, 1500);
            pannel6.Rotate(12264, Math.PI / 24);
            pannel6.Move(OsbEasing.OutCubic, 12264, 12264 + 500, 820, 240, 282, 240);
            pannel6.Fade(12264, 22316, 1, 1);

            var pannel7 = layer.CreateSprite("sb/pixel.png", OsbOrigin.CentreRight);

            pannel7.ScaleVec(12264, 5, 1500);
            pannel7.Rotate(12264, Math.PI / 24);
            pannel7.Move(OsbEasing.OutCubic, 12264, 12264 + 500, 850, 260, 320, 240);
            pannel7.Fade(12264, 22316, 1, 1);

            //Transition to the next section

            var circleTransit = layer.CreateSprite("sb/to.png", OsbOrigin.Centre, new Vector2(50, 240));

            circleTransit.Color(19803, Color4.Black);
            circleTransit.Fade(19803, 20745, 1, 1);
            circleTransit.Scale(OsbEasing.OutCirc, 19803, 19803 + 150, 0, 0.08);
            circleTransit.Scale(OsbEasing.OutCirc, 19960, 22316, 0.3, 0.2);

            var circleOutline = layer.CreateSprite("sb/q2.png", OsbOrigin.Centre, new Vector2(50, 240));

            circleOutline.Color(19960, Color4.Black);
            circleOutline.Fade(19960, 20745, 1, 1);
            circleOutline.Scale(OsbEasing.OutCirc, 19960, 22316, 0, 0.5);

            var line = layer.CreateSprite("sb/pixel.png", OsbOrigin.Centre, new Vector2(50, 240));

            line.Color(19960, Color4.Black);
            line.Fade(19960, 22316, 1, 1);
            line.ScaleVec(OsbEasing.InExpo, 19960, 22316, 500, 2, 1250, 0.66);
            line.Rotate(OsbEasing.InExpo, 19960, 22316, Math.PI / 24 + Math.PI / 2, -1.66 * Math.PI);

            var circleFull = layer.CreateSprite("sb/circle.png", OsbOrigin.Centre, new Vector2(50, 240));

            circleFull.Color(21374, Color4.Black);
            circleFull.Scale(OsbEasing.InExpo, 21374, 22395, 0, 9);
            circleFull.Fade(21374, 22395, 1, 1);
        }
示例#10
0
        public void generatePerCharacter(FontGenerator font, SubtitleSet subtitles, StoryboardLayer layer, string TimestampSplit)
        {
            var TimestampArray = Array.ConvertAll(TimestampSplit.Split(','), s => int.Parse(s));
            var LineStart      = 0;
            var LineEnd        = 0;
            var RunLine        = 0f;
            var aniLyrics      = 0;

            var trace = layer.CreateSprite(TracePath, OsbOrigin.Centre);

            if (StartTrace == 49997)
            {
                trace.Move(StartTrace - tick(0, 2) - tick(0, 1), StartTrace - tick(0, 1), new Vector2(-120, 400), new Vector2(70, 400));
                trace.Fade(StartTrace - tick(0, 2) - tick(0, 1), StartTrace - tick(0, 1), 0, 0.65);
                trace.ScaleVec(StartTrace - tick(0, 2) - tick(0, 1), StartTrace - tick(0, 1), 0, 0.15, 0.22, 0.15);
                trace.Color(StartTrace - tick(0, 2) - tick(0, 1), 0, 0, 0);
                trace.Fade(EndTrace - tick(0, 0.5), EndTrace, 0.65, 0);
            }
            else
            {
                trace.FlipH(StartTrace - tick(0, 2) - tick(0, 1), EndTrace);
                trace.FlipV(StartTrace - tick(0, 2) - tick(0, 1), EndTrace);
                trace.Move(StartTrace - tick(0, 2) - tick(0, 1), StartTrace - tick(0, 1), new Vector2(730, 400), new Vector2(540, 400));
                trace.Fade(StartTrace - tick(0, 2) - tick(0, 1), StartTrace - tick(0, 1), 0, 0.65);
                trace.ScaleVec(StartTrace - tick(0, 2) - tick(0, 1), StartTrace - tick(0, 1), 0, 0.15, 0.22, 0.15);
                trace.Color(StartTrace - tick(0, 2) - tick(0, 1), 0, 0, 0);
                trace.Fade(EndTrace - tick(0, 0.5), EndTrace, 0.65, 0);
            }

            foreach (var subtitleLine in subtitles.Lines)
            {
                foreach (var line in subtitleLine.Text.Split('\0'))
                {
                    var letterX = SubtitleX;
                    var letterY = SubtitleY;

                    var lineWidth  = 0f;
                    var lineHeight = 0f;

                    for (int x = 0; x < TimestampArray.Length; x++)
                    {
                        if (LineStart == TimestampArray[x])
                        {
                            continue;
                        }
                        if (TimestampArray[x] <= subtitleLine.StartTime && TimestampArray[x + 1] >= subtitleLine.StartTime)
                        {
                            LineStart = TimestampArray[x];
                            LineEnd   = TimestampArray[x + 1];
                            RunLine   = 0f;
                            aniLyrics = 0;
                            break;
                        }
                    }

                    foreach (var letter in line)
                    {
                        var texture = font.GetTexture(letter.ToString());
                        lineWidth += texture.BaseWidth * FontScale;
                        lineHeight = Math.Max(lineHeight, texture.BaseHeight * FontScale);
                        if (!texture.IsEmpty)
                        {
                            var position = new Vector2(letterX + RunLine, letterY)
                                           + texture.OffsetFor(Origin) * FontScale;
                            var sprite = layer.CreateSprite(texture.Path, Origin);
                            if (letter == '$')
                            {
                                letterX += texture.BaseWidth * FontScale;
                                continue;
                            }
                            //begin
                            sprite.Scale(LineStart + aniLyrics - tick(0, 0.5) + tick(0, 2), FontScale - 0.2f);
                            sprite.Fade(LineStart + aniLyrics - tick(0, 0.5) + tick(0, 2), LineStart + aniLyrics - tick(0, 0.75), 0, 0.4);
                            sprite.Move(LineStart + aniLyrics - tick(0, 0.5) + tick(0, 2), LineStart + aniLyrics - tick(0, 0.75), position - new Vector2(0, 20), position);
                            //pulse
                            sprite.Scale(subtitleLine.StartTime - 50, subtitleLine.StartTime + 50, FontScale - 0.2f, FontScale);
                            sprite.Fade(subtitleLine.StartTime - 50, subtitleLine.StartTime + 50, 0.4, 1);
                            //end
                            sprite.Scale(subtitleLine.StartTime + 50, subtitleLine.EndTime + tick(0, 1), FontScale, FontScale - 0.2f);
                            sprite.Fade(subtitleLine.StartTime + 50, subtitleLine.EndTime + tick(0, 1), 1, 0);
                        }
                        letterX += texture.BaseWidth * FontScale;
                    }
                    RunLine   += letterX - SubtitleX;
                    letterY   += lineHeight;
                    aniLyrics += 40;
                }
            }
        }
示例#11
0
        public void generatePerLine(FontGenerator font, SubtitleSet subtitles, StoryboardLayer layer, bool additive)
        {
            foreach (var line in subtitles.Lines)
            {
                Vector2[] shakePosition;
                shakePosition = new Vector2[10];
                Vector2[] shakePositionR;
                shakePositionR = new Vector2[10];
                Vector2[] shakePositionB;
                shakePositionB = new Vector2[10];

                for (int i = 0; i < 10; i++)
                {
                    shakePosition[i] = new Vector2(
                        (float)Random(0, 2),
                        (float)Random(0, 2)
                        );
                    shakePositionR[i] = new Vector2(
                        (float)Random(0, 5),
                        (float)Random(0, 5)
                        );
                    shakePositionB[i] = new Vector2(
                        (float)Random(0, 5),
                        (float)Random(0, 5)
                        );
                }

                var beat      = 509;
                int loopCount = (int)Math.Ceiling((line.EndTime - line.StartTime - 200) / (10 * beat / 4));
                var value     = line.Text;

                var lineY = SubtitleY;
                if (line.StartTime > 209149)
                {
                    lineY = 150;
                }

                var texture  = font.GetTexture(line.Text);
                var position = new Vector2(320 - texture.BaseWidth * FontScale * 0.5f, lineY)
                               + texture.OffsetFor(Origin) * FontScale;



                if (value != "Killing" || (line.StartTime < 38302 && line.StartTime >= 54573))
                {
                    var RCopy = layer.CreateSprite(texture.Path, Origin, position);
                    var BCopy = layer.CreateSprite(texture.Path, Origin, position);

                    RCopy.ScaleVec(line.StartTime, FontScale, FontScale);
                    RCopy.Fade(line.StartTime - 200, line.StartTime, 0, 0.5);
                    RCopy.Fade(line.EndTime - 200, line.EndTime, 0.5, 0);
                    RCopy.Color(line.StartTime - 200, 255, 0, 0);

                    RCopy.StartLoopGroup(line.StartTime - 200, loopCount);
                    for (int i = 0; i < 10; i++)
                    {
                        RCopy.Move(OsbEasing.OutBounce, beat / 4 * i, beat / 4 * (i + 1), position + shakePositionR[i], position - shakePositionR[i] / 2);
                    }
                    RCopy.EndGroup();


                    RCopy.ScaleVec(line.EndTime - 200, line.EndTime, FontScale, FontScale, FontScale + 0.5, 0);



                    BCopy.ScaleVec(line.StartTime, FontScale, FontScale);
                    BCopy.Fade(line.StartTime - 200, line.StartTime, 0, 0.5);
                    BCopy.Fade(line.EndTime - 200, line.EndTime, 0.5, 0);
                    BCopy.Color(line.StartTime - 200, 0.2, 0.8, 1);

                    BCopy.StartLoopGroup(line.StartTime - 200, loopCount);
                    for (int i = 0; i < 10; i++)
                    {
                        BCopy.Move(OsbEasing.OutBounce, beat / 4 * i, beat / 4 * (i + 1), position + shakePositionB[i], position - shakePositionB[i] / 2);
                    }
                    BCopy.EndGroup();

                    BCopy.ScaleVec(line.EndTime - 200, line.EndTime, FontScale, FontScale, FontScale + 0.5, 0);

                    RCopy.Additive(line.StartTime - 200, line.EndTime);
                    BCopy.Additive(line.StartTime - 200, line.EndTime);
                }

                var sprite = layer.CreateSprite(texture.Path, Origin, position);

                sprite.ScaleVec(line.StartTime, FontScale, FontScale);
                sprite.Fade(line.StartTime - 200, line.StartTime, 0, 1);
                sprite.Fade(line.EndTime - 200, line.EndTime, 1, 0);

                sprite.StartLoopGroup(line.StartTime - 200, loopCount);
                for (int i = 0; i < 10; i++)
                {
                    sprite.Move(OsbEasing.OutBounce, beat / 4 * i, beat / 4 * (i + 1), position + shakePosition[i], position - shakePosition[i] / 2);
                }
                sprite.EndGroup();


                sprite.ScaleVec(line.EndTime - 200, line.EndTime, FontScale, FontScale, FontScale + 0.5, 0);


                if (additive)
                {
                    sprite.Additive(line.StartTime - 200, line.EndTime);
                }

                if (value == "Killing")
                {
                    sprite.Color(line.StartTime - 200, 0.8, 0, 0);
                }
            }
        }
示例#12
0
 public SpriteSet AddSprite(String spritePath, OsbOrigin origin, Vector2 initialPosition)
 {
     sprites.Add(layer.CreateSprite(spritePath, origin, initialPosition));
     return(this);
 }
示例#13
0
        public override void Generate()
        {
            // Setting layer
            layer = GetLayer("Main");

            // Setting the font
            var font = LoadFont("sb/intro-chars", new FontDescription()
            {
                FontPath         = "fonts/QanelasSoftDEMO-ExtraBold.otf",
                FontSize         = 72,
                Color            = Color4.White,
                Padding          = Vector2.Zero,
                FontStyle        = FontStyle.Regular,
                TrimTransparency = true,
                EffectsOnly      = false,
                Debug            = false,
            },
                                new FontOutline()
            {
                Thickness = 0,
                Color     = Color.Transparent,
            },
                                new FontShadow()
            {
                Thickness = 0,
                Color     = Color.Transparent,
            });

            var k          = font.GetTexture("K");
            var kSprite    = layer.CreateSprite(k.Path, OsbOrigin.TopCentre);
            var four       = font.GetTexture("4");
            var fourSprite = layer.CreateSprite(four.Path, OsbOrigin.TopCentre);
            var l          = font.GetTexture("L");
            var lSprite    = layer.CreateSprite(l.Path, OsbOrigin.TopCentre);
            var one        = font.GetTexture("1");
            var oneSprite  = layer.CreateSprite(one.Path, OsbOrigin.TopCentre);

            setupTitle(kSprite, 484, new Vector2(265, 240));
            setupTitle(fourSprite, 484 + 50, new Vector2(305, 240));
            setupTitle(lSprite, 484 + 100, new Vector2(345, 240));
            setupTitle(oneSprite, 484 + 150, new Vector2(375, 240));
            // Vertical bar and mask
            var mask = layer.CreateSprite("sb/pixel.png", OsbOrigin.TopCentre);

            mask.Scale(13, 400);
            mask.Fade(13, 1583, 1, 1);
            mask.Color(13, Color4.Black);

            var line = layer.CreateSprite("sb/pixel.png");

            line.ScaleVec(13, 327, 0, 0, 1, 1);
            line.ScaleVec(OsbEasing.InOutCirc, 327, 641, 1, 1, 150, 1);
            line.Fade(13, 7111 - 200, 1, 1);
            line.Fade(7111, 7111 + 150, 1, 0);

            //Presents

            var presents = layer.CreateSprite("sb/presents.png", OsbOrigin.Centre, new Vector2(320, 260));

            presents.Scale(641, 0.2);
            presents.Fade(641, 641 + 200, 0, 1);
            presents.Fade(1583 - 200, 1583, 1, 0);
        }
示例#14
0
 public override void GenerateSprite(StoryboardLayer layer)
 {
     sprite0 = sprite0 ?? layer.CreateSprite(SpritePath, OsbOrigin.BottomLeft);
     sprite1 = sprite1 ?? layer.CreateSprite(SpritePath, OsbOrigin.BottomRight);
 }
示例#15
0
        public override void Generate()
        {
            //init
            var startPosition = PositionAt(0f);

            layer = GetLayer("");
            GenerateImage();

            //curved image
            var logoBack = layer.CreateSprite("sb/logoBack.png", OsbOrigin.Centre, new Vector2(320, 230));

            logoBack.Scale(StartTime, .5f);
            logoBack.Fade(EndTime, .7f);

            //cover generation
            for (int i = 0; i < StepSize; i++)
            {
                var sprite = layer.CreateSprite("sb/pixel.png", OsbOrigin.CentreRight, PositionAt(i / (float)StepSize));
                sprite.Color(StartTime, Color4.Black);

                var prev = PositionAt(i / (float)StepSize);
                var next = PositionAt((i + 1) / (float)StepSize);

                sprite.ScaleVec(StartTime + i * SegmentDelay, (prev - next).Length + 10, 15);
                sprite.Rotate(StartTime, RotationAt(i / (float)StepSize) + Math.PI);

                if (sprite.CommandsEndTime > 186805)
                {
                    sprite.Fade(sprite.CommandsStartTime, 1f);
                    sprite.Fade(186805, 0f);
                }
            }

            //lines
            ConnectPoints(0f, DotPositions[0]);
            ConnectPoints(0f, DotPositions[1]);
            ConnectPoints(0f, DotPositions[3]);

            ConnectPoints(DotPositions[0], DotPositions[2]);

            ConnectPoints(DotPositions[0], 1f);
            ConnectPoints(DotPositions[2], 1f);

            //gradient (used to make the transition smooth and to hide the cover when it jumps out of existence)
            var gradient = layer.CreateSprite("sb/logoGradient.png", OsbOrigin.Centre, startPosition);

            gradient.ScaleVec(StartTime, .6, 20);
            gradient.Color(StartTime, Color4.Black);
            gradient.Fade(186805, MidTime, 1f, 0f);
            FollowCurve(gradient, rotate: true);

            //section background
            var background = layer.CreateSprite("sb/introbackground01.jpg");

            background.Scale(185569, 480.0f / 1080);
            background.Additive(185569, 190511);

            //vignette
            GenerateVignette();

            //big dots along the curve
            for (int i = 3; i >= 0; i--)
            {
                var dot = layer.CreateSprite("sb/logoDot.png", OsbOrigin.Centre, PositionAt(i == 0 ? 0f : DotPositions[i - 1]));
                dot.Scale(EndTime, 2 - i / 2f);

                FollowCurve(dot, start: i == 0 ? 0f : DotPositions[i - 1], end: DotPositions[i]);
            }

            //Text
            var text = layer.CreateSprite("sb/logoText.png", OsbOrigin.Centre, new Vector2(310, 245));

            text.Scale(OsbEasing.InOutSine, StartTime, EndTime, .49f, .5f);
            text.Fade(OsbEasing.OutSine, StartTime, EndTime, .8f, 1f);
        }
示例#16
0
 public override void GenerateSprite(StoryboardLayer layer)
 {
     sprite = sprite ?? layer.CreateSprite(SpritePath, SpriteOrigin);
 }
        public void generateSquares(int time, int endtime)
        {
            SquareSprite[,] gridSquares = new SquareSprite[10, 10];
            int limit = 1;

            gridSquares[0, 0] = new SquareSprite(layer.CreateSprite(squarePath, OsbOrigin.Centre, origin), time, layer);

            for (int i = 0; i < 1; i++)
            {
                rotateAll(2526, gridSquares, limit, 8);

                duplicationTR(3782, gridSquares, limit);
                limit++;

                rotateAll(4096, gridSquares, limit, 4);

                duplicationTR(4725, gridSquares, limit);
                limit++;

                duplicationTR(5039, gridSquares, limit);
                limit++;

                rotateAll(5353, gridSquares, limit, 6);

                duplicationTR(6295, gridSquares, limit);
                limit++;

                rotateAll(6609, gridSquares, limit, 2);

                revDuplicationTR(6923, gridSquares, limit);

                duplicationTR(7552, gridSquares, limit);
                limit++;

                rotateAll(7866, gridSquares, limit, 6);

                duplicationTR(8808, gridSquares, limit);
                limit++;

                rotateAll(9122, gridSquares, limit, 4);

                duplicationTR(9751, gridSquares, limit);
                limit++;

                duplicationTR(10065, gridSquares, limit);
                limit++;

                rotateAll(10379, gridSquares, limit, 6);

                duplicationTR(11321, gridSquares, limit);
                limit++;

                rotateAll(11636, gridSquares, limit, 2);

                //revDuplicationTR(11950,gridSquares,limit);
            }

            Wiggle(11950, gridSquares);

            dualTap(12578, 4, ref gridSquares[6, 6], ref gridSquares[6, 7], Color4.DarkCyan, Color4.Cyan);

            snake(12578, gridSquares, Beatmap.ComboColors.ElementAt(0));

            fadeAllOut(22630, gridSquares, limit);
        }
示例#18
0
        public void generatePerCharacter(FontGenerator font, SubtitleSet subtitles, StoryboardLayer layer, bool additive)
        {
            foreach (var subtitleLine in subtitles.Lines)
            {
                var letterY = SubtitleY;
                foreach (var line in subtitleLine.Text.Split('\n'))
                {
                    var lineWidth  = 0f;
                    var lineHeight = 0f;
                    foreach (var letter in line)
                    {
                        var texture = font.GetTexture(letter.ToString());
                        lineWidth += texture.BaseWidth * FontScale;
                        lineHeight = Math.Max(lineHeight, texture.BaseHeight * FontScale);
                    }
                    float letterX;

                    int length = subtitleLine.Text.Length;
                    if (length > 30)
                    {
                        letterX = 10;
                    }
                    else if (length > 20)
                    {
                        letterX = 0;
                    }
                    else
                    {
                        letterX = -10;
                    }


                    var initX = letterX;
                    foreach (var letter in line)
                    {
                        var texture = font.GetTexture(letter.ToString());
                        if (!texture.IsEmpty)
                        {
                            var position = new Vector2(letterX, letterY)
                                           + texture.OffsetFor(Origin) * FontScale;

                            var angle = 15.5155 * Math.PI / 180;

                            var     Radius = position.X - initX;
                            var     x      = Radius * Math.Cos(angle) + initX;
                            var     y      = Radius * Math.Sin(angle) + letterY;
                            Vector2 newPos = new Vector2((float)x, (float)y);

                            Vector2 extraMovement = new Vector2(15f, 5f);

                            Vector2 startPoint = new Vector2(150f, 40f);

                            var layer2 = GetLayer("Background");

                            var redSquare = layer2.CreateSprite("sb/babysquare.png", Origin, newPos);
                            redSquare.Color(subtitleLine.StartTime, 1, 0, 0);
                            redSquare.Fade(subtitleLine.StartTime - 200, subtitleLine.StartTime, 0, 0.15);
                            redSquare.Fade(subtitleLine.EndTime - 200, subtitleLine.EndTime, 0.15, 0);
                            redSquare.Scale(subtitleLine.StartTime, Random(0, 2.5));
                            redSquare.Rotate(subtitleLine.StartTime - 200, subtitleLine.EndTime, Random(-2, 2), Random(-2, 2));

                            var sprite = layer.CreateSprite(texture.Path, Origin, startPoint);
                            sprite.Move(OsbEasing.OutExpo, subtitleLine.StartTime - 200, subtitleLine.StartTime + 200, newPos - startPoint, newPos);
                            sprite.Move(subtitleLine.StartTime + 200, subtitleLine.EndTime, newPos, newPos + extraMovement);
                            sprite.Scale(subtitleLine.StartTime, FontScale);
                            sprite.Fade(subtitleLine.StartTime - 200, subtitleLine.StartTime, 0, 1);
                            sprite.Fade(subtitleLine.EndTime - 200, subtitleLine.EndTime, 1, 0);
                            sprite.Rotate(subtitleLine.StartTime, angle);
                            sprite.Scale(subtitleLine.StartTime - 200, subtitleLine.StartTime, 0.05, 0.25);

                            if (additive)
                            {
                                sprite.Additive(subtitleLine.StartTime - 200, subtitleLine.EndTime);
                            }
                        }
                        letterX += texture.BaseWidth * FontScale;
                    }
                    letterY += lineHeight;
                }
            }
        }
示例#19
0
 protected virtual OsbSprite CreateSprite(StoryboardLayer layer, string path, OsbOrigin origin)
 => layer.CreateSprite(path, origin);
示例#20
0
        void Section4_1()
        {
            // circle
            int   s    = 62840;
            int   e    = 63468;
            float fade = 1;

            layer      = GetLayer("");
            maskLayer  = GetLayer("masks");
            maskLayer2 = GetLayer("masks2");
            var downwardsMovement = new Movement(OsbEasing.OutExpo, s, e, Vectors.Centre + Vectors.up(100), Vectors.Centre);

            var ring1     = maskLayer2.CreateSprite(Sprites.Circle, OsbOrigin.Centre, downwardsMovement.StartPosition);
            var ring1Mask = maskLayer2.CreateSprite(Sprites.Circle, OsbOrigin.Centre, downwardsMovement.StartPosition);

            int   circleWidth   = GetMapsetBitmap(Sprites.Circle).Width;
            float width         = 350.0f;
            float width2        = 250.0f;
            float scale         = width / circleWidth;
            float thickness     = 10;
            float lineThickness = thickness * 0.71f;
            float maskScale     = (width - thickness * 2) / circleWidth / scale;

            ring1.Fade(s, e, fade, fade);
            ring1.Scale(OsbEasing.OutExpo, s, e - Timing.beat(s), scale, scale / width * width2);
            ring1.Move(downwardsMovement);

            ring1Mask.Fade(s, e, 1, 1);
            ring1Mask.Color(s, Color4.Black); ring1Mask.Scale(OsbEasing.OutExpo, s, e - Timing.beat(s), scale * maskScale, scale * maskScale / width * width2);
            ring1Mask.Move(downwardsMovement);

            // 3d ring
            float startOfRotation = e - 1.25f * (float)Timing.beat(s);
            var   inOutExpo       = OsbEasing.InOutExpo.ToEasingFunction();
            var   outExpo         = OsbEasing.OutExpo.ToEasingFunction();
            Func <float, float, Vector3> moving3DCircle = (float t, float time) =>
            {
                float   tilt   = time < startOfRotation ? 0 : (float)inOutExpo((time - startOfRotation) / (e - startOfRotation));
                Vector3 centre = downwardsMovement.PositionAtTime(time).withZ(0);
                float   radius = (MathHelper.Clamp(
                                      InterpolatingFunctions.Float(width, width2, outExpo((time - s) / (e - Timing.beat(s) - s))),
                                      width2, width
                                      ) - thickness) / 2;

                Vector3 rot1 = new Vector3(
                    5 * (float)Math.PI / 16,
                    (float)Math.PI / 2,
                    0
                    );

                Vector3 rot2 = new Vector3(
                    5 * (float)Math.PI / 16,
                    (float)Math.PI / 4,
                    0
                    );

                Vector3 rot = Vector3.Lerp(rot1, rot2, tilt);

                var res = radius * new Vector3(
                    (float)Math.Cos(-t),
                    (float)Math.Sin(-t),
                    0
                    ).rotateX(rot.X).rotateY(rot.Y).rotateZ(rot.Z) + centre;
                return(res);
            };

            int   count    = 200;
            float dotScale = lineThickness / circleWidth;

            for (int i = 0; i < count; i++)
            {
                var sprite = layer.CreateSprite(Sprites.Circle, OsbOrigin.Centre);
                sprite.Fade(s, e, 1, 1);
                for (float t = s; t < e; t += delta)
                {
                    float t2 = t + delta < e ? t + delta : e;

                    Vector3 p1 = moving3DCircle(
                        i * 2 * (float)Math.PI / count,
                        t
                        );

                    Vector3 p2 = moving3DCircle(
                        i * 2 * (float)Math.PI / count,
                        t2
                        );

                    sprite.Move3D(
                        OsbEasing.None,
                        t, t2,
                        p1, p2,
                        FOV,
                        (_sprite, _p1, _p2) =>
                    {
                        float scale1 = dotScale / _p1.normalisedVector.Length;
                        float scale2 = dotScale / _p2.normalisedVector.Length;
                        if (scale1 != scale2)
                        {
                            _sprite.Scale(t, t2, scale1, scale2);
                        }
                    }
                        );
                }
            }

            // dotted line through the sphere
            count = 35;
            float opacity             = 1;
            float lineAppearStart     = s + (float)Timing.beat(s) / 3;
            float appearDelay         = (float)Timing.beat(s) / 2 / count;
            float length              = width2 + 2 * 70;
            float dottedLineThickness = 1.2f;

            SpriteSet axisDottedLine = maskLayer.CreateSpriteSet(
                Sprites.Pixel,
                _ => OsbOrigin.TopCentre,
                Patterns.Line2D(Vectors.Centre + Vectors.up(length / 2), Vectors.Centre + Vectors.down(length / 2), count),
                count
                );

            var dotMovement = new Movement(OsbEasing.OutQuint, s + Timing.beat(s) / 3, e, Vectors.Centre + Vectors.up(100), Vectors.Centre);

            axisDottedLine.MoveRelative(dotMovement - Vectors.Centre);
            axisDottedLine.ScaleVec((int)lineAppearStart, new Vector2(dottedLineThickness, length / count / 2));

            axisDottedLine.Fade(
                OsbEasing.None,
                i => lineAppearStart + i * appearDelay,
                i => lineAppearStart + i * appearDelay + 100,
                0, opacity
                );
            axisDottedLine.Fade(e, 0);

            SpriteSet gradientMask = maskLayer.CreateSpriteSet(Sprites.TransparentGradient, _ => OsbOrigin.CentreRight, 2);

            gradientMask.Rotate(lineAppearStart, i => Math.PI / 2 + i * Math.PI);
            float gradientWidth = GetMapsetBitmap(Sprites.TransparentGradient).Width;

            gradientMask.ScaleVec(lineAppearStart, new Vector2(length / 2 / gradientWidth, dottedLineThickness));
            gradientMask.AddSprites(
                Sprites.Pixel,
                i => (i % 2 == 0 ? OsbOrigin.BottomCentre : OsbOrigin.TopCentre),
                i => Vectors.Centre + (i % 2 == 0 ? 1 : -1) * Vectors.up(length / 2),
                2
                );
            float gradientExtension = Vectors.Centre.Y - length / 2;

            gradientMask.ScaleVec(lineAppearStart, new Vector2(dottedLineThickness, gradientExtension), 2);
            gradientMask.Color(lineAppearStart, Color4.Black);
            gradientMask.Fade(lineAppearStart, e, 1.0, 1.0);

            SpriteSet cover = maskLayer.CreateSpriteSet(Sprites.Pixel, 2);

            cover.Move(i => downwardsMovement.ResampledSection(lineAppearStart, e, delta)
                       + Vectors.up((width2 - lineThickness) / 2) * (i % 2 == 0 ? 1 : -1));
            cover.Fade(lineAppearStart, e, 1.0, 1.0);
            cover.ScaleVec(lineAppearStart, new Vector2(dottedLineThickness, lineThickness));

            // point cloud
            count = 50;
            float pointScale = 0.2f;
            var   pattern    = Patterns.PointCloudGlobe(Vectors.Centre.withZ(0), 500, new Random(RandomSeed));
            var   points     = new List <Vector3>();

            for (int i = 0; i < count; i++)
            {
                points.Add(pattern(i));
            }
            SpriteSet pointCloud = layer.CreateSpriteSet(
                Sprites.Particle,
                _ => OsbOrigin.Centre,
                i => points[i].project(Vectors.ScreenSize, Vectors.Centre, FOV).screenSpaceVector,
                count
                );

            pointCloud.Fade(startOfRotation, startOfRotation + Timing.beat(s) / 2, 0, 0.6);
            pointCloud.Fade(e, 0);
            pointCloud.Scale(startOfRotation, 5);
            for (float t = startOfRotation; t < e; t += delta)
            {
                float t2     = t + delta < e ? t + delta : e;
                float angle  = (float)(-Math.PI / 4 * inOutExpo((t - startOfRotation) / (e - startOfRotation)));
                float angle2 = (float)(-Math.PI / 4 * inOutExpo((t2 - startOfRotation) / (e - startOfRotation)));
                pointCloud.Move3D(
                    OsbEasing.None,
                    t, t2,
                    i => points[i].rotateY(angle, Vectors.Centre3D),
                    i => points[i].rotateY(angle2, Vectors.Centre3D),
                    FOV,
                    (_sprite, _p1, _p2) =>
                {
                    float scale1 = pointScale / _p1.normalisedVector.Length;
                    float scale2 = pointScale / _p2.normalisedVector.Length;
                    if (scale1 != scale2)
                    {
                        _sprite.Scale(t, t2, scale1, scale2);
                    }
                }
                    );
            }
            foreach (var sprite in pointCloud.Sprites)
            {
                SpriteSet trail = Effects.Trail(layer, sprite, startOfRotation, e, 1000.0 / 60, 0, 0, 150, true);
                trail.UseScaleOf(sprite);
            }
        }
        public void generatePerLine(FontGenerator font, SubtitleSet subtitles, StoryboardLayer layer, bool additive)
        {
            var positionList = new TupleList <int, int> {
                { 120, 100 }, //I'll
                { 230, 100 }, //find
                { 370, 100 }, //some
                { 120, 138 }, //peace
                { 120, 192 }, //this
                { 120, 254 }, //time
                { 306, 194 }, //i'll
                { 410, 194 }, //let
                { 306, 254 }, //you
                { 120, 312 }, //Know
                { 155, 160 }, //we're
                { 325, 160 }, //gonna
                { 155, 206 }, //grow
                { 110, 100 }, //i'm
                { 180, 100 }, //gonna
                { 250, 146 }, //show
                { 316, 190 }, //you
                { 110, 146 }, //my
                { 110, 240 }, //Heart
                { 340, 240 }, //and
                { 110, 300 }, //soul
                { 200, 150 }, // this
                { 325, 150 }, //time
                { 138, 190 }, //this
                { 325, 190 }, //time
                { 170, 140 }, //my
                { 150, 180 }, //love
                { 3, 1 },
                { 1, 1 }
            };
            var scaleList = new TupleList <double, double> {
                { 0.35, 0.35 },  //I'll
                { 0.35, 0.35 },  //find
                { 0.35, 0.35 },  //some
                { 0.845, 0.50 }, //peace
                { 0.55, 0.55 },  //this
                { 0.55, 0.55 },  //time
                { 0.45, 0.45 },  //i'll
                { 0.42, 0.45 },  //let
                { 0.65, 0.53 },  //you
                { 0.900, 0.60 }, //Know
                { 0.35, 0.35 },  //we're
                { 0.35, 0.35 },  //gonna
                { 0.78, 1.3 },   //grow
                { 0.35, 0.35 },  //i'm
                { 0.35, 0.35 },  //gonna
                { 0.35, 0.35 },  //you
                { 0.35, 0.35 },  //show
                { 0.65, 0.80 },  //my
                { 0.45, 0.50 },  //Heart
                { 0.45, 0.5 },   //and
                { 1.1, 0.80 },   //soul
                { 0.35, 0.35 },  // this
                { 0.35, 0.35 },  //time
                { 0.55, 0.55 },  //this
                { 0.55, 0.55 },  //time
                { 0.35, 0.35 },  //my
                { 0.75, 0.75 },  //love
            };
            var angleList = new List <int> {
                0, //I'll
                0, //find
                0, //some
                0, //peace
                0, //this
                0, //time
                0, //i'll
                0, //let
                0, //you
                0, //Know
                0, //we're
                0, //gonna
                0, //grow
                0, //i'm
                0, //gonna
                0, //show
                0, //you
                0, //my
                0, //Heart
                0, //and
                0, //soul
                0, // this
                0, //time
                0, //this
                0, //time
                0, //my
                0, //love
            };
            var colorList = new List <Color4> {
                Color4.White,          //I'll
                Color4.White,          //find
                Color4.White,          //some
                Color4.MediumSeaGreen, //peace
                Color4.White,          //this
                Color4.MediumSeaGreen, //time
                Color4.White,          //i'll
                Color4.White,          //let
                Color4.White,          //you
                Color4.CornflowerBlue, //Know
                Color4.White,          //we're
                Color4.White,          //gonna
                Color4.CornflowerBlue, //grow
                Color4.White,          //i'm
                Color4.White,          //gonna
                Color4.CornflowerBlue, //show
                Color4.White,          //you
                Color4.White,          //my
                Color4.Red,            //Heart
                Color4.White,          //and
                Color4.Red,            //soul
                Color4.White,          // this
                Color4.MediumSeaGreen, //time
                Color4.White,          //this
                Color4.MediumSeaGreen, //time
                Color4.White,          //my
                Color4.Red,            //love
            };
            var run = 0;

            foreach (var line in subtitles.Lines)
            {
                var texture  = font.GetTexture(line.Text);
                var position = new Vector2(positionList[run].Item1, positionList[run].Item2);
                var sprite   = layer.CreateSprite(texture.Path, Origin, position);
                sprite.ScaleVec(line.StartTime, scaleList[run].Item1, scaleList[run].Item2);
                sprite.Fade(line.StartTime - 100, line.StartTime, 0, 1);
                sprite.Fade(line.EndTime - 100, line.EndTime, 1, 0);
                sprite.Rotate(line.EndTime - 100, MathHelper.DegreesToRadians(angleList[run]));
                sprite.Color(line.StartTime, colorList[run]);
                run += 1;
            }
        }
        //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);
        }