using UnityEngine; namespace Coffee.UISoftMaskInternal { public enum TransformSensitivity { Low, Medium, High } /// /// Extension methods for Transform class. /// internal static class TransformExtensionsForTransformSensitivity { private const float k_DefaultEpsilon = 1f / (2 ^ 8); /// /// Check if a transform has changed. /// public static bool HasChanged(this Transform self, ref Matrix4x4 prev, TransformSensitivity sensitivity) { return self.HasChanged_Internal(null, ref prev, Convert(sensitivity)); } /// /// Check if a transform has changed. /// public static bool HasChanged(this Transform self, Transform baseTransform, ref Matrix4x4 prev, TransformSensitivity sensitivity) { return self.HasChanged_Internal(baseTransform, ref prev, Convert(sensitivity)); } private static float Convert(TransformSensitivity self) { switch (self) { case TransformSensitivity.Low: return 1f / (1 << 4); case TransformSensitivity.Medium: return 1f / (1 << 8); case TransformSensitivity.High: return 1f / (1 << 12); default: return 1f / (1 << (int)self); } } private static bool HasChanged_Internal(this Transform self, Transform baseTransform, ref Matrix4x4 prev, float epsilon) { if (!self) return false; var hash = baseTransform ? baseTransform.GetHashCode() : 0; if (FrameCache.TryGet(self, nameof(HasChanged), hash, out bool result)) return result; var matrix = baseTransform ? baseTransform.worldToLocalMatrix * self.localToWorldMatrix : self.localToWorldMatrix; var current = matrix * Matrix4x4.Scale(Vector3.one * 10000); result = !Approximately(current, prev, epsilon); FrameCache.Set(self, nameof(HasChanged), hash, result); if (result) { prev = current; } return result; } private static bool Approximately(Matrix4x4 self, Matrix4x4 other, float epsilon = k_DefaultEpsilon) { for (var i = 0; i < 16; i++) { if (epsilon < Mathf.Abs(self[i] - other[i])) { return false; } } return true; } } }