Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SpriteUtilities.cs 2.3KB

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