Seven is the number.
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.

152 lines
4.7 KiB

3 years ago
3 years ago
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. namespace LeTai.TrueShadow
  5. {
  6. class ShadowSettingSnapshot
  7. {
  8. public readonly TrueShadow shadow;
  9. public readonly Canvas canvas;
  10. public readonly RectTransform canvasRt;
  11. public readonly bool shouldAntialiasImprint;
  12. public readonly float canvasScale;
  13. public readonly float size;
  14. public readonly Vector2 canvasRelativeOffset;
  15. public readonly Vector2 dimensions;
  16. internal ShadowSettingSnapshot(TrueShadow shadow)
  17. {
  18. this.shadow = shadow;
  19. canvas = shadow.Graphic.canvas;
  20. canvasRt = (RectTransform) canvas.transform;
  21. var meshBound = shadow.SpriteMesh.bounds;
  22. shouldAntialiasImprint = canvas.renderMode != RenderMode.ScreenSpaceOverlay;
  23. canvasScale = canvas.scaleFactor;
  24. var canvasRelativeRotation = Quaternion.Inverse(canvasRt.rotation) * shadow.RectTransform.rotation;
  25. canvasRelativeOffset = shadow.Offset.Rotate(-canvasRelativeRotation.eulerAngles.z) * canvasScale;
  26. dimensions = (Vector2) meshBound.size * canvasScale;
  27. size = shadow.Size * canvasScale;
  28. CalcHash();
  29. }
  30. const int DIMENSIONS_HASH_STEP = 1;
  31. void CalcHash()
  32. {
  33. var graphic = shadow.Graphic;
  34. int canvasScaleHash = (int) (canvasScale * 1e4);
  35. int insetHash = shadow.Inset ? 1 : 0;
  36. var clearColor = shadow.ClearColor;
  37. var imageColor = graphic.color;
  38. int colorHash = HashUtils.CombineHashCodes(
  39. shadow.IgnoreCasterColor ? 1 : 0,
  40. (int) shadow.ColorBleedMode,
  41. (int) (imageColor.r * 255),
  42. (int) (imageColor.g * 255),
  43. (int) (imageColor.b * 255),
  44. (int) (imageColor.a * 255),
  45. (int) (clearColor.r * 255),
  46. (int) (clearColor.g * 255),
  47. (int) (clearColor.b * 255),
  48. (int) (clearColor.a * 255)
  49. );
  50. // Hack until we have separated cutout cache, or proper sibling mode
  51. int offsetHash = HashUtils.CombineHashCodes(
  52. shadow.Cutout ? 1 : 0,
  53. (int) (canvasRelativeOffset.x * 100),
  54. (int) (canvasRelativeOffset.y * 100)
  55. );
  56. // Tiled type cannot be batched by similar size
  57. int dimensionHash = graphic is Image im && im.type == Image.Type.Tiled
  58. ? dimensions.GetHashCode()
  59. : HashUtils.CombineHashCodes(
  60. Mathf.CeilToInt(dimensions.x / DIMENSIONS_HASH_STEP) * DIMENSIONS_HASH_STEP,
  61. Mathf.CeilToInt(dimensions.y / DIMENSIONS_HASH_STEP) * DIMENSIONS_HASH_STEP
  62. );
  63. var sizeHash = Mathf.CeilToInt(size * 100);
  64. var commonHash = HashUtils.CombineHashCodes(
  65. shadow.TextureRevision,
  66. canvasScaleHash,
  67. insetHash,
  68. colorHash,
  69. offsetHash,
  70. dimensionHash,
  71. sizeHash
  72. );
  73. switch (graphic)
  74. {
  75. case Image image:
  76. int spriteHash = 0;
  77. if (image.sprite)
  78. spriteHash = image.sprite.GetHashCode();
  79. int imageHash = HashUtils.CombineHashCodes(
  80. (int) image.type,
  81. (int) (image.fillAmount * 360 * 20),
  82. (int) image.fillMethod,
  83. image.fillOrigin,
  84. image.fillClockwise ? 1 : 0
  85. );
  86. hash = HashUtils.CombineHashCodes(
  87. commonHash,
  88. spriteHash,
  89. imageHash
  90. );
  91. break;
  92. case RawImage rawImage:
  93. var textureHash = 0;
  94. if (rawImage.texture)
  95. textureHash = rawImage.texture.GetInstanceID();
  96. hash = HashUtils.CombineHashCodes(
  97. commonHash,
  98. textureHash
  99. );
  100. break;
  101. case Text text:
  102. var textHash = HashUtils.CombineHashCodes(
  103. text.text.GetHashCode(),
  104. text.font.GetHashCode(),
  105. text.fontSize,
  106. (int) text.lineSpacing * 100,
  107. (int) text.alignment
  108. );
  109. hash = HashUtils.CombineHashCodes(
  110. commonHash,
  111. textHash
  112. );
  113. break;
  114. default:
  115. hash = commonHash;
  116. break;
  117. }
  118. }
  119. int hash;
  120. // ReSharper disable once NonReadonlyMemberInGetHashCode
  121. public override int GetHashCode() => hash;
  122. public override bool Equals(object obj)
  123. {
  124. if (obj == null) return false;
  125. return GetHashCode() == obj.GetHashCode();
  126. }
  127. }
  128. }