Search Unity

Vector4Int missing?

Discussion in 'Scripting' started by arkano22, Jan 14, 2020.

  1. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    647
    Maybe I'm the only one looking for it, but.... the absence of Vector4Int when there's Vector3Int and Vector2Int to match their floating point counterparts, is mildly uncomfortable. :)

    Any plans to include it?
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    7,075
    I think you may be the only one looking for it, TBH. I'm having a hard time imagining a point for Vector4Int. It's tough enough thinking of ways to use Vector4, and all the examples for that I can think of for that (v3+time, some graphics shenanigans, etc) are very explicitly dependent on the numbers being floats.
     
    arkano22, lordofduct and Joe-Censored like this.
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,829
    Agreed with StarManta, but if you find yourself needing it you can just write your own:
    Code (csharp):
    1.  
    2. using System;
    3. using System.Globalization;
    4. using System.Runtime.InteropServices;
    5. using UnityEngine.Scripting;
    6.  
    7. namespace UnityEngine
    8. {
    9.     [System.Serializable]
    10.     [StructLayout(LayoutKind.Sequential)]
    11.     public struct Vector4Int : IEquatable<Vector4Int>, IFormattable
    12.     {
    13.         public int x { get { return m_X; } set { m_X = value; } }
    14.         public int y { get { return m_Y; } set { m_Y = value; } }
    15.         public int z { get { return m_Z; } set { m_Z = value; } }
    16.         public int w { get { return m_W; } set { m_W = value; } }
    17.  
    18.         private int m_X;
    19.         private int m_Y;
    20.         private int m_Z;
    21.         private int m_W;
    22.  
    23.         public Vector4Int(int x, int y, int z, int w)
    24.         {
    25.             m_X = x;
    26.             m_Y = y;
    27.             m_Z = z;
    28.             m_W = w;
    29.         }
    30.  
    31.         // Set x, y and z components of an existing Vector.
    32.         public void Set(int x, int y, int z, int w)
    33.         {
    34.             m_X = x;
    35.             m_Y = y;
    36.             m_Z = z;
    37.             m_W = w;
    38.         }
    39.  
    40.         // Access the /x/, /y/ or /z/ component using [0], [1] or [2] respectively.
    41.         public int this[int index]
    42.         {
    43.             get
    44.             {
    45.                 switch (index)
    46.                 {
    47.                     case 0: return x;
    48.                     case 1: return y;
    49.                     case 2: return z;
    50.                     case 3: return w;
    51.                     default:
    52.                         throw new IndexOutOfRangeException(UnityString.Format("Invalid Vector4Int index addressed: {0}!", index));
    53.                 }
    54.             }
    55.  
    56.             set
    57.             {
    58.                 switch (index)
    59.                 {
    60.                     case 0: x = value; break;
    61.                     case 1: y = value; break;
    62.                     case 2: z = value; break;
    63.                     case 3: w = value; break;
    64.                     default:
    65.                         throw new IndexOutOfRangeException(UnityString.Format("Invalid Vector4Int index addressed: {0}!", index));
    66.                 }
    67.             }
    68.         }
    69.  
    70.         // Returns the length of this vector (RO).
    71.         public float magnitude { get { return Mathf.Sqrt((float)(x * x + y * y + z * z + w * w)); } }
    72.  
    73.         // Returns the squared length of this vector (RO).
    74.         public int sqrMagnitude { get { return x * x + y * y + z * z + w * w; } }
    75.  
    76.         // Returns the distance between /a/ and /b/.
    77.         public static float Distance(Vector4Int a, Vector4Int b) { return (a - b).magnitude; }
    78.  
    79.         // Returns a vector that is made from the smallest components of two vectors.
    80.         public static Vector4Int Min(Vector4Int lhs, Vector4Int rhs) { return new Vector4Int(Mathf.Min(lhs.x, rhs.x), Mathf.Min(lhs.y, rhs.y), Mathf.Min(lhs.z, rhs.z), Mathf.Min(lhs.w, rhs.w)); }
    81.  
    82.         // Returns a vector that is made from the largest components of two vectors.
    83.         public static Vector4Int Max(Vector4Int lhs, Vector4Int rhs) { return new Vector4Int(Mathf.Max(lhs.x, rhs.x), Mathf.Max(lhs.y, rhs.y), Mathf.Max(lhs.z, rhs.z), Mathf.Max(lhs.w, rhs.w)); }
    84.  
    85.         // Multiplies two vectors component-wise.
    86.         public static Vector4Int Scale(Vector4Int a, Vector4Int b) { return new Vector4Int(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); }
    87.  
    88.         // Multiplies every component of this vector by the same component of /scale/.
    89.         public void Scale(Vector4Int scale) { x *= scale.x; y *= scale.y; z *= scale.z; w *= scale.w; }
    90.  
    91.         public void Clamp(Vector4Int min, Vector4Int max)
    92.         {
    93.             x = Math.Max(min.x, x);
    94.             x = Math.Min(max.x, x);
    95.             y = Math.Max(min.y, y);
    96.             y = Math.Min(max.y, y);
    97.             z = Math.Max(min.z, z);
    98.             z = Math.Min(max.z, z);
    99.             w = Math.Max(min.w, w);
    100.             w = Math.Min(max.w, w);
    101.         }
    102.  
    103.         // Converts a Vector4Int to a [[Vector4]].
    104.         public static implicit operator Vector4(Vector4Int v)
    105.         {
    106.             return new Vector4(v.x, v.y, v.z, v.w);
    107.         }
    108.  
    109.         // Converts a Vector4Int to a [[Vector2Int]].
    110.         public static explicit operator Vector3Int(Vector4Int v)
    111.         {
    112.             return new Vector3Int(v.x, v.y, v.z);
    113.         }
    114.  
    115.         // Converts a Vector4Int to a [[Vector2Int]].
    116.         public static explicit operator Vector2Int(Vector4Int v)
    117.         {
    118.             return new Vector2Int(v.x, v.y);
    119.         }
    120.  
    121.         public static Vector4Int FloorToInt(Vector4 v)
    122.         {
    123.             return new Vector4Int(
    124.                 Mathf.FloorToInt(v.x),
    125.                 Mathf.FloorToInt(v.y),
    126.                 Mathf.FloorToInt(v.z),
    127.                 Mathf.FloorToInt(v.w)
    128.             );
    129.         }
    130.  
    131.         public static Vector4Int CeilToInt(Vector4 v)
    132.         {
    133.             return new Vector4Int(
    134.                 Mathf.CeilToInt(v.x),
    135.                 Mathf.CeilToInt(v.y),
    136.                 Mathf.CeilToInt(v.z),
    137.                 Mathf.CeilToInt(v.w)
    138.             );
    139.         }
    140.  
    141.         public static Vector4Int RoundToInt(Vector4 v)
    142.         {
    143.             return new Vector4Int(
    144.                 Mathf.RoundToInt(v.x),
    145.                 Mathf.RoundToInt(v.y),
    146.                 Mathf.RoundToInt(v.z),
    147.                 Mathf.RoundToInt(v.w)
    148.             );
    149.         }
    150.  
    151.         public static Vector4Int operator+(Vector4Int a, Vector4Int b)
    152.         {
    153.             return new Vector4Int(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
    154.         }
    155.  
    156.         public static Vector4Int operator-(Vector4Int a, Vector4Int b)
    157.         {
    158.             return new Vector4Int(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
    159.         }
    160.  
    161.         public static Vector4Int operator*(Vector4Int a, Vector4Int b)
    162.         {
    163.             return new Vector4Int(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
    164.         }
    165.  
    166.         public static Vector4Int operator-(Vector4Int a)
    167.         {
    168.             return new Vector4Int(-a.x, -a.y, -a.z, -a.w);
    169.         }
    170.  
    171.         public static Vector4Int operator*(Vector4Int a, int b)
    172.         {
    173.             return new Vector4Int(a.x * b, a.y * b, a.z * b, a.w * b);
    174.         }
    175.  
    176.         public static Vector4Int operator*(int a, Vector4Int b)
    177.         {
    178.             return new Vector4Int(a * b.x, a * b.y, a * b.z, a * b.w);
    179.         }
    180.  
    181.         public static Vector4Int operator/(Vector4Int a, int b)
    182.         {
    183.             return new Vector4Int(a.x / b, a.y / b, a.z / b, a.w / b);
    184.         }
    185.  
    186.         public static bool operator==(Vector4Int lhs, Vector4Int rhs)
    187.         {
    188.             return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w;
    189.         }
    190.  
    191.         public static bool operator!=(Vector4Int lhs, Vector4Int rhs)
    192.         {
    193.             return !(lhs == rhs);
    194.         }
    195.  
    196.         public override bool Equals(object other)
    197.         {
    198.             if (!(other is Vector4Int)) return false;
    199.  
    200.             return Equals((Vector4Int)other);
    201.         }
    202.  
    203.         public bool Equals(Vector4Int other)
    204.         {
    205.             return this == other;
    206.         }
    207.  
    208.         public override int GetHashCode()
    209.         {
    210.             var yHash = y.GetHashCode();
    211.             var zHash = z.GetHashCode();
    212.             var wHash = w.GetHashCode();
    213.             return x.GetHashCode() ^ (yHash << 8) ^ (yHash >> 24) ^ (zHash << 16) ^ (zHash >> 16) ^ (wHash << 24) ^ (wHash >> 8);
    214.         }
    215.  
    216.         public override string ToString()
    217.         {
    218.             return ToString(null, CultureInfo.InvariantCulture.NumberFormat);
    219.         }
    220.  
    221.         public string ToString(string format)
    222.         {
    223.             return ToString(format, CultureInfo.InvariantCulture.NumberFormat);
    224.         }
    225.  
    226.         public string ToString(string format, IFormatProvider formatProvider)
    227.         {
    228.             return UnityString.Format("({0}, {1}, {2}, {3})", x.ToString(format, formatProvider), y.ToString(format, formatProvider), z.ToString(format, formatProvider), w.ToString(format, formatProvider));
    229.         }
    230.  
    231.         public static Vector4Int zero { get { return s_Zero; } }
    232.         public static Vector4Int one { get { return s_One; } }
    233.  
    234.         private static readonly Vector4Int s_Zero = new Vector4Int(0, 0, 0, 0);
    235.         private static readonly Vector4Int s_One = new Vector4Int(1, 1, 1, 1);
    236.     }
    237. }
    238.  
    completely untested, written quickly in notepad, based off the unity source for Vector3Int:
    https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Math/Vector3Int.cs
     
    arkano22 likes this.
  4. APSchmidt

    APSchmidt

    Joined:
    Aug 8, 2016
    Posts:
    3,211
    I was surprised to see that Vector4 existed; what could it be used for?
     
    Joe-Censored likes this.
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,829
    4-dimensional vector math.

    Specifically in unity things like mesh tangents, and shader logic. Shader logic uses 4d vectors for various things since a lot of the math utilizes a 4x4 matrix for transformations, and a row/col of that matrix will be a 4d vector. Vector4 exists as a type to translate between shaders and unity. Also color information in shaders can be stored as 4d vectors (rgba, argb, etc). As well as when you may just need to do some 4d vector math of your own.
     
    arkano22 and APSchmidt like this.
  6. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    647
    Hi!

    I wrote my own simplistic version of it, but it simply struck me as strange that it did not already exist.

    My use case is a bit special. Im writing a cell based spatial subdivision structure in which cells are four dimensional. So the index of a cell is 4 ints. Might as well write a “CellIndex” struct specific for this.

    Vector4, in addition to matrix multiplication, shaders, storing colors and some unconventional quaternion operations, also comes in handy when interfacing with native code that needs 16 byte alignment for simd intrinsics. I guess i’m a weirdo, but I very often I find myself using Vector4.
     
    Last edited: Jan 14, 2020
  7. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    7,256
    As ridiculous as it sounds, technically doing this is a violation of the Unity Reference Only License in which the Unity source is licensed under :p

    https://unity3d.com/legal/licenses/Unity_Reference_Only_License
     
unityunity