|
|
- using System;
- using UnityEngine;
- using UnityEngine.UI;
-
- namespace LeTai.TrueShadow
- {
- class ShadowSettingSnapshot
- {
- public readonly TrueShadow shadow;
- public readonly Canvas canvas;
- public readonly RectTransform canvasRt;
- public readonly bool shouldAntialiasImprint;
- public readonly float canvasScale;
- public readonly float size;
- public readonly Vector2 canvasRelativeOffset;
- public readonly Vector2 dimensions;
-
- internal ShadowSettingSnapshot(TrueShadow shadow)
- {
- this.shadow = shadow;
- canvas = shadow.Graphic.canvas;
- canvasRt = (RectTransform) canvas.transform;
-
- var meshBound = shadow.SpriteMesh.bounds;
-
- shouldAntialiasImprint = canvas.renderMode != RenderMode.ScreenSpaceOverlay;
-
- canvasScale = canvas.scaleFactor;
-
- var canvasRelativeRotation = Quaternion.Inverse(canvasRt.rotation) * shadow.RectTransform.rotation;
- canvasRelativeOffset = shadow.Offset.Rotate(-canvasRelativeRotation.eulerAngles.z) * canvasScale;
-
- dimensions = (Vector2) meshBound.size * canvasScale;
- size = shadow.Size * canvasScale;
-
- CalcHash();
- }
-
- const int DIMENSIONS_HASH_STEP = 1;
-
- void CalcHash()
- {
- var graphic = shadow.Graphic;
-
- int canvasScaleHash = (int) (canvasScale * 1e4);
- int insetHash = shadow.Inset ? 1 : 0;
-
- var clearColor = shadow.ClearColor;
- var imageColor = graphic.color;
- int colorHash = HashUtils.CombineHashCodes(
- shadow.IgnoreCasterColor ? 1 : 0,
- (int) shadow.ColorBleedMode,
- (int) (imageColor.r * 255),
- (int) (imageColor.g * 255),
- (int) (imageColor.b * 255),
- (int) (imageColor.a * 255),
- (int) (clearColor.r * 255),
- (int) (clearColor.g * 255),
- (int) (clearColor.b * 255),
- (int) (clearColor.a * 255)
- );
-
- // Hack until we have separated cutout cache, or proper sibling mode
- int offsetHash = HashUtils.CombineHashCodes(
- shadow.Cutout ? 1 : 0,
- (int) (canvasRelativeOffset.x * 100),
- (int) (canvasRelativeOffset.y * 100)
- );
-
- // Tiled type cannot be batched by similar size
- int dimensionHash = graphic is Image im && im.type == Image.Type.Tiled
- ? dimensions.GetHashCode()
- : HashUtils.CombineHashCodes(
- Mathf.CeilToInt(dimensions.x / DIMENSIONS_HASH_STEP) * DIMENSIONS_HASH_STEP,
- Mathf.CeilToInt(dimensions.y / DIMENSIONS_HASH_STEP) * DIMENSIONS_HASH_STEP
- );
-
- var sizeHash = Mathf.CeilToInt(size * 100);
-
- var commonHash = HashUtils.CombineHashCodes(
- shadow.TextureRevision,
- canvasScaleHash,
- insetHash,
- colorHash,
- offsetHash,
- dimensionHash,
- sizeHash
- );
-
- switch (graphic)
- {
- case Image image:
- int spriteHash = 0;
- if (image.sprite)
- spriteHash = image.sprite.GetHashCode();
-
- int imageHash = HashUtils.CombineHashCodes(
- (int) image.type,
- (int) (image.fillAmount * 360 * 20),
- (int) image.fillMethod,
- image.fillOrigin,
- image.fillClockwise ? 1 : 0
- );
-
- hash = HashUtils.CombineHashCodes(
- commonHash,
- spriteHash,
- imageHash
- );
- break;
- case RawImage rawImage:
- var textureHash = 0;
- if (rawImage.texture)
- textureHash = rawImage.texture.GetInstanceID();
-
- hash = HashUtils.CombineHashCodes(
- commonHash,
- textureHash
- );
- break;
- case Text text:
- var textHash = HashUtils.CombineHashCodes(
- text.text.GetHashCode(),
- text.font.GetHashCode(),
- text.fontSize,
- (int) text.lineSpacing * 100,
- (int) text.alignment
- );
- hash = HashUtils.CombineHashCodes(
- commonHash,
- textHash
- );
- break;
- default:
- hash = commonHash;
- break;
- }
- }
-
- int hash;
-
- // ReSharper disable once NonReadonlyMemberInGetHashCode
- public override int GetHashCode() => hash;
-
- public override bool Equals(object obj)
- {
- if (obj == null) return false;
-
- return GetHashCode() == obj.GetHashCode();
- }
- }
- }
|