com.wallstop-studios.unity-helpers 2.0.0-rc12 → 2.0.0-rc14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/Editor/EnsureTextureSizeWizard.cs +110 -0
  2. package/Editor/EnsureTextureSizeWizard.cs.meta +3 -0
  3. package/Runtime/Core/Attributes/ChildComponentAttribute.cs +124 -31
  4. package/Runtime/Core/Attributes/ParentComponent.cs +119 -29
  5. package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +31 -12
  6. package/Runtime/Core/Extension/ColorExtensions.cs +260 -1
  7. package/Runtime/Core/Extension/UnityExtensions.cs +10 -0
  8. package/Runtime/Core/Helper/Geometry.cs +17 -0
  9. package/Runtime/Core/Helper/SpriteHelpers.cs +36 -3
  10. package/Runtime/Core/Random/PcgRandom.cs +2 -2
  11. package/Runtime/Core/Random/RomuDuo.cs +116 -0
  12. package/Runtime/Core/Random/RomuDuo.cs.meta +3 -0
  13. package/Runtime/Core/Random/SplitMix64.cs +94 -0
  14. package/Runtime/Core/Random/SplitMix64.cs.meta +3 -0
  15. package/Runtime/Core/Random/XorShiroRandom.cs +117 -0
  16. package/Runtime/Core/Random/XorShiroRandom.cs.meta +3 -0
  17. package/Runtime/UI/LayeredImage.cs +364 -0
  18. package/Runtime/UI/LayeredImage.cs.meta +3 -0
  19. package/Runtime/UI.meta +3 -0
  20. package/Tests/Runtime/Attributes/ChildComponentTests.cs +81 -0
  21. package/Tests/Runtime/Attributes/ChildComponentTests.cs.meta +3 -0
  22. package/Tests/Runtime/Attributes/Components/ExpectChildSpriteRenderers.cs +28 -0
  23. package/Tests/Runtime/Attributes/Components/ExpectChildSpriteRenderers.cs.meta +3 -0
  24. package/Tests/Runtime/Attributes/Components/ExpectParentSpriteRenderers.cs +28 -0
  25. package/Tests/Runtime/Attributes/Components/ExpectParentSpriteRenderers.cs.meta +3 -0
  26. package/Tests/Runtime/Attributes/Components.meta +3 -0
  27. package/Tests/Runtime/Attributes/ParentComponentTests.cs +68 -0
  28. package/Tests/Runtime/Attributes/ParentComponentTests.cs.meta +3 -0
  29. package/Tests/Runtime/Attributes.meta +3 -0
  30. package/Tests/Runtime/Performance/RandomPerformanceTests.cs +3 -0
  31. package/Tests/Runtime/Random/RomuDuoRandomTests.cs +9 -0
  32. package/Tests/Runtime/Random/RomuDuoRandomTests.cs.meta +3 -0
  33. package/Tests/Runtime/Random/SplitMix64RandomTests.cs +9 -0
  34. package/Tests/Runtime/Random/SplitMix64RandomTests.cs.meta +3 -0
  35. package/Tests/Runtime/Random/XorShiroRandomTests.cs +9 -0
  36. package/Tests/Runtime/Random/XorShiroRandomTests.cs.meta +3 -0
  37. package/package.json +1 -1
@@ -1,13 +1,272 @@
1
1
  namespace UnityHelpers.Core.Extension
