// -------------------------------------------------------------------------------------------------------------------- // // 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 Vector3IntExt { #region Public Types & Data /// /// Representation of the minimum int values per component. /// public static ref readonly Vector3Int MinValue => ref s_minValue; /// /// Representation of the maximum int values per component. /// public static ref readonly Vector3Int MaxValue => ref s_maxValue; #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 Vector3Int self) { return self.x == int.MinValue || self.x == int.MaxValue || self.y == int.MinValue || self.y == int.MaxValue || self.z == int.MinValue || self.z == 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 Vector3Int Abs(this in Vector3Int self) { return new Vector3Int(Mathf.Abs(self.x), Mathf.Abs(self.y), Mathf.Abs(self.z)); } /// /// 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 Vector3Int Clamp(this in Vector3Int self, in Vector3Int min, in Vector3Int 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.ToVector3Int(); } /// /// Replaces NaN component values with valid values. /// /// Vector whose NaN values to replace /// Vector with valid values /// Result vector public static Vector3Int FillNaNWith(this in Vector3Int self, in Vector3Int 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.ToVector3Int(); } /// /// Transforms an array of ints to a component by component. /// /// Source data /// Result vector public static Vector3Int ToVector3Int(this int[] data) { Array.Resize(ref data, VectorLength); return new Vector3Int(data[0], data[1], data[2]); } /// /// 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 Vector3Int result) { try { result = Parse(s); return true; } catch { result = MaxValue; return false; } } /// /// Parses a from a string. /// /// Source string /// Parsed vector public static Vector3Int 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.ToVector3Int(); } /// /// 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 Vector3Int result) ? result : (Vector3Int?)null, ct); } #endregion #region Private Types & Data private const int VectorLength = 3; private const string CardinalSeparator = ","; private static readonly char[] s_cardinalSeparator = CardinalSeparator.ToCharArray(); private static readonly Vector3Int s_minValue = int.MinValue * Vector3Int.one; private static readonly Vector3Int s_maxValue = int.MaxValue * Vector3Int.one; #endregion } }