A game framework written with osu! in mind.
at master 7.3 kB view raw
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.Graphics; 6using osu.Framework.Graphics.Lines; 7using osu.Framework.Graphics.Sprites; 8using osu.Framework.Graphics.Textures; 9using osu.Framework.Input; 10using osu.Framework.Input.Events; 11using osu.Framework.Testing; 12using osuTK; 13using osuTK.Graphics; 14using SixLabors.ImageSharp; 15using SixLabors.ImageSharp.PixelFormats; 16 17namespace osu.Framework.Tests.Visual.Input 18{ 19 [System.ComponentModel.Description("live path optimiastion")] 20 public class TestSceneInputResampler : GridTestScene 21 { 22 public TestSceneInputResampler() 23 : base(3, 3) 24 { 25 const int width = 2; 26 Texture gradientTexture = new Texture(width, 1, true); 27 var image = new Image<Rgba32>(width, 1); 28 29 for (int i = 0; i < width; ++i) 30 { 31 var brightnessByte = (byte)((float)i / (width - 1) * 255); 32 image[i, 0] = new Rgba32(brightnessByte, brightnessByte, brightnessByte); 33 } 34 35 gradientTexture.SetData(new TextureUpload(image)); 36 37 SpriteText[] text = new SpriteText[6]; 38 39 Cell(0, 0).AddRange(new Drawable[] 40 { 41 text[0] = createLabel("Raw"), 42 new ArcPath(true, true, new InputResampler(), gradientTexture, Color4.Green, text[0]), 43 }); 44 45 Cell(0, 1).AddRange(new Drawable[] 46 { 47 text[1] = createLabel("Rounded (resembles mouse input)"), 48 new ArcPath(true, false, new InputResampler(), gradientTexture, Color4.Blue, text[1]), 49 }); 50 51 Cell(0, 2).AddRange(new Drawable[] 52 { 53 text[2] = createLabel("Custom: Smoothed=0, Raw=0"), 54 new UserDrawnPath 55 { 56 DrawText = text[2], 57 Texture = gradientTexture, 58 Colour = Color4.White, 59 }, 60 }); 61 62 Cell(1, 0).AddRange(new Drawable[] 63 { 64 text[3] = createLabel("Smoothed raw"), 65 new ArcPath(false, true, new InputResampler(), gradientTexture, Color4.Green, text[3]), 66 }); 67 68 Cell(1, 1).AddRange(new Drawable[] 69 { 70 text[4] = createLabel("Smoothed rounded"), 71 new ArcPath(false, false, new InputResampler(), gradientTexture, Color4.Blue, text[4]), 72 }); 73 74 Cell(1, 2).AddRange(new Drawable[] 75 { 76 text[5] = createLabel("Smoothed custom: Smoothed=0, Raw=0"), 77 new SmoothedUserDrawnPath 78 { 79 DrawText = text[5], 80 Texture = gradientTexture, 81 Colour = Color4.White, 82 InputResampler = new InputResampler(), 83 }, 84 }); 85 86 Cell(2, 0).AddRange(new Drawable[] 87 { 88 text[3] = createLabel("Force-smoothed raw"), 89 new ArcPath(false, true, new InputResampler { ResampleRawInput = true }, gradientTexture, Color4.Green, text[3]), 90 }); 91 92 Cell(2, 1).AddRange(new Drawable[] 93 { 94 text[4] = createLabel("Force-smoothed rounded"), 95 new ArcPath(false, false, new InputResampler { ResampleRawInput = true }, gradientTexture, Color4.Blue, text[4]), 96 }); 97 98 Cell(2, 2).AddRange(new Drawable[] 99 { 100 text[5] = createLabel("Force-smoothed custom: Smoothed=0, Raw=0"), 101 new SmoothedUserDrawnPath 102 { 103 DrawText = text[5], 104 Texture = gradientTexture, 105 Colour = Color4.White, 106 InputResampler = new InputResampler 107 { 108 ResampleRawInput = true 109 }, 110 }, 111 }); 112 } 113 114 private SpriteText createLabel(string text) => new SpriteText 115 { 116 Text = text, 117 Font = new FontUsage(size: 14), 118 Colour = Color4.White, 119 }; 120 121 private class SmoothedPath : TexturedPath 122 { 123 protected SmoothedPath() 124 { 125 PathRadius = 2; 126 } 127 128 public InputResampler InputResampler { get; set; } = new InputResampler(); 129 130 protected int NumVertices { get; set; } 131 132 protected int NumRaw { get; set; } 133 134 protected void AddRawVertex(Vector2 pos) 135 { 136 NumRaw++; 137 AddVertex(pos); 138 NumVertices++; 139 } 140 141 protected bool AddSmoothedVertex(Vector2 pos) 142 { 143 NumRaw++; 144 bool foundOne = false; 145 146 foreach (Vector2 relevant in InputResampler.AddPosition(pos)) 147 { 148 AddVertex(relevant); 149 NumVertices++; 150 foundOne = true; 151 } 152 153 return foundOne; 154 } 155 } 156 157 private class ArcPath : SmoothedPath 158 { 159 public ArcPath(bool raw, bool keepFraction, InputResampler inputResampler, Texture texture, Color4 colour, SpriteText output) 160 { 161 InputResampler = inputResampler; 162 163 AutoSizeAxes = Axes.None; 164 RelativeSizeAxes = Axes.Both; 165 Texture = texture; 166 Colour = colour; 167 168 const float target_raw = 1024; 169 170 for (float i = 0; i < target_raw; i++) 171 { 172 float x = (MathF.Sin(i / target_raw * (MathF.PI * 0.5f)) * 200) + 50.5f; 173 float y = (MathF.Cos(i / target_raw * (MathF.PI * 0.5f)) * 200) + 50.5f; 174 Vector2 v = keepFraction ? new Vector2(x, y) : new Vector2((int)x, (int)y); 175 if (raw) 176 AddRawVertex(v); 177 else 178 AddSmoothedVertex(v); 179 } 180 181 output.Text += ": Smoothed=" + NumVertices + ", Raw=" + NumRaw; 182 } 183 } 184 185 private class UserDrawnPath : SmoothedPath 186 { 187 public SpriteText DrawText; 188 189 public UserDrawnPath() 190 { 191 AutoSizeAxes = Axes.None; 192 RelativeSizeAxes = Axes.Both; 193 } 194 195 protected virtual void AddUserVertex(Vector2 v) => AddRawVertex(v); 196 197 protected override bool OnDragStart(DragStartEvent e) 198 { 199 AddUserVertex(e.MousePosition); 200 DrawText.Text = "Custom Smoothed Drawn: Smoothed=" + NumVertices + ", Raw=" + NumRaw; 201 return true; 202 } 203 204 protected override void OnDrag(DragEvent e) 205 { 206 AddUserVertex(e.MousePosition); 207 DrawText.Text = "Custom Smoothed Drawn: Smoothed=" + NumVertices + ", Raw=" + NumRaw; 208 base.OnDrag(e); 209 } 210 } 211 212 private class SmoothedUserDrawnPath : UserDrawnPath 213 { 214 protected override void AddUserVertex(Vector2 v) => AddSmoothedVertex(v); 215 } 216 } 217}