A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5using osu.Framework.Allocation;
6using osu.Framework.Caching;
7using osu.Framework.Graphics.Textures;
8using osuTK.Graphics;
9using SixLabors.ImageSharp;
10using SixLabors.ImageSharp.PixelFormats;
11
12namespace osu.Framework.Graphics.Lines
13{
14 public class SmoothPath : Path
15 {
16 [BackgroundDependencyLoader]
17 private void load()
18 {
19 validateTexture();
20 }
21
22 public override float PathRadius
23 {
24 get => base.PathRadius;
25 set
26 {
27 if (base.PathRadius == value)
28 return;
29
30 base.PathRadius = value;
31
32 InvalidateTexture();
33 }
34 }
35
36 private readonly Cached textureCache = new Cached();
37
38 protected void InvalidateTexture()
39 {
40 textureCache.Invalidate();
41 Invalidate(Invalidation.DrawNode);
42 }
43
44 private void validateTexture()
45 {
46 if (textureCache.IsValid)
47 return;
48
49 int textureWidth = (int)PathRadius * 2;
50
51 //initialise background
52 var raw = new Image<Rgba32>(textureWidth, 1);
53
54 const float aa_portion = 0.02f;
55
56 for (int i = 0; i < textureWidth; i++)
57 {
58 float progress = (float)i / (textureWidth - 1);
59
60 var colour = ColourAt(progress);
61 raw[i, 0] = new Rgba32(colour.R, colour.G, colour.B, colour.A * Math.Min(progress / aa_portion, 1));
62 }
63
64 var texture = new DisposableTexture(textureWidth, 1, true);
65 texture.SetData(new TextureUpload(raw));
66 Texture = texture;
67
68 textureCache.Validate();
69 }
70
71 internal override DrawNode GenerateDrawNodeSubtree(ulong frame, int treeIndex, bool forceNewDrawNode)
72 {
73 validateTexture();
74 return base.GenerateDrawNodeSubtree(frame, treeIndex, forceNewDrawNode);
75 }
76
77 /// <summary>
78 /// Retrieves the colour from a position in the texture of the <see cref="Path"/>.
79 /// </summary>
80 /// <param name="position">The position within the texture. 0 indicates the outermost-point of the path, 1 indicates the centre of the path.</param>
81 protected virtual Color4 ColourAt(float position) => Color4.White;
82 }
83}