2
2
  {
3
3
  using System;
4
+ using System.Collections.Generic;
5
+ using System.ComponentModel;
6
+ using System.Linq;
7
+ using Helper;
4
8
  using Random;
5
9
  using UnityEngine;
6
10
 
11
+ public enum ColorAveragingMethod
12
+ {
13
+ LAB = 0, // CIE L*a*b* space averaging
14
+ HSV = 1, // HSV space averaging
15
+ Weighted = 2, // Weighted RGB averaging using perceived luminance
16
+ Dominant = 3, // Find most dominant color cluster
17
+ }
18
+
7
19
  // https://sharpsnippets.wordpress.com/2014/03/11/c-extension-complementary-color/
8
20
  public static class ColorExtensions
9
21
  {
10
- public static Color GetComplement(this Color source, IRandom random = null, float variance = 0f)
22
+ public static Color GetAverageColor(
23
+ this Sprite sprite,
24
+ ColorAveragingMethod method = ColorAveragingMethod.LAB
25
+ )
26
+ {
27
+ return GetAverageColor(Enumerables.Of(sprite), method);
28
+ }
29
+
30
+ public static Color GetAverageColor(
31
+ this IEnumerable<Sprite> sprites,
32
+ ColorAveragingMethod method = ColorAveragingMethod.LAB
33
+ )
34
+ {
35
+ return GetAverageColor(
36
+ sprites
37
+ .Where(Objects.NotNull)
38
+ .Select(sprite => sprite.texture)
39
+ .Where(Objects.NotNull)
40
+ .SelectMany(texture =>
41
+ {
42
+ texture.MakeReadable();
43
+ Color[] pixels = texture.GetPixels();
44
+ return pixels.Where(pixel => pixel.a > 0.01f);
45
+ }),
46
+ method
47
+ );
48
+ }
49
+
50
+ public static Color GetAverageColor(
51
+ this IEnumerable<Color> pixels,
52
+ ColorAveragingMethod method = ColorAveragingMethod.LAB
53
+ )
54
+ {
55
+ switch (method)
56
+ {
57
+ case ColorAveragingMethod.LAB:
58
+ {
59
+ return AverageInLABSpace(pixels);
60
+ }
61
+ case ColorAveragingMethod.HSV:
62
+ {
63
+ return AverageInHSVSpace(pixels);
64
+ }
65
+ case ColorAveragingMethod.Weighted:
66
+ {
67
+ return WeightedRGBAverage(pixels);
68
+ }
69
+ case ColorAveragingMethod.Dominant:
70
+ {
71
+ return GetDominantColor(pixels);
72
+ }
73
+ default:
74
+ {
75
+ throw new InvalidEnumArgumentException(
76
+ nameof(method),
77
+ (int)method,
78
+ typeof(ColorAveragingMethod)
79
+ );
80
+ }
81
+ }
82
+ }
83
+
84
+ // CIE L*a*b* space averaging - most perceptually accurate
85
+ private static Color AverageInLABSpace(IEnumerable<Color> pixels)
86
+ {
87
+ List<LABColor> labValues = pixels.Select(RGBToLAB).ToList();
88
+
89
+ double avgL = labValues.Average(lab => lab.l);
90
+ double avgA = labValues.Average(lab => lab.a);
91
+ double avgB = labValues.Average(lab => lab.b);
92
+
93
+ return LABToRGB(avgL, avgA, avgB);
94
+ }
95
+
96
+ // HSV space averaging - good for preserving vibrant colors
97
+ private static Color AverageInHSVSpace(IEnumerable<Color> pixels)
98
+ {
99
+ float avgH = 0f;
100
+ float avgS = 0f;
101
+ float avgV = 0f;
102
+ int count = 0;
103
+
104
+ foreach (Color pixel in pixels)
105
+ {
106
+ Color.RGBToHSV(pixel, out float h, out float s, out float v);
107
+
108
+ // Handle hue wrapping around 360 degrees
109
+ float hRad = h * 2f * Mathf.PI;
110
+ avgH += Mathf.Cos(hRad);
111
+ avgH += Mathf.Sin(hRad);
112
+
113
+ avgS += s;
114
+ avgV += v;
115
+ count++;
116
+ }
117
+
118
+ avgH = Mathf.Atan2(avgH / count, avgH / count) / (2f * Mathf.PI);
119
+ if (avgH < 0)
120
+ {
121
+ avgH += 1f;
122
+ }
123
+
124
+ if (count <= 0)
125
+ {
126
+ count = 1;
127
+ }
128
+
129
+ avgS /= count;
130
+ avgV /= count;
131
+
132
+ return Color.HSVToRGB(avgH, avgS, avgV);
133
+ }
134
+
135
+ // Weighted RGB averaging using perceived luminance
136
+ private static Color WeightedRGBAverage(IEnumerable<Color> pixels)
137
+ {
138
+ // Use perceived luminance weights
139
+ const float rWeight = 0.299f;
140
+ const float gWeight = 0.587f;
141
+ const float bWeight = 0.114f;
142
+
143
+ float totalWeight = 0f;
144
+ float r = 0f,
145
+ g = 0f,
146
+ b = 0f,
147
+ a = 0f;
148
+
149
+ foreach (Color pixel in pixels)
150
+ {
151
+ float weight = pixel.r * rWeight + pixel.g * gWeight + pixel.b * bWeight;
152
+ r += pixel.r * weight;
153
+ g += pixel.g * weight;
154
+ b += pixel.b * weight;
155
+ a += pixel.a * weight;
156
+ totalWeight += weight;
157
+ }
158
+
159
+ if (totalWeight > 0f)
160
+ {
161
+ r /= totalWeight;
162
+ g /= totalWeight;
163
+ b /= totalWeight;
164
+ a /= totalWeight;
165
+ }
166
+
167
+ return new Color(r, g, b, a);
168
+ }
169
+
170
+ // Find dominant color using simple clustering
171
+ private static Color GetDominantColor(IEnumerable<Color> pixels)
172
+ {
173
+ Dictionary<Vector3Int, int> colorBuckets = new();
174
+ const int bucketSize = 32; // Adjust for different precision
175
+
176
+ foreach (Color pixel in pixels)
177
+ {
178
+ Vector3Int bucket = new(
179
+ Mathf.RoundToInt(pixel.r * 255 / bucketSize),
180
+ Mathf.RoundToInt(pixel.g * 255 / bucketSize),
181
+ Mathf.RoundToInt(pixel.b * 255 / bucketSize)
182
+ );
183
+
184
+ colorBuckets.TryAdd(bucket, 0);
185
+ colorBuckets[bucket]++;
186
+ }
187
+
188
+ Vector3Int dominantBucket = colorBuckets
189
+ .OrderByDescending(kvp => kvp.Value)
190
+ .First()
191
+ .Key;
192
+ return new Color(
193
+ dominantBucket.x * bucketSize / 255f,
194
+ dominantBucket.y * bucketSize / 255f,
195
+ dominantBucket.z * bucketSize / 255f
196
+ );
197
+ }
198
+
199
+ // Helper struct for LAB color space
200
+ private readonly struct LABColor
201
+ {
202
+ public readonly double l;
203
+ public readonly double a;
204
+ public readonly double b;
205
+
206
+ public LABColor(double l, double a, double b)
207
+ {
208
+ this.l = l;
209
+ this.a = a;
210
+ this.b = b;
211
+ }
212
+ }
213
+
214
+ private static LABColor RGBToLAB(Color rgb)
215
+ {
216
+ // First convert to XYZ
217
+ double r =
218
+ rgb.r > 0.04045 ? Mathf.Pow((rgb.r + 0.055f) / 1.055f, 2.4f) : rgb.r / 12.92f;
219
+ double g =
220
+ rgb.g > 0.04045 ? Mathf.Pow((rgb.g + 0.055f) / 1.055f, 2.4f) : rgb.g / 12.92f;
221
+ double b =
222
+ rgb.b > 0.04045 ? Mathf.Pow((rgb.b + 0.055f) / 1.055f, 2.4f) : rgb.b / 12.92f;
223
+
224
+ double x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
225
+ double y = (r * 0.2126 + g * 0.7152 + b * 0.0722);
226
+ double z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
227
+
228
+ x = x > 0.008856 ? Mathf.Pow((float)x, 1f / 3f) : (7.787 * x) + 16f / 116f;
229
+ y = y > 0.008856 ? Mathf.Pow((float)y, 1f / 3f) : (7.787 * y) + 16f / 116f;
230
+ z = z > 0.008856 ? Mathf.Pow((float)z, 1f / 3f) : (7.787 * z) + 16f / 116f;
231
+
232
+ return new LABColor((116 * y) - 16, 500 * (x - y), 200 * (y - z));
233
+ }
234
+
235
+ private static Color LABToRGB(double l, double a, double b)
236
+ {
237
+ double y = (l + 16) / 116;
238
+ double x = a / 500 + y;
239
+ double z = y - b / 200;
240
+
241
+ double x3 = x * x * x;
242
+ double y3 = y * y * y;
243
+ double z3 = z * z * z;
244
+
245
+ x = 0.95047 * (x3 > 0.008856 ? x3 : (x - 16.0 / 116.0) / 7.787);
246
+ y = y3 > 0.008856 ? y3 : (y - 16.0 / 116.0) / 7.787;
247
+ z = 1.08883 * (z3 > 0.008856 ? z3 : (z - 16.0 / 116.0) / 7.787);
248
+
249
+ double r = x * 3.2406 + y * -1.5372 + z * -0.4986;
250
+ double g = x * -0.9689 + y * 1.8758 + z * 0.0415;
251
+ double b2 = x * 0.0557 + y * -0.2040 + z * 1.0570;
252
+
253
+ r = r > 0.0031308 ? 1.055 * Mathf.Pow((float)r, 1 / 2.4f) - 0.055 : 12.92 * r;
254
+ g = g > 0.0031308 ? 1.055 * Mathf.Pow((float)g, 1 / 2.4f) - 0.055 : 12.92 * g;
255
+ b2 = b2 > 0.0031308 ? 1.055 * Mathf.Pow((float)b2, 1 / 2.4f) - 0.055 : 12.92 * b2;
256
+
257
+ return new Color(
258
+ Mathf.Clamp01((float)r),
259
+ Mathf.Clamp01((float)g),
260
+ Mathf.Clamp01((float)b2),
261
+ 1f
262
+ );
263
+ }
264
+
265
+ public static Color GetComplement(
266
+ this Color source,
267
+ IRandom random = null,
268
+ float variance = 0f
269
+ )
11
270
  {
12
271
  Color inputColor = source;
13
272
  //if RGB values are close to each other by a diff less than 10%, then if RGB values are lighter side, decrease the blue by 50% (eventually it will increase in conversion below), if RBB values are on darker side, decrease yellow by about 50% (it will increase in conversion)
@@ -14,6 +14,16 @@
14
14
 
15
15
  public static class UnityExtensions
16
16
  {
17
+ public static Vector2 GetCenter(this GameObject gameObject)
18
+ {
19
+ if (gameObject.TryGetComponent(out CenterPointOffset centerPointOffset))
20
+ {
21
+ return centerPointOffset.CenterPoint;
22
+ }
23
+
24
+ return gameObject.transform.position;
25
+ }
26
+
17
27
  public static Bounds Bounds(this Rect rect)
18
28
  {
19
29
  return new Bounds(rect.center, rect.size);
@@ -1,9 +1,26 @@
1
1
  namespace UnityHelpers.Core.Helper
2
2
  {
3
+ using System.Collections.Generic;
4
+ using System.Linq;
3
5
  using UnityEngine;
4
6
 
5
7
  public static class Geometry
6
8
  {
9
+ public static Rect Accumulate(this IEnumerable<Rect> rects)
10
+ {
11
+ return rects.Aggregate(
12
+ (accumulated, next) =>
13
+ new Rect(
14
+ Mathf.Min(accumulated.xMin, next.xMin),
15
+ Mathf.Min(accumulated.yMin, next.yMin),
16
+ Mathf.Max(accumulated.xMax, next.xMax)
17
+ - Mathf.Min(accumulated.xMin, next.xMin),
18
+ Mathf.Max(accumulated.yMax, next.yMax)
19
+ - Mathf.Min(accumulated.yMin, next.yMin)
20
+ )
21
+ );
22
+ }
23
+
7
24
  //Where is p in relation to a-b
8
25
  // < 0 -> to the right
9
26
  // = 0 -> on the line
@@ -1,11 +1,41 @@
1
1
  namespace UnityHelpers.Core.Helper
2
2
  {
3
+ using Extension;
3
4
  using UnityEditor;
4
5
  using UnityEngine;
5
6
  using Utils;
6
7
 
7
8
  public static class SpriteHelpers
8
9
  {
10
+ public static void MakeReadable(this Texture2D texture)
11
+ {
12
+ if (texture.isReadable)
13
+ {
14
+ return;
15
+ }
16
+
17
+ #if UNITY_EDITOR
18
+ string assetPath = AssetDatabase.GetAssetPath(texture);
19
+ if (string.IsNullOrEmpty(assetPath))
20
+ {
21
+ texture.LogError("Failed to get asset path.");
22
+ return;
23
+ }
24
+
25
+ TextureImporter tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
26
+ if (tImporter == null)
27
+ {
28
+ texture.LogError("Failed to get texture importer.");
29
+ return;
30
+ }
31
+
32
+ tImporter.isReadable = true;
33
+ EditorUtility.SetDirty(tImporter);
34
+ tImporter.SaveAndReimport();
35
+ EditorUtility.SetDirty(texture);
36
+ #endif
37
+ }
38
+
9
39
  public static void SetSpritePivot(string fullSpritePath, Vector2 pivot)
10
40
  {
11
41
  #if UNITY_EDITOR
@@ -16,7 +46,10 @@
16
46
  public static void SetSpritePivot(Sprite sprite, Vector2 pivot)
17
47
  {
18
48
  #if UNITY_EDITOR
19
- SetSpritePivot(AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(sprite)) as TextureImporter, pivot);
49
+ SetSpritePivot(
50
+ AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(sprite)) as TextureImporter,
51
+ pivot
52
+ );
20
53
  #endif
21
54
  }
22
55
 
@@ -30,7 +63,7 @@
30
63
 
31
64
  TextureImporterSettings textureImportSettings = new TextureImporterSettings();
32
65
  textureImporter.ReadTextureSettings(textureImportSettings);
33
- textureImportSettings.spriteAlignment = (int) SpriteAlignment.Custom;
66
+ textureImportSettings.spriteAlignment = (int)SpriteAlignment.Custom;
34
67
  textureImportSettings.wrapMode = TextureWrapMode.Clamp;
35
68
  textureImportSettings.filterMode = FilterMode.Trilinear;
36
69
  textureImporter.SetTextureSettings(textureImportSettings);
@@ -40,7 +73,7 @@
40
73
  resizeAlgorithm = TextureResizeAlgorithm.Bilinear,
41
74
  maxTextureSize = SetTextureImportData.RegularTextureSize,
42
75
  textureCompression = TextureImporterCompression.Compressed,
43
- format = TextureImporterFormat.Automatic
76
+ format = TextureImporterFormat.Automatic,
44
77
  };
45
78
 
46
79
  textureImporter.SetPlatformTextureSettings(importerSettings);
@@ -17,6 +17,8 @@
17
17
  {
18
18
  public static IRandom Instance => ThreadLocalRandom<PcgRandom>.Instance;
19
19
 
20
+ public override RandomState InternalState => new(_state, _increment, _cachedGaussian);
21
+
20
22
  internal readonly ulong _increment;
21
23
 
22
24
  internal ulong _state;
@@ -53,8 +55,6 @@
53
55
  _increment = NextUlong();
54
56
  }
55
57
 
56
- public override RandomState InternalState => new(_state, _increment, _cachedGaussian);
57
-
58
58
  public override uint NextUint()
59
59
  {
60
60
  unchecked
@@ -0,0 +1,116 @@
1
+ namespace UnityHelpers.Core.Random
2
+ {
3
+ using System;
4
+ using System.Runtime.CompilerServices;
5
+ using System.Runtime.Serialization;
6
+ using System.Text.Json.Serialization;
7
+ using Extension;
8
+ using Helper;
9
+
10
+ [Serializable]
11
+ [DataContract]
12
+ public sealed class RomuDuo
13
+ : AbstractRandom,
14
+ IEquatable<RomuDuo>,
15
+ IComparable,
16
+ IComparable<RomuDuo>
17
+ {
18
+ public static IRandom Instance => ThreadLocalRandom<RomuDuo>.Instance;
19
+ public override RandomState InternalState => new(_x, _y, _cachedGaussian);
20
+
21
+ internal ulong _x;
22
+ internal ulong _y;
23
+
24
+ public RomuDuo()
25
+ : this(Guid.NewGuid()) { }
26
+
27
+ public RomuDuo(Guid guid)
28
+ {
29
+ byte[] bytes = guid.ToByteArray();
30
+ _x = BitConverter.ToUInt64(bytes, 0);
31
+ _y = BitConverter.ToUInt64(bytes, sizeof(ulong));
32
+ }
33
+
34
+ public RomuDuo(ulong seedX, ulong seedY)
35
+ {
36
+ _x = seedX;
37
+ _y = seedY;
38
+ }
39
+
40
+ [JsonConstructor]
41
+ public RomuDuo(RandomState internalState)
42
+ {
43
+ _x = internalState.State1;
44
+ _y = internalState.State2;
45
+ _cachedGaussian = internalState.Gaussian;
46
+ }
47
+
48
+ public override uint NextUint()
49
+ {
50
+ unchecked
51
+ {
52
+ ulong xp = _x;
53
+ _x = 15241094284759029579UL * _y;
54
+ _y = Rol64(_y, 27) + xp;
55
+ return (uint)xp;
56
+ }
57
+ }
58
+
59
+ public override IRandom Copy()
60
+ {
61
+ return new RomuDuo(InternalState);
62
+ }
63
+
64
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
65
+ private static ulong Rol64(ulong x, int k)
66
+ {
67
+ return (x << k) | (x >> (64 - k));
68
+ }
69
+
70
+ public override bool Equals(object obj)
71
+ {
72
+ return Equals(obj as RomuDuo);
73
+ }
74
+
75
+ public bool Equals(RomuDuo other)
76
+ {
77
+ if (other == null)
78
+ {
79
+ return false;
80
+ }
81
+
82
+ return _x == other._x && _y == other._y;
83
+ }
84
+
85
+ public override int GetHashCode()
86
+ {
87
+ return Objects.ValueTypeHashCode(_x, _y);
88
+ }
89
+
90
+ public override string ToString()
91
+ {
92
+ return this.ToJson();
93
+ }
94
+
95
+ public int CompareTo(object obj)
96
+ {
97
+ return CompareTo(obj as RomuDuo);
98
+ }
99
+
100
+ public int CompareTo(RomuDuo other)
101
+ {
102
+ if (other == null)
103
+ {
104
+ return -1;
105
+ }
106
+
107
+ int comparison = _x.CompareTo(other._x);
108
+ if (comparison != 0)
109
+ {
110
+ return comparison;
111
+ }
112
+
113
+ return _y.CompareTo(other._y);
114
+ }
115
+ }
116
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 562c2538ef434c048b1fd0816dcc2369
3
+ timeCreated: 1735610205
@@ -0,0 +1,94 @@
1
+ namespace UnityHelpers.Core.Random
2
+ {
3
+ using System;
4
+ using System.Runtime.Serialization;
5
+ using System.Text.Json.Serialization;
6
+
7
+ [Serializable]
8
+ [DataContract]
9
+ public sealed class SplitMix64
10
+ : AbstractRandom,
11
+ IEquatable<SplitMix64>,
12
+ IComparable,
13
+ IComparable<SplitMix64>
14
+ {
15
+ public static IRandom Instance => ThreadLocalRandom<SplitMix64>.Instance;
16
+
17
+ public override RandomState InternalState => new(_state, 0, _cachedGaussian);
18
+
19
+ internal ulong _state;
20
+
21
+ public SplitMix64()
22
+ : this(Guid.NewGuid()) { }
23
+
24
+ public SplitMix64(Guid guid)
25
+ : this(BitConverter.ToUInt64(guid.ToByteArray(), 0)) { }
26
+
27
+ public SplitMix64(ulong seed)
28
+ {
29
+ _state = seed;
30
+ }
31
+
32
+ [JsonConstructor]
33
+ public SplitMix64(RandomState internalState)
34
+ {
35
+ _state = internalState.State1;
36
+ _cachedGaussian = internalState.Gaussian;
37
+ }
38
+
39
+ public override uint NextUint()
40
+ {
41
+ unchecked
42
+ {
43
+ _state += 0x9E3779B97F4A7C15UL;
44
+
45
+ ulong z = _state;
46
+ z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9UL;
47
+ z = (z ^ (z >> 27)) * 0x94D049BB133111EBUL;
48
+ z ^= (z >> 31);
49
+
50
+ return (uint)z;
51
+ }
52
+ }
53
+
54
+ public override IRandom Copy()
55
+ {
56
+ return new SplitMix64(InternalState);
57
+ }
58
+
59
+ public bool Equals(SplitMix64 other)
60
+ {
61
+ if (other == null)
62
+ {
63
+ return false;
64
+ }
65
+
66
+ return _state == other._state;
67
+ }
68
+
69
+ public int CompareTo(object obj)
70
+ {
71
+ return CompareTo(obj as SplitMix64);
72
+ }
73
+
74
+ public int CompareTo(SplitMix64 other)
75
+ {
76
+ if (other == null)
77
+ {
78
+ return -1;
79
+ }
80
+
81
+ return _state.CompareTo(other._state);
82
+ }
83
+
84
+ public override int GetHashCode()
85
+ {
86
+ return _state.GetHashCode();
87
+ }
88
+
89
+ public override string ToString()
90
+ {
91
+ return $"{{\"State\": {_state}}}";
92
+ }
93
+ }
94
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: cea6a12d9c0d4373b21094cdb49b8cfb
3
+ timeCreated: 1735605670