using System; using System.Globalization; using System.Runtime.CompilerServices; using UnityEngine; using UnityEngine.TestTools; namespace BracerLib.Utility { [ExcludeFromCoverage] public struct Vector4Int : IEquatable, IFormattable { private static readonly Vector4Int zero = new Vector4Int(0, 0, 0, 0); private static readonly Vector4Int one = new Vector4Int(1, 1, 1, 1); private static readonly Vector4Int up = new Vector4Int(0, 1, 0, 0); private static readonly Vector4Int down = new Vector4Int(0, -1, 0, 0); private static readonly Vector4Int left = new Vector4Int(-1, 0, 0, 0); private static readonly Vector4Int right = new Vector4Int(1, 0, 0, 0); private static readonly Vector4Int forward = new Vector4Int(0, 0, 1, 0); private static readonly Vector4Int back = new Vector4Int(0, 0, -1, 0); public static Vector4Int Zero { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Vector4Int.zero; } /// /// Shorthand for writing Vector4Int(1, 1, 1, 1). /// public static Vector4Int One { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Vector4Int.one; } /// /// Shorthand for writing Vector4Int(0, 1, 0, 0). /// public static Vector4Int Up { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Vector4Int.up; } /// /// Shorthand for writing Vector4Int(0, -1, 0, 0). /// public static Vector4Int Down { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Vector4Int.down; } /// /// Shorthand for writing Vector4Int(-1, 0, 0, 0). /// public static Vector4Int Left { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Vector4Int.left; } /// /// Shorthand for writing Vector4Int(1, 0, 0, 0). /// public static Vector4Int Right { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Vector4Int.right; } /// /// Shorthand for writing Vector4Int(0, 0, 1, 0). /// public static Vector4Int Forward { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Vector4Int.forward; } /// /// Shorthand for writing Vector4Int(0, 0, -1, 0). /// public static Vector4Int Back { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Vector4Int.back; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector4(Vector4Int v) { return new Vector4((float) v.x, (float) v.y, (float) v.z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Vector2Int(Vector4Int v) => new Vector2Int(v.x, v.y); /// /// Converts a Vector4 to a Vector4Int by doing a Floor to each value. /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int FloorToInt(Vector4 v) { return new Vector4Int(Mathf.FloorToInt(v.x), Mathf.FloorToInt(v.y), Mathf.FloorToInt(v.z), Mathf.FloorToInt(v.w)); } /// /// Converts a Vector4 to a Vector4Int by doing a Ceiling to each value. /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int CeilToInt(Vector4 v) { return new Vector4Int(Mathf.CeilToInt(v.x), Mathf.CeilToInt(v.y), Mathf.CeilToInt(v.z),Mathf.CeilToInt(v.w)); } /// /// Converts a Vector4 to a Vector4Int by doing a Round to each value. /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int RoundToInt(Vector4 v) { return new Vector4Int(Mathf.RoundToInt(v.x), Mathf.RoundToInt(v.y), Mathf.RoundToInt(v.z), Mathf.RoundToInt(v.w)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int operator +(Vector4Int a, Vector4Int b) { return new Vector4Int(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int operator -(Vector4Int a, Vector4Int b) { return new Vector4Int(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int operator *(Vector4Int a, Vector4Int b) { return new Vector4Int(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int operator -(Vector4Int a) => new Vector4Int(-a.x, -a.y, -a.z, -a.w); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int operator *(Vector4Int a, int b) { return new Vector4Int(a.x * b, a.y * b, a.z * b, a.w * b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int operator *(int a, Vector4Int b) { return new Vector4Int(a * b.x, a * b.y, a * b.z, a * b.w); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4Int operator /(Vector4Int a, int b) { return new Vector4Int(a.x / b, a.y / b, a.z / b, a.w / b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector4Int lhs, Vector4Int rhs) { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Vector4Int lhs, Vector4Int rhs) => !(lhs == rhs); private int x; private int y; private int z; private int w; public int X { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => x; [MethodImpl(MethodImplOptions.AggressiveInlining)] set => x = value; } public int Y { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => y; [MethodImpl(MethodImplOptions.AggressiveInlining)] set => y = value; } public int Z { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => z; [MethodImpl(MethodImplOptions.AggressiveInlining)] set => z = value; } public int W { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => w; [MethodImpl(MethodImplOptions.AggressiveInlining)] set => w = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4Int(int x) { this.x = x; this.y = 0; this.z = 0; this.w = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4Int(int x, int y) { this.x = x; this.y = y; this.z = 0; this.w = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4Int(int x, int y, int z) { this.x = x; this.y = y; this.z = z; this.w = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4Int(int x, int y, int z, int w) { this.x = x; this.y = y; this.z = z; this.w = w; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4Int(Vector3Int indexes, int w) { x = indexes.x; y = indexes.y; z = indexes.z; this.w = w; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Vector4Int other) => this == other; [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object other) => other is Vector4Int other1 && Equals(other1); [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { int hashCode1 = y.GetHashCode(); int hashCode2 = z.GetHashCode(); return x.GetHashCode() ^ hashCode1 << 4 ^ hashCode1 >> 28 ^ hashCode2 >> 4 ^ hashCode2 << 28; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3Int ToVector3Int() { return new Vector3Int(x, y, z); } /// /// Returns a formatted string for this vector. /// /// A numeric format string. /// An object that specifies culture-specific formatting. [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() => ToString((string) null, (IFormatProvider) null); /// /// Returns a formatted string for this vector. /// /// A numeric format string. /// An object that specifies culture-specific formatting. [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ToString(string format) => ToString(format, (IFormatProvider) null); /// /// Returns a formatted string for this vector. /// /// A numeric format string. /// An object that specifies culture-specific formatting. [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ToString(string format, IFormatProvider formatProvider) { if (formatProvider == null) formatProvider = (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat; return $"({(object)x.ToString(format, formatProvider)}, {(object)y.ToString(format, formatProvider)}, {(object)z.ToString(format, formatProvider)})"; } } }