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();
|
|
}
|
|
}
|
|
}
|