A game about forced loneliness, made by TACStudios
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}