A game about forced loneliness, made by TACStudios
at master 53 lines 2.4 kB view raw
1using Unity.Collections.LowLevel.Unsafe; 2using UnityEngine.Experimental.Rendering; 3 4namespace UnityEngine.InputSystem.Utilities 5{ 6 internal static class SpriteUtilities 7 { 8 public static unsafe Sprite CreateCircleSprite(int radius, Color32 colour) 9 { 10 // cache the diameter 11 var d = radius * 2; 12 13 var texture = new Texture2D(d, d, DefaultFormat.LDR, TextureCreationFlags.None); 14 var colours = texture.GetRawTextureData<Color32>(); 15 var coloursPtr = (Color32*)colours.GetUnsafePtr(); 16 UnsafeUtility.MemSet(coloursPtr, 0, colours.Length * UnsafeUtility.SizeOf<Color32>()); 17 18 // pack the colour into a ulong so we can write two pixels at a time to the texture data 19 var colorPtr = (uint*)UnsafeUtility.AddressOf(ref colour); 20 var colourAsULong = *(ulong*)colorPtr << 32 | *colorPtr; 21 22 float rSquared = radius * radius; 23 24 // loop over the texture memory one column at a time filling in a line between the two x coordinates 25 // of the circle at each column 26 for (var y = -radius; y < radius; y++) 27 { 28 // for the current column, calculate what the x coordinate of the circle would be 29 // using x^2 + y^2 = r^2, or x^2 = r^2 - y^2. The square root of the value of the 30 // x coordinate will equal half the width of the circle at the current y coordinate 31 var halfWidth = (int)Mathf.Sqrt(rSquared - y * y); 32 33 // position the pointer so it points at the memory where we should start filling in 34 // the current line 35 var ptr = coloursPtr 36 + (y + radius) * d // the position of the memory at the start of the row at the current y coordinate 37 + radius - halfWidth; // the position along the row where we should start inserting colours 38 39 // fill in two pixels at a time 40 for (var x = 0; x < halfWidth; x++) 41 { 42 *(ulong*)ptr = colourAsULong; 43 ptr += 2; 44 } 45 } 46 47 texture.Apply(); 48 49 var sprite = Sprite.Create(texture, new Rect(0, 0, d, d), new Vector2(radius, radius), 1, 0, SpriteMeshType.FullRect); 50 return sprite; 51 } 52 } 53}