// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) VRMADA, All rights reserved. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Globalization; using System.Threading; using System.Threading.Tasks; using UltimateXR.Extensions.System; using UnityEngine; namespace UltimateXR.Extensions.Unity.Math { /// /// extensions. /// public static class Vector2IntExt { #region Public Types & Data /// /// Representation of the negative infinity vector. /// public static ref readonly Vector2Int NegativeInfinity => ref s_negativeInfinity; /// /// Representation of the positive infinity vector. /// public static ref readonly Vector2Int PositiveInfinity => ref s_positiveInfinity; #endregion #region Public Methods /// /// Checks whether any vector component stores an infinity value. /// /// Vector to check /// Whether any component has an infinity value public static bool IsInfinity(this in Vector2Int self) { return self.x == int.MinValue || self.x == int.MaxValue || self.y == int.MinValue || self.y == int.MaxValue; } /// /// Computes the absolute values of each vector component. /// /// Input vector /// Result vector where each component is the absolute value of the input value component public static Vector2Int Abs(this in Vector2Int self) { return new Vector2Int(Mathf.Abs(self.x), Mathf.Abs(self.y)); } /// /// Clamps the vector components between min and max values. /// /// Input vector whose values to clamp /// Minimum component values /// Maximum component values /// Clamped vector public static Vector2Int Clamp(this in Vector2Int self, in Vector2Int min, in Vector2Int max) { int[] result = new int[VectorLength]; for (int i = 0; i < VectorLength; ++i) { result[i] = Mathf.Clamp(self[i], min[i], max[i]); } return result.ToVector2Int(); } /// /// Replaces NaN component values with valid values. /// /// Vector whose NaN values to replace /// Vector with valid values /// Result vector public static Vector2Int FillNanWith(this in Vector2Int self, in Vector2Int other) { int[] result = new int[VectorLength]; for (int i = 0; i < VectorLength; ++i) { result[i] = self.x == int.MinValue || self.x == int.MaxValue ? other[i] : self[i]; } return result.ToVector2Int(); } /// /// Transforms an array of ints to a component by component. /// /// Source data /// Result vector public static Vector2Int ToVector2Int(this int[] data) { Array.Resize(ref data, VectorLength); return new Vector2Int(data[0], data[1]); } /// /// Tries to parse a from a string. /// /// Source string /// Parsed vector or if there was an error /// Whether the vector was parsed successfully public static bool TryParse(string s, out Vector2Int result) { try { result = Parse(s); return true; } catch { result = PositiveInfinity; return false; } } /// /// Parses a from a string. /// /// Source string /// Parsed vector public static Vector2Int Parse(string s) { s.ThrowIfNullOrWhitespace(nameof(s)); // Remove the parentheses s = s.TrimStart(' ', '(', '['); s = s.TrimEnd(' ', ')', ']'); // split the items string[] sArray = s.Split(s_cardinalSeparator, VectorLength); // store as an array int[] result = new int[VectorLength]; for (int i = 0; i < sArray.Length; ++i) { result[i] = int.Parse(sArray[i], CultureInfo.InvariantCulture.NumberFormat); } return result.ToVector2Int(); } /// /// Tries to parse a from a string, asynchronously. /// /// Source string /// Optional cancellation token, to cancel the operation /// Awaitable task returning the parsed vector or null if there was an error public static Task ParseAsync(string s, CancellationToken ct = default) { return Task.Run(() => TryParse(s, out Vector2Int result) ? result : (Vector2Int?)null, ct); } #endregion #region Private Types & Data private const int VectorLength = 2; private const string CardinalSeparator = ","; private static readonly char[] s_cardinalSeparator = CardinalSeparator.ToCharArray(); private static readonly Vector2Int s_negativeInfinity = int.MinValue * Vector2Int.one; private static readonly Vector2Int s_positiveInfinity = int.MaxValue * Vector2Int.one; #endregion } }