A game about forced loneliness, made by TACStudios
at master 322 lines 18 kB view raw
1using System; 2using System.Runtime.CompilerServices; 3using Unity.IL2CPP.CompilerServices; 4using static Unity.Mathematics.math; 5 6namespace Unity.Mathematics 7{ 8 /// <summary> 9 /// An affine transformation type. 10 /// </summary> 11 [Il2CppEagerStaticClassConstruction] 12 [Serializable] 13 public struct AffineTransform : IEquatable<AffineTransform>, IFormattable 14 { 15 /// <summary> 16 /// The rotation and scale part of the affine transformation. 17 /// </summary> 18 public float3x3 rs; 19 20 /// <summary> 21 /// The translation part of the affine transformation. 22 /// </summary> 23 public float3 t; 24 25 /// <summary>An AffineTransform representing the identity transform.</summary> 26 public static readonly AffineTransform identity = new AffineTransform(float3.zero, float3x3.identity); 27 28 /// <summary> 29 /// An AffineTransform zero value. 30 /// </summary> 31 public static readonly AffineTransform zero; 32 33 /// <summary>Constructs an AffineTransform from a translation represented by a float3 vector and rotation represented by a unit quaternion.</summary> 34 /// <param name="translation">The translation vector.</param> 35 /// <param name="rotation">The rotation quaternion.</param> 36 [MethodImpl(MethodImplOptions.AggressiveInlining)] 37 public AffineTransform(float3 translation, quaternion rotation) 38 { 39 rs = float3x3(rotation); 40 t = translation; 41 } 42 43 /// <summary>Constructs an AffineTransform from a translation represented by a float3 vector, rotation represented by a unit quaternion and scale represented by a float3 vector.</summary> 44 /// <param name="translation">The translation vector.</param> 45 /// <param name="rotation">The rotation quaternion.</param> 46 /// <param name="scale">The scale vector.</param> 47 [MethodImpl(MethodImplOptions.AggressiveInlining)] 48 public AffineTransform(float3 translation, quaternion rotation, float3 scale) 49 { 50 rs = mulScale(math.float3x3(rotation), scale); 51 t = translation; 52 } 53 54 /// <summary>Constructs an AffineTransform from a translation represented by float3 vector and a float3x3 matrix representing both rotation and scale.</summary> 55 /// <param name="translation">The translation vector.</param> 56 /// <param name="rotationScale">The rotation and scale matrix.</param> 57 [MethodImpl(MethodImplOptions.AggressiveInlining)] 58 public AffineTransform(float3 translation, float3x3 rotationScale) 59 { 60 rs = rotationScale; 61 t = translation; 62 } 63 64 /// <summary>Constructs an AffineTransform from float3x3 matrix representating both rotation and scale.</summary> 65 /// <param name="rotationScale">The rotation and scale matrix.</param> 66 [MethodImpl(MethodImplOptions.AggressiveInlining)] 67 public AffineTransform(float3x3 rotationScale) 68 { 69 rs = rotationScale; 70 t = float3.zero; 71 } 72 73 /// <summary>Constructs an AffineTransform from a RigidTransform.</summary> 74 /// <param name="rigid">The RigidTransform.</param> 75 [MethodImpl(MethodImplOptions.AggressiveInlining)] 76 public AffineTransform(RigidTransform rigid) 77 { 78 rs = math.float3x3(rigid.rot); 79 t = rigid.pos; 80 } 81 82 /// <summary>Constructs an AffineTransform from a float3x4 matrix.</summary> 83 /// <param name="m">The float3x4 matrix.</param> 84 [MethodImpl(MethodImplOptions.AggressiveInlining)] 85 public AffineTransform(float3x4 m) 86 { 87 rs = math.float3x3(m.c0, m.c1, m.c2); 88 t = m.c3; 89 } 90 91 /// <summary>Constructs an AffineTransform from a float4x4 matrix.</summary> 92 /// <param name="m">The float4x4 matrix.</param> 93 [MethodImpl(MethodImplOptions.AggressiveInlining)] 94 public AffineTransform(float4x4 m) 95 { 96 rs = math.float3x3(m.c0.xyz, m.c1.xyz, m.c2.xyz); 97 t = m.c3.xyz; 98 } 99 100 /// <summary>Implicit float3x4 cast operator.</summary> 101 /// <param name="m">The AffineTransform.</param> 102 /// <returns>The converted AffineTransform.</returns> 103 [MethodImpl(MethodImplOptions.AggressiveInlining)] 104 public static implicit operator float3x4(AffineTransform m) { return float3x4(m.rs.c0, m.rs.c1, m.rs.c2, m.t); } 105 106 /// <summary>Implicit float4x4 cast operator.</summary> 107 /// <param name="m">The AffineTransform.</param> 108 /// <returns>The converted AffineTransform.</returns> 109 [MethodImpl(MethodImplOptions.AggressiveInlining)] 110 public static implicit operator float4x4(AffineTransform m) { return float4x4(float4(m.rs.c0, 0f), float4(m.rs.c1, 0f), float4(m.rs.c2, 0f), float4(m.t, 1f)); } 111 112 /// <summary>Returns true if the AffineTransform is equal to a given AffineTransform, false otherwise.</summary> 113 /// <param name="rhs">Right hand side argument to compare equality with.</param> 114 /// <returns>The result of the equality comparison.</returns> 115 [MethodImpl(MethodImplOptions.AggressiveInlining)] 116 public bool Equals(AffineTransform rhs) { return rs.Equals(rhs.rs) && t.Equals(rhs.t); } 117 118 /// <summary>Returns true if the AffineTransform is equal to a given AffineTransform, false otherwise.</summary> 119 /// <param name="o">Right hand side argument to compare equality with.</param> 120 /// <returns>The result of the equality comparison.</returns> 121 public override bool Equals(object o) { return o is AffineTransform converted && Equals(converted); } 122 123 /// <summary>Returns a hash code for the AffineTransform.</summary> 124 /// <returns>The computed hash code.</returns> 125 [MethodImpl(MethodImplOptions.AggressiveInlining)] 126 public override int GetHashCode() { return (int)hash(this); } 127 128 /// <summary>Returns a string representation of the AffineTransform.</summary> 129 /// <returns>String representation of the value.</returns> 130 [MethodImpl(MethodImplOptions.AggressiveInlining)] 131 public override string ToString() 132 { 133 return string.Format("AffineTransform(({0}f, {1}f, {2}f, {3}f, {4}f, {5}f, {6}f, {7}f, {8}f), ({9}f, {10}f, {11}f))", 134 rs.c0.x, rs.c1.x, rs.c2.x, rs.c0.y, rs.c1.y, rs.c2.y, rs.c0.z, rs.c1.z, rs.c2.z, t.x, t.y, t.z 135 ); 136 } 137 138 /// <summary>Returns a string representation of the AffineTransform using a specified format and culture-specific format information.</summary> 139 /// <param name="format">Format string to use during string formatting.</param> 140 /// <param name="formatProvider">Format provider to use during string formatting.</param> 141 /// <returns>String representation of the value.</returns> 142 [MethodImpl(MethodImplOptions.AggressiveInlining)] 143 public string ToString(string format, IFormatProvider formatProvider) 144 { 145 return string.Format("AffineTransform(({0}f, {1}f, {2}f, {3}f, {4}f, {5}f, {6}f, {7}f, {8}f), ({9}f, {10}f, {11}f))", 146 rs.c0.x.ToString(format, formatProvider), rs.c1.x.ToString(format, formatProvider), rs.c2.x.ToString(format, formatProvider), 147 rs.c0.y.ToString(format, formatProvider), rs.c1.y.ToString(format, formatProvider), rs.c2.y.ToString(format, formatProvider), 148 rs.c0.z.ToString(format, formatProvider), rs.c1.z.ToString(format, formatProvider), rs.c2.z.ToString(format, formatProvider), 149 t.x.ToString(format, formatProvider), t.y.ToString(format, formatProvider), t.z.ToString(format, formatProvider) 150 ); 151 } 152 } 153 154 public static partial class math 155 { 156 /// <summary>Returns an AffineTransform constructed from a translation represented by a float3 vector and rotation represented by a unit quaternion.</summary> 157 /// <param name="translation">The AffineTransform translation.</param> 158 /// <param name="rotation">The AffineTransform rotation.</param> 159 /// <returns>The AffineTransform given the translation vector and rotation quaternion.</returns> 160 [MethodImpl(MethodImplOptions.AggressiveInlining)] 161 public static AffineTransform AffineTransform(float3 translation, quaternion rotation) { return new AffineTransform(translation, rotation); } 162 163 /// <summary>Returns an AffineTransform constructed from a translation represented by a float3 vector, rotation represented by a unit quaternion and scale represented by a float3 vector.</summary> 164 /// <param name="translation">The translation vector.</param> 165 /// <param name="rotation">The rotation quaternion.</param> 166 /// <param name="scale">The scale vector.</param> 167 /// <returns>The AffineTransform given the translation vector, rotation quaternion and scale vector.</returns> 168 [MethodImpl(MethodImplOptions.AggressiveInlining)] 169 public static AffineTransform AffineTransform(float3 translation, quaternion rotation, float3 scale) { return new AffineTransform(translation, rotation, scale); } 170 171 /// <summary>Returns an AffineTransform constructed from a translation represented by float3 vector and a float3x3 matrix representing both rotation and scale.</summary> 172 /// <param name="translation">The translation vector.</param> 173 /// <param name="rotationScale">The rotation and scale matrix.</param> 174 /// <returns>The AffineTransform given the translation vector and float3x3 matrix.</returns> 175 [MethodImpl(MethodImplOptions.AggressiveInlining)] 176 public static AffineTransform AffineTransform(float3 translation, float3x3 rotationScale) { return new AffineTransform(translation, rotationScale); } 177 178 /// <summary>Returns an AffineTransform constructed from a float3x3 matrix representing both rotation and scale.</summary> 179 /// <param name="rotationScale">The rotation and scale matrix.</param> 180 /// <returns>The AffineTransform given a float3x3 matrix.</returns> 181 [MethodImpl(MethodImplOptions.AggressiveInlining)] 182 public static AffineTransform AffineTransform(float3x3 rotationScale) { return new AffineTransform(rotationScale); } 183 184 /// <summary>Returns an AffineTransform constructed from a float4x4 matrix.</summary> 185 /// <param name="m">The float4x4 matrix.</param> 186 /// <returns>The AffineTransform given a float4x4 matrix.</returns> 187 [MethodImpl(MethodImplOptions.AggressiveInlining)] 188 public static AffineTransform AffineTransform(float4x4 m) { return new AffineTransform(m); } 189 190 /// <summary>Returns an AffineTransform constructed from a float3x4 matrix.</summary> 191 /// <param name="m">The float3x4 matrix.</param> 192 /// <returns>The AffineTransform given a float3x4 matrix.</returns> 193 [MethodImpl(MethodImplOptions.AggressiveInlining)] 194 public static AffineTransform AffineTransform(float3x4 m) { return new AffineTransform(m); } 195 196 /// <summary>Returns an AffineTransform constructed from a RigidTransform.</summary> 197 /// <param name="rigid">The RigidTransform.</param> 198 /// <returns>The AffineTransform given a RigidTransform.</returns> 199 [MethodImpl(MethodImplOptions.AggressiveInlining)] 200 public static AffineTransform AffineTransform(RigidTransform rigid) { return new AffineTransform (rigid); } 201 202 /// <summary>Returns a float4x4 matrix constructed from an AffineTransform.</summary> 203 /// <param name="transform">The AffineTransform.</param> 204 /// <returns>The float4x4 matrix given an AffineTransform.</returns> 205 [MethodImpl(MethodImplOptions.AggressiveInlining)] 206 public static float4x4 float4x4(AffineTransform transform) { return float4x4(float4(transform.rs.c0, 0f), float4(transform.rs.c1, 0f), float4(transform.rs.c2, 0f), float4(transform.t, 1f)); } 207 208 /// <summary>Returns a float3x4 matrix constructed from an AffineTransform.</summary> 209 /// <param name="transform">The AffineTransform.</param> 210 /// <returns>The float3x4 matrix given an AffineTransform.</returns> 211 [MethodImpl(MethodImplOptions.AggressiveInlining)] 212 public static float3x4 float3x4(AffineTransform transform) { return float3x4(transform.rs.c0, transform.rs.c1, transform.rs.c2, transform.t); } 213 214 /// <summary>Returns the result of transforming the AffineTransform b by the AffineTransform a.</summary> 215 /// <param name="a">The AffineTransform on the left.</param> 216 /// <param name="b">The AffineTransform on the right.</param> 217 /// <returns>The AffineTransform of a transforming b.</returns> 218 [MethodImpl(MethodImplOptions.AggressiveInlining)] 219 public static AffineTransform mul(AffineTransform a, AffineTransform b) 220 { 221 return new AffineTransform(transform(a, b.t), mul(a.rs, b.rs)); 222 } 223 224 /// <summary>Returns the result of transforming the AffineTransform b by a float3x3 matrix a.</summary> 225 /// <param name="a">The float3x3 matrix on the left.</param> 226 /// <param name="b">The AffineTransform on the right.</param> 227 /// <returns>The AffineTransform of a transforming b.</returns> 228 [MethodImpl(MethodImplOptions.AggressiveInlining)] 229 public static AffineTransform mul(float3x3 a, AffineTransform b) 230 { 231 return new AffineTransform(mul(a, b.t), mul(a, b.rs)); 232 } 233 234 /// <summary>Returns the result of transforming the float3x3 b by an AffineTransform a.</summary> 235 /// <param name="a">The AffineTransform on the left.</param> 236 /// <param name="b">The float3x3 matrix on the right.</param> 237 /// <returns>The AffineTransform of a transforming b.</returns> 238 [MethodImpl(MethodImplOptions.AggressiveInlining)] 239 public static AffineTransform mul(AffineTransform a, float3x3 b) 240 { 241 return new AffineTransform(a.t, mul(b, a.rs)); 242 } 243 244 /// <summary>Returns the result of transforming a float4 homogeneous coordinate by an AffineTransform.</summary> 245 /// <param name="a">The AffineTransform.</param> 246 /// <param name="pos">The position to be transformed.</param> 247 /// <returns>The transformed position.</returns> 248 [MethodImpl(MethodImplOptions.AggressiveInlining)] 249 public static float4 mul(AffineTransform a, float4 pos) 250 { 251 return float4(mul(a.rs, pos.xyz) + a.t * pos.w, pos.w); 252 } 253 254 /// <summary>Returns the result of rotating a float3 vector by an AffineTransform.</summary> 255 /// <param name="a">The AffineTransform.</param> 256 /// <param name="dir">The direction vector to rotate.</param> 257 /// <returns>The rotated direction vector.</returns> 258 [MethodImpl(MethodImplOptions.AggressiveInlining)] 259 public static float3 rotate(AffineTransform a, float3 dir) 260 { 261 return mul(a.rs, dir); 262 } 263 264 /// <summary>Returns the result of transforming a float3 point by an AffineTransform.</summary> 265 /// <param name="a">The AffineTransform.</param> 266 /// <param name="pos">The position to transform.</param> 267 /// <returns>The transformed position.</returns> 268 [MethodImpl(MethodImplOptions.AggressiveInlining)] 269 public static float3 transform(AffineTransform a, float3 pos) 270 { 271 return a.t + mul(a.rs, pos); 272 } 273 274 /// <summary>Returns the inverse of an AffineTransform.</summary> 275 /// <param name="a">The AffineTransform to invert.</param> 276 /// <returns>The inverse AffineTransform.</returns> 277 [MethodImpl(MethodImplOptions.AggressiveInlining)] 278 public static AffineTransform inverse(AffineTransform a) 279 { 280 AffineTransform inv; 281 inv.rs = pseudoinverse(a.rs); 282 inv.t = mul(inv.rs, -a.t); 283 return inv; 284 } 285 286 /// <summary>Decomposes the AffineTransform in translation, rotation and scale.</summary> 287 /// <param name="a">The AffineTransform</param> 288 /// <param name="translation">The decomposed translation vector of the AffineTransform.</param> 289 /// <param name="rotation">The decomposed rotation quaternion of the AffineTransform.</param> 290 /// <param name="scale">The decomposed scale of the AffineTransform.</param> 291 [MethodImpl(MethodImplOptions.AggressiveInlining)] 292 public static void decompose(AffineTransform a, out float3 translation, out quaternion rotation, out float3 scale) 293 { 294 translation = a.t; 295 rotation = math.rotation(a.rs); 296 var sm = mul(float3x3(conjugate(rotation)), a.rs); 297 scale = float3(sm.c0.x, sm.c1.y, sm.c2.z); 298 } 299 300 /// <summary>Returns a uint hash code of an AffineTransform.</summary> 301 /// <param name="a">The AffineTransform to hash.</param> 302 /// <returns>The hash code of the input AffineTransform.</returns> 303 [MethodImpl(MethodImplOptions.AggressiveInlining)] 304 public static uint hash(AffineTransform a) 305 { 306 return hash(a.rs) + 0xC5C5394Bu * hash(a.t); 307 } 308 309 /// <summary> 310 /// Returns a uint4 vector hash code of an AffineTransform. 311 /// When multiple elements are to be hashes together, it can more efficient to calculate and combine wide hash 312 /// that are only reduced to a narrow uint hash at the very end instead of at every step. 313 /// </summary> 314 /// <param name="a">The AffineTransform to hash.</param> 315 /// <returns>The uint4 wide hash code.</returns> 316 [MethodImpl(MethodImplOptions.AggressiveInlining)] 317 public static uint4 hashwide(AffineTransform a) 318 { 319 return hashwide(a.rs).xyzz + 0xC5C5394Bu * hashwide(a.t).xyzz; 320 } 321 } 322}