Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Matrix4x4.cs
Go to the documentation of this file.
7
8namespace System.Numerics;
9
10[Intrinsic]
11public struct Matrix4x4 : IEquatable<Matrix4x4>
12{
13 private struct CanonicalBasis
14 {
15 public Vector3 Row0;
16
17 public Vector3 Row1;
18
19 public Vector3 Row2;
20 }
21
22 private struct VectorBasis
23 {
24 public unsafe Vector3* Element0;
25
26 public unsafe Vector3* Element1;
27
28 public unsafe Vector3* Element2;
29 }
30
31 private static readonly Matrix4x4 _identity = new Matrix4x4(1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f);
32
33 public float M11;
34
35 public float M12;
36
37 public float M13;
38
39 public float M14;
40
41 public float M21;
42
43 public float M22;
44
45 public float M23;
46
47 public float M24;
48
49 public float M31;
50
51 public float M32;
52
53 public float M33;
54
55 public float M34;
56
57 public float M41;
58
59 public float M42;
60
61 public float M43;
62
63 public float M44;
64
65 public static Matrix4x4 Identity => _identity;
66
67 public readonly bool IsIdentity
68 {
69 get
70 {
71 if (M11 == 1f && M22 == 1f && M33 == 1f && M44 == 1f && M12 == 0f && M13 == 0f && M14 == 0f && M21 == 0f && M23 == 0f && M24 == 0f && M31 == 0f && M32 == 0f && M34 == 0f && M41 == 0f && M42 == 0f)
72 {
73 return M43 == 0f;
74 }
75 return false;
76 }
77 }
78
80 {
81 readonly get
82 {
83 return new Vector3(M41, M42, M43);
84 }
85 set
86 {
87 M41 = value.X;
88 M42 = value.Y;
89 M43 = value.Z;
90 }
91 }
92
93 public Matrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
94 {
95 M11 = m11;
96 M12 = m12;
97 M13 = m13;
98 M14 = m14;
99 M21 = m21;
100 M22 = m22;
101 M23 = m23;
102 M24 = m24;
103 M31 = m31;
104 M32 = m32;
105 M33 = m33;
106 M34 = m34;
107 M41 = m41;
108 M42 = m42;
109 M43 = m43;
110 M44 = m44;
111 }
112
114 {
115 M11 = value.M11;
116 M12 = value.M12;
117 M13 = 0f;
118 M14 = 0f;
119 M21 = value.M21;
120 M22 = value.M22;
121 M23 = 0f;
122 M24 = 0f;
123 M31 = 0f;
124 M32 = 0f;
125 M33 = 1f;
126 M34 = 0f;
127 M41 = value.M31;
128 M42 = value.M32;
129 M43 = 0f;
130 M44 = 1f;
131 }
132
133 public unsafe static Matrix4x4 operator +(Matrix4x4 value1, Matrix4x4 value2)
134 {
136 {
137 }
138 if (Sse.IsSupported)
139 {
140 Sse.Store(&value1.M11, Sse.Add(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)));
141 Sse.Store(&value1.M21, Sse.Add(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value2.M21)));
142 Sse.Store(&value1.M31, Sse.Add(Sse.LoadVector128(&value1.M31), Sse.LoadVector128(&value2.M31)));
143 Sse.Store(&value1.M41, Sse.Add(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41)));
144 return value1;
145 }
146 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
147 result.M11 = value1.M11 + value2.M11;
148 result.M12 = value1.M12 + value2.M12;
149 result.M13 = value1.M13 + value2.M13;
150 result.M14 = value1.M14 + value2.M14;
151 result.M21 = value1.M21 + value2.M21;
152 result.M22 = value1.M22 + value2.M22;
153 result.M23 = value1.M23 + value2.M23;
154 result.M24 = value1.M24 + value2.M24;
155 result.M31 = value1.M31 + value2.M31;
156 result.M32 = value1.M32 + value2.M32;
157 result.M33 = value1.M33 + value2.M33;
158 result.M34 = value1.M34 + value2.M34;
159 result.M41 = value1.M41 + value2.M41;
160 result.M42 = value1.M42 + value2.M42;
161 result.M43 = value1.M43 + value2.M43;
162 result.M44 = value1.M44 + value2.M44;
163 return result;
164 }
165
166 public unsafe static bool operator ==(Matrix4x4 value1, Matrix4x4 value2)
167 {
169 {
170 }
171 if (Sse.IsSupported)
172 {
174 {
175 return VectorMath.Equal(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41));
176 }
177 return false;
178 }
179 if (value1.M11 == value2.M11 && value1.M22 == value2.M22 && value1.M33 == value2.M33 && value1.M44 == value2.M44 && value1.M12 == value2.M12 && value1.M13 == value2.M13 && value1.M14 == value2.M14 && value1.M21 == value2.M21 && value1.M23 == value2.M23 && value1.M24 == value2.M24 && value1.M31 == value2.M31 && value1.M32 == value2.M32 && value1.M34 == value2.M34 && value1.M41 == value2.M41 && value1.M42 == value2.M42)
180 {
181 return value1.M43 == value2.M43;
182 }
183 return false;
184 }
185
186 public unsafe static bool operator !=(Matrix4x4 value1, Matrix4x4 value2)
187 {
189 {
190 }
191 if (Sse.IsSupported)
192 {
194 {
195 return VectorMath.NotEqual(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41));
196 }
197 return true;
198 }
199 if (value1.M11 == value2.M11 && value1.M12 == value2.M12 && value1.M13 == value2.M13 && value1.M14 == value2.M14 && value1.M21 == value2.M21 && value1.M22 == value2.M22 && value1.M23 == value2.M23 && value1.M24 == value2.M24 && value1.M31 == value2.M31 && value1.M32 == value2.M32 && value1.M33 == value2.M33 && value1.M34 == value2.M34 && value1.M41 == value2.M41 && value1.M42 == value2.M42 && value1.M43 == value2.M43)
200 {
201 return value1.M44 != value2.M44;
202 }
203 return true;
204 }
205
206 public unsafe static Matrix4x4 operator *(Matrix4x4 value1, Matrix4x4 value2)
207 {
209 {
210 }
211 if (Sse.IsSupported)
212 {
213 Vector128<float> vector = Sse.LoadVector128(&value1.M11);
214 Sse.Store(&value1.M11, Sse.Add(Sse.Add(Sse.Multiply(Sse.Shuffle(vector, vector, 0), Sse.LoadVector128(&value2.M11)), Sse.Multiply(Sse.Shuffle(vector, vector, 85), Sse.LoadVector128(&value2.M21))), Sse.Add(Sse.Multiply(Sse.Shuffle(vector, vector, 170), Sse.LoadVector128(&value2.M31)), Sse.Multiply(Sse.Shuffle(vector, vector, byte.MaxValue), Sse.LoadVector128(&value2.M41)))));
215 vector = Sse.LoadVector128(&value1.M21);
216 Sse.Store(&value1.M21, Sse.Add(Sse.Add(Sse.Multiply(Sse.Shuffle(vector, vector, 0), Sse.LoadVector128(&value2.M11)), Sse.Multiply(Sse.Shuffle(vector, vector, 85), Sse.LoadVector128(&value2.M21))), Sse.Add(Sse.Multiply(Sse.Shuffle(vector, vector, 170), Sse.LoadVector128(&value2.M31)), Sse.Multiply(Sse.Shuffle(vector, vector, byte.MaxValue), Sse.LoadVector128(&value2.M41)))));
217 vector = Sse.LoadVector128(&value1.M31);
218 Sse.Store(&value1.M31, Sse.Add(Sse.Add(Sse.Multiply(Sse.Shuffle(vector, vector, 0), Sse.LoadVector128(&value2.M11)), Sse.Multiply(Sse.Shuffle(vector, vector, 85), Sse.LoadVector128(&value2.M21))), Sse.Add(Sse.Multiply(Sse.Shuffle(vector, vector, 170), Sse.LoadVector128(&value2.M31)), Sse.Multiply(Sse.Shuffle(vector, vector, byte.MaxValue), Sse.LoadVector128(&value2.M41)))));
219 vector = Sse.LoadVector128(&value1.M41);
220 Sse.Store(&value1.M41, Sse.Add(Sse.Add(Sse.Multiply(Sse.Shuffle(vector, vector, 0), Sse.LoadVector128(&value2.M11)), Sse.Multiply(Sse.Shuffle(vector, vector, 85), Sse.LoadVector128(&value2.M21))), Sse.Add(Sse.Multiply(Sse.Shuffle(vector, vector, 170), Sse.LoadVector128(&value2.M31)), Sse.Multiply(Sse.Shuffle(vector, vector, byte.MaxValue), Sse.LoadVector128(&value2.M41)))));
221 return value1;
222 }
223 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
224 result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21 + value1.M13 * value2.M31 + value1.M14 * value2.M41;
225 result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22 + value1.M13 * value2.M32 + value1.M14 * value2.M42;
226 result.M13 = value1.M11 * value2.M13 + value1.M12 * value2.M23 + value1.M13 * value2.M33 + value1.M14 * value2.M43;
227 result.M14 = value1.M11 * value2.M14 + value1.M12 * value2.M24 + value1.M13 * value2.M34 + value1.M14 * value2.M44;
228 result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21 + value1.M23 * value2.M31 + value1.M24 * value2.M41;
229 result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22 + value1.M23 * value2.M32 + value1.M24 * value2.M42;
230 result.M23 = value1.M21 * value2.M13 + value1.M22 * value2.M23 + value1.M23 * value2.M33 + value1.M24 * value2.M43;
231 result.M24 = value1.M21 * value2.M14 + value1.M22 * value2.M24 + value1.M23 * value2.M34 + value1.M24 * value2.M44;
232 result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value1.M33 * value2.M31 + value1.M34 * value2.M41;
233 result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value1.M33 * value2.M32 + value1.M34 * value2.M42;
234 result.M33 = value1.M31 * value2.M13 + value1.M32 * value2.M23 + value1.M33 * value2.M33 + value1.M34 * value2.M43;
235 result.M34 = value1.M31 * value2.M14 + value1.M32 * value2.M24 + value1.M33 * value2.M34 + value1.M34 * value2.M44;
236 result.M41 = value1.M41 * value2.M11 + value1.M42 * value2.M21 + value1.M43 * value2.M31 + value1.M44 * value2.M41;
237 result.M42 = value1.M41 * value2.M12 + value1.M42 * value2.M22 + value1.M43 * value2.M32 + value1.M44 * value2.M42;
238 result.M43 = value1.M41 * value2.M13 + value1.M42 * value2.M23 + value1.M43 * value2.M33 + value1.M44 * value2.M43;
239 result.M44 = value1.M41 * value2.M14 + value1.M42 * value2.M24 + value1.M43 * value2.M34 + value1.M44 * value2.M44;
240 return result;
241 }
242
243 public unsafe static Matrix4x4 operator *(Matrix4x4 value1, float value2)
244 {
246 {
247 }
248 if (Sse.IsSupported)
249 {
250 Vector128<float> right = Vector128.Create(value2);
251 Sse.Store(&value1.M11, Sse.Multiply(Sse.LoadVector128(&value1.M11), right));
252 Sse.Store(&value1.M21, Sse.Multiply(Sse.LoadVector128(&value1.M21), right));
253 Sse.Store(&value1.M31, Sse.Multiply(Sse.LoadVector128(&value1.M31), right));
254 Sse.Store(&value1.M41, Sse.Multiply(Sse.LoadVector128(&value1.M41), right));
255 return value1;
256 }
257 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
258 result.M11 = value1.M11 * value2;
259 result.M12 = value1.M12 * value2;
260 result.M13 = value1.M13 * value2;
261 result.M14 = value1.M14 * value2;
262 result.M21 = value1.M21 * value2;
263 result.M22 = value1.M22 * value2;
264 result.M23 = value1.M23 * value2;
265 result.M24 = value1.M24 * value2;
266 result.M31 = value1.M31 * value2;
267 result.M32 = value1.M32 * value2;
268 result.M33 = value1.M33 * value2;
269 result.M34 = value1.M34 * value2;
270 result.M41 = value1.M41 * value2;
271 result.M42 = value1.M42 * value2;
272 result.M43 = value1.M43 * value2;
273 result.M44 = value1.M44 * value2;
274 return result;
275 }
276
277 public unsafe static Matrix4x4 operator -(Matrix4x4 value1, Matrix4x4 value2)
278 {
280 {
281 }
282 if (Sse.IsSupported)
283 {
284 Sse.Store(&value1.M11, Sse.Subtract(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)));
285 Sse.Store(&value1.M21, Sse.Subtract(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value2.M21)));
286 Sse.Store(&value1.M31, Sse.Subtract(Sse.LoadVector128(&value1.M31), Sse.LoadVector128(&value2.M31)));
287 Sse.Store(&value1.M41, Sse.Subtract(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41)));
288 return value1;
289 }
290 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
291 result.M11 = value1.M11 - value2.M11;
292 result.M12 = value1.M12 - value2.M12;
293 result.M13 = value1.M13 - value2.M13;
294 result.M14 = value1.M14 - value2.M14;
295 result.M21 = value1.M21 - value2.M21;
296 result.M22 = value1.M22 - value2.M22;
297 result.M23 = value1.M23 - value2.M23;
298 result.M24 = value1.M24 - value2.M24;
299 result.M31 = value1.M31 - value2.M31;
300 result.M32 = value1.M32 - value2.M32;
301 result.M33 = value1.M33 - value2.M33;
302 result.M34 = value1.M34 - value2.M34;
303 result.M41 = value1.M41 - value2.M41;
304 result.M42 = value1.M42 - value2.M42;
305 result.M43 = value1.M43 - value2.M43;
306 result.M44 = value1.M44 - value2.M44;
307 return result;
308 }
309
310 public unsafe static Matrix4x4 operator -(Matrix4x4 value)
311 {
313 {
314 }
315 if (Sse.IsSupported)
316 {
318 Sse.Store(&value.M11, Sse.Subtract(zero, Sse.LoadVector128(&value.M11)));
319 Sse.Store(&value.M21, Sse.Subtract(zero, Sse.LoadVector128(&value.M21)));
320 Sse.Store(&value.M31, Sse.Subtract(zero, Sse.LoadVector128(&value.M31)));
321 Sse.Store(&value.M41, Sse.Subtract(zero, Sse.LoadVector128(&value.M41)));
322 return value;
323 }
324 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
325 result.M11 = 0f - value.M11;
326 result.M12 = 0f - value.M12;
327 result.M13 = 0f - value.M13;
328 result.M14 = 0f - value.M14;
329 result.M21 = 0f - value.M21;
330 result.M22 = 0f - value.M22;
331 result.M23 = 0f - value.M23;
332 result.M24 = 0f - value.M24;
333 result.M31 = 0f - value.M31;
334 result.M32 = 0f - value.M32;
335 result.M33 = 0f - value.M33;
336 result.M34 = 0f - value.M34;
337 result.M41 = 0f - value.M41;
338 result.M42 = 0f - value.M42;
339 result.M43 = 0f - value.M43;
340 result.M44 = 0f - value.M44;
341 return result;
342 }
343
344 [MethodImpl(MethodImplOptions.AggressiveInlining)]
345 public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2)
346 {
347 return value1 + value2;
348 }
349
350 public static Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector)
351 {
352 Vector3 left = objectPosition - cameraPosition;
353 float num = left.LengthSquared();
354 left = ((!(num < 0.0001f)) ? Vector3.Multiply(left, 1f / MathF.Sqrt(num)) : (-cameraForwardVector));
355 Vector3 vector = Vector3.Normalize(Vector3.Cross(cameraUpVector, left));
356 Vector3 vector2 = Vector3.Cross(left, vector);
357 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
358 result.M11 = vector.X;
359 result.M12 = vector.Y;
360 result.M13 = vector.Z;
361 result.M14 = 0f;
362 result.M21 = vector2.X;
363 result.M22 = vector2.Y;
364 result.M23 = vector2.Z;
365 result.M24 = 0f;
366 result.M31 = left.X;
367 result.M32 = left.Y;
368 result.M33 = left.Z;
369 result.M34 = 0f;
370 result.M41 = objectPosition.X;
371 result.M42 = objectPosition.Y;
372 result.M43 = objectPosition.Z;
373 result.M44 = 1f;
374 return result;
375 }
376
377 public static Matrix4x4 CreateConstrainedBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 rotateAxis, Vector3 cameraForwardVector, Vector3 objectForwardVector)
378 {
379 Vector3 left = objectPosition - cameraPosition;
380 float num = left.LengthSquared();
381 left = ((!(num < 0.0001f)) ? Vector3.Multiply(left, 1f / MathF.Sqrt(num)) : (-cameraForwardVector));
382 Vector3 vector = rotateAxis;
383 float x = Vector3.Dot(rotateAxis, left);
384 Vector3 vector3;
385 Vector3 vector2;
386 if (MathF.Abs(x) > 0.99825466f)
387 {
388 vector2 = objectForwardVector;
389 x = Vector3.Dot(rotateAxis, vector2);
390 if (MathF.Abs(x) > 0.99825466f)
391 {
392 vector2 = ((MathF.Abs(rotateAxis.Z) > 0.99825466f) ? new Vector3(1f, 0f, 0f) : new Vector3(0f, 0f, -1f));
393 }
394 vector3 = Vector3.Normalize(Vector3.Cross(rotateAxis, vector2));
395 vector2 = Vector3.Normalize(Vector3.Cross(vector3, rotateAxis));
396 }
397 else
398 {
399 vector3 = Vector3.Normalize(Vector3.Cross(rotateAxis, left));
400 vector2 = Vector3.Normalize(Vector3.Cross(vector3, vector));
401 }
402 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
403 result.M11 = vector3.X;
404 result.M12 = vector3.Y;
405 result.M13 = vector3.Z;
406 result.M14 = 0f;
407 result.M21 = vector.X;
408 result.M22 = vector.Y;
409 result.M23 = vector.Z;
410 result.M24 = 0f;
411 result.M31 = vector2.X;
412 result.M32 = vector2.Y;
413 result.M33 = vector2.Z;
414 result.M34 = 0f;
415 result.M41 = objectPosition.X;
416 result.M42 = objectPosition.Y;
417 result.M43 = objectPosition.Z;
418 result.M44 = 1f;
419 return result;
420 }
421
422 public static Matrix4x4 CreateFromAxisAngle(Vector3 axis, float angle)
423 {
424 float x = axis.X;
425 float y = axis.Y;
426 float z = axis.Z;
427 float num = MathF.Sin(angle);
428 float num2 = MathF.Cos(angle);
429 float num3 = x * x;
430 float num4 = y * y;
431 float num5 = z * z;
432 float num6 = x * y;
433 float num7 = x * z;
434 float num8 = y * z;
435 Matrix4x4 identity = Identity;
436 identity.M11 = num3 + num2 * (1f - num3);
437 identity.M12 = num6 - num2 * num6 + num * z;
438 identity.M13 = num7 - num2 * num7 - num * y;
439 identity.M21 = num6 - num2 * num6 - num * z;
440 identity.M22 = num4 + num2 * (1f - num4);
441 identity.M23 = num8 - num2 * num8 + num * x;
442 identity.M31 = num7 - num2 * num7 + num * y;
443 identity.M32 = num8 - num2 * num8 - num * x;
444 identity.M33 = num5 + num2 * (1f - num5);
445 return identity;
446 }
447
448 public static Matrix4x4 CreateFromQuaternion(Quaternion quaternion)
449 {
450 Matrix4x4 identity = Identity;
451 float num = quaternion.X * quaternion.X;
452 float num2 = quaternion.Y * quaternion.Y;
453 float num3 = quaternion.Z * quaternion.Z;
454 float num4 = quaternion.X * quaternion.Y;
455 float num5 = quaternion.Z * quaternion.W;
456 float num6 = quaternion.Z * quaternion.X;
457 float num7 = quaternion.Y * quaternion.W;
458 float num8 = quaternion.Y * quaternion.Z;
459 float num9 = quaternion.X * quaternion.W;
460 identity.M11 = 1f - 2f * (num2 + num3);
461 identity.M12 = 2f * (num4 + num5);
462 identity.M13 = 2f * (num6 - num7);
463 identity.M21 = 2f * (num4 - num5);
464 identity.M22 = 1f - 2f * (num3 + num);
465 identity.M23 = 2f * (num8 + num9);
466 identity.M31 = 2f * (num6 + num7);
467 identity.M32 = 2f * (num8 - num9);
468 identity.M33 = 1f - 2f * (num2 + num);
469 return identity;
470 }
471
472 public static Matrix4x4 CreateFromYawPitchRoll(float yaw, float pitch, float roll)
473 {
474 Quaternion quaternion = Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll);
475 return CreateFromQuaternion(quaternion);
476 }
477
478 public static Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector)
479 {
480 Vector3 vector = Vector3.Normalize(cameraPosition - cameraTarget);
481 Vector3 vector2 = Vector3.Normalize(Vector3.Cross(cameraUpVector, vector));
482 Vector3 vector3 = Vector3.Cross(vector, vector2);
483 Matrix4x4 identity = Identity;
484 identity.M11 = vector2.X;
485 identity.M12 = vector3.X;
486 identity.M13 = vector.X;
487 identity.M21 = vector2.Y;
488 identity.M22 = vector3.Y;
489 identity.M23 = vector.Y;
490 identity.M31 = vector2.Z;
491 identity.M32 = vector3.Z;
492 identity.M33 = vector.Z;
493 identity.M41 = 0f - Vector3.Dot(vector2, cameraPosition);
494 identity.M42 = 0f - Vector3.Dot(vector3, cameraPosition);
495 identity.M43 = 0f - Vector3.Dot(vector, cameraPosition);
496 return identity;
497 }
498
499 public static Matrix4x4 CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane)
500 {
501 Matrix4x4 identity = Identity;
502 identity.M11 = 2f / width;
503 identity.M22 = 2f / height;
504 identity.M33 = 1f / (zNearPlane - zFarPlane);
505 identity.M43 = zNearPlane / (zNearPlane - zFarPlane);
506 return identity;
507 }
508
509 public static Matrix4x4 CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane)
510 {
511 Matrix4x4 identity = Identity;
512 identity.M11 = 2f / (right - left);
513 identity.M22 = 2f / (top - bottom);
514 identity.M33 = 1f / (zNearPlane - zFarPlane);
515 identity.M41 = (left + right) / (left - right);
516 identity.M42 = (top + bottom) / (bottom - top);
517 identity.M43 = zNearPlane / (zNearPlane - zFarPlane);
518 return identity;
519 }
520
521 public static Matrix4x4 CreatePerspective(float width, float height, float nearPlaneDistance, float farPlaneDistance)
522 {
523 if (nearPlaneDistance <= 0f)
524 {
525 throw new ArgumentOutOfRangeException("nearPlaneDistance");
526 }
527 if (farPlaneDistance <= 0f)
528 {
529 throw new ArgumentOutOfRangeException("farPlaneDistance");
530 }
531 if (nearPlaneDistance >= farPlaneDistance)
532 {
533 throw new ArgumentOutOfRangeException("nearPlaneDistance");
534 }
535 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
536 result.M11 = 2f * nearPlaneDistance / width;
537 result.M12 = (result.M13 = (result.M14 = 0f));
538 result.M22 = 2f * nearPlaneDistance / height;
539 result.M21 = (result.M23 = (result.M24 = 0f));
540 float num = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
541 result.M31 = (result.M32 = 0f);
542 result.M34 = -1f;
543 result.M41 = (result.M42 = (result.M44 = 0f));
544 result.M43 = nearPlaneDistance * num;
545 return result;
546 }
547
548 public static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance)
549 {
550 if (fieldOfView <= 0f || fieldOfView >= (float)Math.PI)
551 {
552 throw new ArgumentOutOfRangeException("fieldOfView");
553 }
554 if (nearPlaneDistance <= 0f)
555 {
556 throw new ArgumentOutOfRangeException("nearPlaneDistance");
557 }
558 if (farPlaneDistance <= 0f)
559 {
560 throw new ArgumentOutOfRangeException("farPlaneDistance");
561 }
562 if (nearPlaneDistance >= farPlaneDistance)
563 {
564 throw new ArgumentOutOfRangeException("nearPlaneDistance");
565 }
566 float num = 1f / MathF.Tan(fieldOfView * 0.5f);
567 float m = num / aspectRatio;
568 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
569 result.M11 = m;
570 result.M12 = (result.M13 = (result.M14 = 0f));
571 result.M22 = num;
572 result.M21 = (result.M23 = (result.M24 = 0f));
573 result.M31 = (result.M32 = 0f);
574 float num2 = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
575 result.M34 = -1f;
576 result.M41 = (result.M42 = (result.M44 = 0f));
577 result.M43 = nearPlaneDistance * num2;
578 return result;
579 }
580
581 public static Matrix4x4 CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlaneDistance, float farPlaneDistance)
582 {
583 if (nearPlaneDistance <= 0f)
584 {
585 throw new ArgumentOutOfRangeException("nearPlaneDistance");
586 }
587 if (farPlaneDistance <= 0f)
588 {
589 throw new ArgumentOutOfRangeException("farPlaneDistance");
590 }
591 if (nearPlaneDistance >= farPlaneDistance)
592 {
593 throw new ArgumentOutOfRangeException("nearPlaneDistance");
594 }
595 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
596 result.M11 = 2f * nearPlaneDistance / (right - left);
597 result.M12 = (result.M13 = (result.M14 = 0f));
598 result.M22 = 2f * nearPlaneDistance / (top - bottom);
599 result.M21 = (result.M23 = (result.M24 = 0f));
600 result.M31 = (left + right) / (right - left);
601 result.M32 = (top + bottom) / (top - bottom);
602 float num = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
603 result.M34 = -1f;
604 result.M43 = nearPlaneDistance * num;
605 result.M41 = (result.M42 = (result.M44 = 0f));
606 return result;
607 }
608
610 {
612 float x = value.Normal.X;
613 float y = value.Normal.Y;
614 float z = value.Normal.Z;
615 float num = -2f * x;
616 float num2 = -2f * y;
617 float num3 = -2f * z;
618 Matrix4x4 identity = Identity;
619 identity.M11 = num * x + 1f;
620 identity.M12 = num2 * x;
621 identity.M13 = num3 * x;
622 identity.M21 = num * y;
623 identity.M22 = num2 * y + 1f;
624 identity.M23 = num3 * y;
625 identity.M31 = num * z;
626 identity.M32 = num2 * z;
627 identity.M33 = num3 * z + 1f;
628 identity.M41 = num * value.D;
629 identity.M42 = num2 * value.D;
630 identity.M43 = num3 * value.D;
631 return identity;
632 }
633
634 public static Matrix4x4 CreateRotationX(float radians)
635 {
636 Matrix4x4 identity = Identity;
637 float num = MathF.Cos(radians);
638 float num2 = MathF.Sin(radians);
639 identity.M22 = num;
640 identity.M23 = num2;
641 identity.M32 = 0f - num2;
642 identity.M33 = num;
643 return identity;
644 }
645
646 public static Matrix4x4 CreateRotationX(float radians, Vector3 centerPoint)
647 {
648 Matrix4x4 identity = Identity;
649 float num = MathF.Cos(radians);
650 float num2 = MathF.Sin(radians);
651 float m = centerPoint.Y * (1f - num) + centerPoint.Z * num2;
652 float m2 = centerPoint.Z * (1f - num) - centerPoint.Y * num2;
653 identity.M22 = num;
654 identity.M23 = num2;
655 identity.M32 = 0f - num2;
656 identity.M33 = num;
657 identity.M42 = m;
658 identity.M43 = m2;
659 return identity;
660 }
661
662 public static Matrix4x4 CreateRotationY(float radians)
663 {
664 Matrix4x4 identity = Identity;
665 float num = MathF.Cos(radians);
666 float num2 = MathF.Sin(radians);
667 identity.M11 = num;
668 identity.M13 = 0f - num2;
669 identity.M31 = num2;
670 identity.M33 = num;
671 return identity;
672 }
673
674 public static Matrix4x4 CreateRotationY(float radians, Vector3 centerPoint)
675 {
676 Matrix4x4 identity = Identity;
677 float num = MathF.Cos(radians);
678 float num2 = MathF.Sin(radians);
679 float m = centerPoint.X * (1f - num) - centerPoint.Z * num2;
680 float m2 = centerPoint.Z * (1f - num) + centerPoint.X * num2;
681 identity.M11 = num;
682 identity.M13 = 0f - num2;
683 identity.M31 = num2;
684 identity.M33 = num;
685 identity.M41 = m;
686 identity.M43 = m2;
687 return identity;
688 }
689
690 public static Matrix4x4 CreateRotationZ(float radians)
691 {
692 Matrix4x4 identity = Identity;
693 float num = MathF.Cos(radians);
694 float num2 = MathF.Sin(radians);
695 identity.M11 = num;
696 identity.M12 = num2;
697 identity.M21 = 0f - num2;
698 identity.M22 = num;
699 return identity;
700 }
701
702 public static Matrix4x4 CreateRotationZ(float radians, Vector3 centerPoint)
703 {
704 Matrix4x4 identity = Identity;
705 float num = MathF.Cos(radians);
706 float num2 = MathF.Sin(radians);
707 float m = centerPoint.X * (1f - num) + centerPoint.Y * num2;
708 float m2 = centerPoint.Y * (1f - num) - centerPoint.X * num2;
709 identity.M11 = num;
710 identity.M12 = num2;
711 identity.M21 = 0f - num2;
712 identity.M22 = num;
713 identity.M41 = m;
714 identity.M42 = m2;
715 return identity;
716 }
717
718 public static Matrix4x4 CreateScale(float xScale, float yScale, float zScale)
719 {
720 Matrix4x4 identity = Identity;
721 identity.M11 = xScale;
722 identity.M22 = yScale;
723 identity.M33 = zScale;
724 return identity;
725 }
726
727 public static Matrix4x4 CreateScale(float xScale, float yScale, float zScale, Vector3 centerPoint)
728 {
729 Matrix4x4 identity = Identity;
730 float m = centerPoint.X * (1f - xScale);
731 float m2 = centerPoint.Y * (1f - yScale);
732 float m3 = centerPoint.Z * (1f - zScale);
733 identity.M11 = xScale;
734 identity.M22 = yScale;
735 identity.M33 = zScale;
736 identity.M41 = m;
737 identity.M42 = m2;
738 identity.M43 = m3;
739 return identity;
740 }
741
742 public static Matrix4x4 CreateScale(Vector3 scales)
743 {
744 Matrix4x4 identity = Identity;
745 identity.M11 = scales.X;
746 identity.M22 = scales.Y;
747 identity.M33 = scales.Z;
748 return identity;
749 }
750
751 public static Matrix4x4 CreateScale(Vector3 scales, Vector3 centerPoint)
752 {
753 Matrix4x4 identity = Identity;
754 float m = centerPoint.X * (1f - scales.X);
755 float m2 = centerPoint.Y * (1f - scales.Y);
756 float m3 = centerPoint.Z * (1f - scales.Z);
757 identity.M11 = scales.X;
758 identity.M22 = scales.Y;
759 identity.M33 = scales.Z;
760 identity.M41 = m;
761 identity.M42 = m2;
762 identity.M43 = m3;
763 return identity;
764 }
765
766 public static Matrix4x4 CreateScale(float scale)
767 {
768 Matrix4x4 identity = Identity;
769 identity.M11 = scale;
770 identity.M22 = scale;
771 identity.M33 = scale;
772 return identity;
773 }
774
775 public static Matrix4x4 CreateScale(float scale, Vector3 centerPoint)
776 {
777 Matrix4x4 identity = Identity;
778 float m = centerPoint.X * (1f - scale);
779 float m2 = centerPoint.Y * (1f - scale);
780 float m3 = centerPoint.Z * (1f - scale);
781 identity.M11 = scale;
782 identity.M22 = scale;
783 identity.M33 = scale;
784 identity.M41 = m;
785 identity.M42 = m2;
786 identity.M43 = m3;
787 return identity;
788 }
789
790 public static Matrix4x4 CreateShadow(Vector3 lightDirection, Plane plane)
791 {
792 Plane plane2 = Plane.Normalize(plane);
793 float num = plane2.Normal.X * lightDirection.X + plane2.Normal.Y * lightDirection.Y + plane2.Normal.Z * lightDirection.Z;
794 float num2 = 0f - plane2.Normal.X;
795 float num3 = 0f - plane2.Normal.Y;
796 float num4 = 0f - plane2.Normal.Z;
797 float num5 = 0f - plane2.D;
798 Matrix4x4 identity = Identity;
799 identity.M11 = num2 * lightDirection.X + num;
800 identity.M21 = num3 * lightDirection.X;
801 identity.M31 = num4 * lightDirection.X;
802 identity.M41 = num5 * lightDirection.X;
803 identity.M12 = num2 * lightDirection.Y;
804 identity.M22 = num3 * lightDirection.Y + num;
805 identity.M32 = num4 * lightDirection.Y;
806 identity.M42 = num5 * lightDirection.Y;
807 identity.M13 = num2 * lightDirection.Z;
808 identity.M23 = num3 * lightDirection.Z;
809 identity.M33 = num4 * lightDirection.Z + num;
810 identity.M43 = num5 * lightDirection.Z;
811 identity.M44 = num;
812 return identity;
813 }
814
815 public static Matrix4x4 CreateTranslation(Vector3 position)
816 {
817 Matrix4x4 identity = Identity;
818 identity.M41 = position.X;
819 identity.M42 = position.Y;
820 identity.M43 = position.Z;
821 return identity;
822 }
823
824 public static Matrix4x4 CreateTranslation(float xPosition, float yPosition, float zPosition)
825 {
826 Matrix4x4 identity = Identity;
827 identity.M41 = xPosition;
828 identity.M42 = yPosition;
829 identity.M43 = zPosition;
830 return identity;
831 }
832
833 public static Matrix4x4 CreateWorld(Vector3 position, Vector3 forward, Vector3 up)
834 {
835 Vector3 vector = Vector3.Normalize(-forward);
836 Vector3 vector2 = Vector3.Normalize(Vector3.Cross(up, vector));
837 Vector3 vector3 = Vector3.Cross(vector, vector2);
838 Matrix4x4 identity = Identity;
839 identity.M11 = vector2.X;
840 identity.M12 = vector2.Y;
841 identity.M13 = vector2.Z;
842 identity.M21 = vector3.X;
843 identity.M22 = vector3.Y;
844 identity.M23 = vector3.Z;
845 identity.M31 = vector.X;
846 identity.M32 = vector.Y;
847 identity.M33 = vector.Z;
848 identity.M41 = position.X;
849 identity.M42 = position.Y;
850 identity.M43 = position.Z;
851 return identity;
852 }
853
854 [MethodImpl(MethodImplOptions.AggressiveInlining)]
855 public static bool Invert(Matrix4x4 matrix, out Matrix4x4 result)
856 {
857 if (Sse.IsSupported)
858 {
859 return SseImpl(matrix, out result);
860 }
861 return SoftwareFallback(matrix, out result);
862 static bool SoftwareFallback(Matrix4x4 matrix, out Matrix4x4 result)
863 {
864 float m = matrix.M11;
865 float m2 = matrix.M12;
866 float m3 = matrix.M13;
867 float m4 = matrix.M14;
868 float m5 = matrix.M21;
869 float m6 = matrix.M22;
870 float m7 = matrix.M23;
871 float m8 = matrix.M24;
872 float m9 = matrix.M31;
873 float m10 = matrix.M32;
874 float m11 = matrix.M33;
875 float m12 = matrix.M34;
876 float m13 = matrix.M41;
877 float m14 = matrix.M42;
878 float m15 = matrix.M43;
879 float m16 = matrix.M44;
880 float num = m11 * m16 - m12 * m15;
881 float num2 = m10 * m16 - m12 * m14;
882 float num3 = m10 * m15 - m11 * m14;
883 float num4 = m9 * m16 - m12 * m13;
884 float num5 = m9 * m15 - m11 * m13;
885 float num6 = m9 * m14 - m10 * m13;
886 float num7 = m6 * num - m7 * num2 + m8 * num3;
887 float num8 = 0f - (m5 * num - m7 * num4 + m8 * num5);
888 float num9 = m5 * num2 - m6 * num4 + m8 * num6;
889 float num10 = 0f - (m5 * num3 - m6 * num5 + m7 * num6);
890 float num11 = m * num7 + m2 * num8 + m3 * num9 + m4 * num10;
891 if (MathF.Abs(num11) < float.Epsilon)
892 {
893 result = new Matrix4x4(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN);
894 return false;
895 }
896 float num12 = 1f / num11;
897 result.M11 = num7 * num12;
898 result.M21 = num8 * num12;
899 result.M31 = num9 * num12;
900 result.M41 = num10 * num12;
901 result.M12 = (0f - (m2 * num - m3 * num2 + m4 * num3)) * num12;
902 result.M22 = (m * num - m3 * num4 + m4 * num5) * num12;
903 result.M32 = (0f - (m * num2 - m2 * num4 + m4 * num6)) * num12;
904 result.M42 = (m * num3 - m2 * num5 + m3 * num6) * num12;
905 float num13 = m7 * m16 - m8 * m15;
906 float num14 = m6 * m16 - m8 * m14;
907 float num15 = m6 * m15 - m7 * m14;
908 float num16 = m5 * m16 - m8 * m13;
909 float num17 = m5 * m15 - m7 * m13;
910 float num18 = m5 * m14 - m6 * m13;
911 result.M13 = (m2 * num13 - m3 * num14 + m4 * num15) * num12;
912 result.M23 = (0f - (m * num13 - m3 * num16 + m4 * num17)) * num12;
913 result.M33 = (m * num14 - m2 * num16 + m4 * num18) * num12;
914 result.M43 = (0f - (m * num15 - m2 * num17 + m3 * num18)) * num12;
915 float num19 = m7 * m12 - m8 * m11;
916 float num20 = m6 * m12 - m8 * m10;
917 float num21 = m6 * m11 - m7 * m10;
918 float num22 = m5 * m12 - m8 * m9;
919 float num23 = m5 * m11 - m7 * m9;
920 float num24 = m5 * m10 - m6 * m9;
921 result.M14 = (0f - (m2 * num19 - m3 * num20 + m4 * num21)) * num12;
922 result.M24 = (m * num19 - m3 * num22 + m4 * num23) * num12;
923 result.M34 = (0f - (m * num20 - m2 * num22 + m4 * num24)) * num12;
924 result.M44 = (m * num21 - m2 * num23 + m3 * num24) * num12;
925 return true;
926 }
927 unsafe static bool SseImpl(Matrix4x4 matrix, out Matrix4x4 result)
928 {
929 if (!Sse.IsSupported)
930 {
932 }
933 Vector128<float> left = Sse.LoadVector128(&matrix.M11);
934 Vector128<float> right = Sse.LoadVector128(&matrix.M21);
935 Vector128<float> left2 = Sse.LoadVector128(&matrix.M31);
936 Vector128<float> right2 = Sse.LoadVector128(&matrix.M41);
937 Vector128<float> left3 = Sse.Shuffle(left, right, 68);
938 Vector128<float> left4 = Sse.Shuffle(left, right, 238);
939 Vector128<float> right3 = Sse.Shuffle(left2, right2, 68);
940 Vector128<float> right4 = Sse.Shuffle(left2, right2, 238);
941 left = Sse.Shuffle(left3, right3, 136);
942 right = Sse.Shuffle(left3, right3, 221);
943 left2 = Sse.Shuffle(left4, right4, 136);
944 right2 = Sse.Shuffle(left4, right4, 221);
945 Vector128<float> left5 = Permute(left2, 80);
946 Vector128<float> right5 = Permute(right2, 238);
947 Vector128<float> left6 = Permute(left, 80);
948 Vector128<float> right6 = Permute(right, 238);
949 Vector128<float> left7 = Sse.Shuffle(left2, left, 136);
950 Vector128<float> right7 = Sse.Shuffle(right2, right, 221);
951 Vector128<float> left8 = Sse.Multiply(left5, right5);
952 Vector128<float> left9 = Sse.Multiply(left6, right6);
953 Vector128<float> left10 = Sse.Multiply(left7, right7);
954 left5 = Permute(left2, 238);
955 right5 = Permute(right2, 80);
956 left6 = Permute(left, 238);
957 right6 = Permute(right, 80);
958 left7 = Sse.Shuffle(left2, left, 221);
959 right7 = Sse.Shuffle(right2, right, 136);
960 left8 = Sse.Subtract(left8, Sse.Multiply(left5, right5));
961 left9 = Sse.Subtract(left9, Sse.Multiply(left6, right6));
962 left10 = Sse.Subtract(left10, Sse.Multiply(left7, right7));
963 right6 = Sse.Shuffle(left8, left10, 93);
964 left5 = Permute(right, 73);
965 right5 = Sse.Shuffle(right6, left8, 50);
966 left6 = Permute(left, 18);
967 right6 = Sse.Shuffle(right6, left8, 153);
968 Vector128<float> left11 = Sse.Shuffle(left9, left10, 253);
969 left7 = Permute(right2, 73);
970 right7 = Sse.Shuffle(left11, left9, 50);
971 Vector128<float> left12 = Permute(left2, 18);
972 left11 = Sse.Shuffle(left11, left9, 153);
973 Vector128<float> left13 = Sse.Multiply(left5, right5);
974 Vector128<float> left14 = Sse.Multiply(left6, right6);
975 Vector128<float> left15 = Sse.Multiply(left7, right7);
976 Vector128<float> left16 = Sse.Multiply(left12, left11);
977 right6 = Sse.Shuffle(left8, left10, 4);
978 left5 = Permute(right, 158);
979 right5 = Sse.Shuffle(left8, right6, 147);
980 left6 = Permute(left, 123);
981 right6 = Sse.Shuffle(left8, right6, 38);
982 left11 = Sse.Shuffle(left9, left10, 164);
983 left7 = Permute(right2, 158);
984 right7 = Sse.Shuffle(left9, left11, 147);
985 left12 = Permute(left2, 123);
986 left11 = Sse.Shuffle(left9, left11, 38);
987 left13 = Sse.Subtract(left13, Sse.Multiply(left5, right5));
988 left14 = Sse.Subtract(left14, Sse.Multiply(left6, right6));
989 left15 = Sse.Subtract(left15, Sse.Multiply(left7, right7));
990 left16 = Sse.Subtract(left16, Sse.Multiply(left12, left11));
991 left5 = Permute(right, 51);
992 right5 = Sse.Shuffle(left8, left10, 74);
993 right5 = Permute(right5, 44);
994 left6 = Permute(left, 141);
995 right6 = Sse.Shuffle(left8, left10, 76);
996 right6 = Permute(right6, 147);
997 left7 = Permute(right2, 51);
998 right7 = Sse.Shuffle(left9, left10, 234);
999 right7 = Permute(right7, 44);
1000 left12 = Permute(left2, 141);
1001 left11 = Sse.Shuffle(left9, left10, 236);
1002 left11 = Permute(left11, 147);
1003 left5 = Sse.Multiply(left5, right5);
1004 left6 = Sse.Multiply(left6, right6);
1005 left7 = Sse.Multiply(left7, right7);
1006 left12 = Sse.Multiply(left12, left11);
1007 Vector128<float> right8 = Sse.Subtract(left13, left5);
1008 left13 = Sse.Add(left13, left5);
1009 Vector128<float> right9 = Sse.Add(left14, left6);
1010 left14 = Sse.Subtract(left14, left6);
1011 Vector128<float> right10 = Sse.Subtract(left15, left7);
1012 left15 = Sse.Add(left15, left7);
1013 Vector128<float> right11 = Sse.Add(left16, left12);
1014 left16 = Sse.Subtract(left16, left12);
1015 left13 = Sse.Shuffle(left13, right8, 216);
1016 left14 = Sse.Shuffle(left14, right9, 216);
1017 left15 = Sse.Shuffle(left15, right10, 216);
1018 left16 = Sse.Shuffle(left16, right11, 216);
1019 left13 = Permute(left13, 216);
1020 left14 = Permute(left14, 216);
1021 left15 = Permute(left15, 216);
1022 left16 = Permute(left16, 216);
1023 right3 = left;
1024 float num25 = Vector4.Dot(left13.AsVector4(), right3.AsVector4());
1025 if (MathF.Abs(num25) < float.Epsilon)
1026 {
1027 result = new Matrix4x4(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN);
1028 return false;
1029 }
1030 Vector128<float> left17 = Vector128.Create(1f);
1031 Vector128<float> right12 = Vector128.Create(num25);
1032 right12 = Sse.Divide(left17, right12);
1033 left = Sse.Multiply(left13, right12);
1034 right = Sse.Multiply(left14, right12);
1035 left2 = Sse.Multiply(left15, right12);
1036 right2 = Sse.Multiply(left16, right12);
1037 Unsafe.SkipInit<Matrix4x4>(out result);
1038 ref Vector128<float> reference = ref Unsafe.As<Matrix4x4, Vector128<float>>(ref result);
1039 reference = left;
1040 Unsafe.Add(ref reference, 1) = right;
1041 Unsafe.Add(ref reference, 2) = left2;
1042 Unsafe.Add(ref reference, 3) = right2;
1043 return true;
1044 }
1045 }
1046
1047 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1048 public static Matrix4x4 Multiply(Matrix4x4 value1, Matrix4x4 value2)
1049 {
1050 return value1 * value2;
1051 }
1052
1053 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1054 public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
1055 {
1056 return value1 * value2;
1057 }
1058
1059 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1061 {
1062 return -value;
1063 }
1064
1065 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1066 public static Matrix4x4 Subtract(Matrix4x4 value1, Matrix4x4 value2)
1067 {
1068 return value1 - value2;
1069 }
1070
1071 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1072 private static Vector128<float> Permute(Vector128<float> value, byte control)
1073 {
1074 if (Avx.IsSupported)
1075 {
1076 return Avx.Permute(value, control);
1077 }
1078 if (Sse.IsSupported)
1079 {
1080 return Sse.Shuffle(value, value, control);
1081 }
1083 }
1084
1085 public unsafe static bool Decompose(Matrix4x4 matrix, out Vector3 scale, out Quaternion rotation, out Vector3 translation)
1086 {
1087 bool result = true;
1088 fixed (Vector3* ptr = &scale)
1089 {
1090 float* ptr2 = (float*)ptr;
1091 System.Runtime.CompilerServices.Unsafe.SkipInit(out VectorBasis vectorBasis);
1092 Vector3** ptr3 = (Vector3**)(&vectorBasis);
1093 Matrix4x4 identity = Identity;
1094 CanonicalBasis canonicalBasis = default(CanonicalBasis);
1095 Vector3* ptr4 = &canonicalBasis.Row0;
1096 canonicalBasis.Row0 = new Vector3(1f, 0f, 0f);
1097 canonicalBasis.Row1 = new Vector3(0f, 1f, 0f);
1098 canonicalBasis.Row2 = new Vector3(0f, 0f, 1f);
1099 translation = new Vector3(matrix.M41, matrix.M42, matrix.M43);
1100 *ptr3 = (Vector3*)(&identity.M11);
1101 ptr3[1] = (Vector3*)(&identity.M21);
1102 ptr3[2] = (Vector3*)(&identity.M31);
1103 *(*ptr3) = new Vector3(matrix.M11, matrix.M12, matrix.M13);
1104 *ptr3[1] = new Vector3(matrix.M21, matrix.M22, matrix.M23);
1105 *ptr3[2] = new Vector3(matrix.M31, matrix.M32, matrix.M33);
1106 scale.X = (*ptr3)->Length();
1107 scale.Y = ptr3[1]->Length();
1108 scale.Z = ptr3[2]->Length();
1109 float num = *ptr2;
1110 float num2 = ptr2[1];
1111 float num3 = ptr2[2];
1112 uint num4;
1113 uint num5;
1114 uint num6;
1115 if (num < num2)
1116 {
1117 if (num2 < num3)
1118 {
1119 num4 = 2u;
1120 num5 = 1u;
1121 num6 = 0u;
1122 }
1123 else
1124 {
1125 num4 = 1u;
1126 if (num < num3)
1127 {
1128 num5 = 2u;
1129 num6 = 0u;
1130 }
1131 else
1132 {
1133 num5 = 0u;
1134 num6 = 2u;
1135 }
1136 }
1137 }
1138 else if (num < num3)
1139 {
1140 num4 = 2u;
1141 num5 = 0u;
1142 num6 = 1u;
1143 }
1144 else
1145 {
1146 num4 = 0u;
1147 if (num2 < num3)
1148 {
1149 num5 = 2u;
1150 num6 = 1u;
1151 }
1152 else
1153 {
1154 num5 = 1u;
1155 num6 = 2u;
1156 }
1157 }
1158 if (ptr2[num4] < 0.0001f)
1159 {
1160 *ptr3[num4] = ptr4[num4];
1161 }
1162 *ptr3[num4] = Vector3.Normalize(*ptr3[num4]);
1163 if (ptr2[num5] < 0.0001f)
1164 {
1165 float num7 = MathF.Abs(ptr3[num4]->X);
1166 float num8 = MathF.Abs(ptr3[num4]->Y);
1167 float num9 = MathF.Abs(ptr3[num4]->Z);
1168 uint num10 = ((num7 < num8) ? ((!(num8 < num9)) ? ((!(num7 < num9)) ? 2u : 0u) : 0u) : ((num7 < num9) ? 1u : ((num8 < num9) ? 1u : 2u)));
1169 *ptr3[num5] = Vector3.Cross(*ptr3[num4], ptr4[num10]);
1170 }
1171 *ptr3[num5] = Vector3.Normalize(*ptr3[num5]);
1172 if (ptr2[num6] < 0.0001f)
1173 {
1174 *ptr3[num6] = Vector3.Cross(*ptr3[num4], *ptr3[num5]);
1175 }
1176 *ptr3[num6] = Vector3.Normalize(*ptr3[num6]);
1177 float num11 = identity.GetDeterminant();
1178 if (num11 < 0f)
1179 {
1180 ptr2[num4] = 0f - ptr2[num4];
1181 *ptr3[num4] = -(*ptr3[num4]);
1182 num11 = 0f - num11;
1183 }
1184 num11 -= 1f;
1185 num11 *= num11;
1186 if (0.0001f < num11)
1187 {
1188 rotation = Quaternion.Identity;
1189 result = false;
1190 }
1191 else
1192 {
1193 rotation = Quaternion.CreateFromRotationMatrix(identity);
1194 }
1195 }
1196 return result;
1197 }
1198
1199 public unsafe static Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount)
1200 {
1201 if (AdvSimd.IsSupported)
1202 {
1203 }
1204 if (Sse.IsSupported)
1205 {
1206 Vector128<float> t = Vector128.Create(amount);
1207 Sse.Store(&matrix1.M11, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M11), Sse.LoadVector128(&matrix2.M11), t));
1208 Sse.Store(&matrix1.M21, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M21), Sse.LoadVector128(&matrix2.M21), t));
1209 Sse.Store(&matrix1.M31, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M31), Sse.LoadVector128(&matrix2.M31), t));
1210 Sse.Store(&matrix1.M41, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M41), Sse.LoadVector128(&matrix2.M41), t));
1211 return matrix1;
1212 }
1213 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
1214 result.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount;
1215 result.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount;
1216 result.M13 = matrix1.M13 + (matrix2.M13 - matrix1.M13) * amount;
1217 result.M14 = matrix1.M14 + (matrix2.M14 - matrix1.M14) * amount;
1218 result.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount;
1219 result.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount;
1220 result.M23 = matrix1.M23 + (matrix2.M23 - matrix1.M23) * amount;
1221 result.M24 = matrix1.M24 + (matrix2.M24 - matrix1.M24) * amount;
1222 result.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount;
1223 result.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount;
1224 result.M33 = matrix1.M33 + (matrix2.M33 - matrix1.M33) * amount;
1225 result.M34 = matrix1.M34 + (matrix2.M34 - matrix1.M34) * amount;
1226 result.M41 = matrix1.M41 + (matrix2.M41 - matrix1.M41) * amount;
1227 result.M42 = matrix1.M42 + (matrix2.M42 - matrix1.M42) * amount;
1228 result.M43 = matrix1.M43 + (matrix2.M43 - matrix1.M43) * amount;
1229 result.M44 = matrix1.M44 + (matrix2.M44 - matrix1.M44) * amount;
1230 return result;
1231 }
1232
1234 {
1235 float num = rotation.X + rotation.X;
1236 float num2 = rotation.Y + rotation.Y;
1237 float num3 = rotation.Z + rotation.Z;
1238 float num4 = rotation.W * num;
1239 float num5 = rotation.W * num2;
1240 float num6 = rotation.W * num3;
1241 float num7 = rotation.X * num;
1242 float num8 = rotation.X * num2;
1243 float num9 = rotation.X * num3;
1244 float num10 = rotation.Y * num2;
1245 float num11 = rotation.Y * num3;
1246 float num12 = rotation.Z * num3;
1247 float num13 = 1f - num10 - num12;
1248 float num14 = num8 - num6;
1249 float num15 = num9 + num5;
1250 float num16 = num8 + num6;
1251 float num17 = 1f - num7 - num12;
1252 float num18 = num11 - num4;
1253 float num19 = num9 - num5;
1254 float num20 = num11 + num4;
1255 float num21 = 1f - num7 - num10;
1256 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
1257 result.M11 = value.M11 * num13 + value.M12 * num14 + value.M13 * num15;
1258 result.M12 = value.M11 * num16 + value.M12 * num17 + value.M13 * num18;
1259 result.M13 = value.M11 * num19 + value.M12 * num20 + value.M13 * num21;
1260 result.M14 = value.M14;
1261 result.M21 = value.M21 * num13 + value.M22 * num14 + value.M23 * num15;
1262 result.M22 = value.M21 * num16 + value.M22 * num17 + value.M23 * num18;
1263 result.M23 = value.M21 * num19 + value.M22 * num20 + value.M23 * num21;
1264 result.M24 = value.M24;
1265 result.M31 = value.M31 * num13 + value.M32 * num14 + value.M33 * num15;
1266 result.M32 = value.M31 * num16 + value.M32 * num17 + value.M33 * num18;
1267 result.M33 = value.M31 * num19 + value.M32 * num20 + value.M33 * num21;
1268 result.M34 = value.M34;
1269 result.M41 = value.M41 * num13 + value.M42 * num14 + value.M43 * num15;
1270 result.M42 = value.M41 * num16 + value.M42 * num17 + value.M43 * num18;
1271 result.M43 = value.M41 * num19 + value.M42 * num20 + value.M43 * num21;
1272 result.M44 = value.M44;
1273 return result;
1274 }
1275
1276 public unsafe static Matrix4x4 Transpose(Matrix4x4 matrix)
1277 {
1279 {
1280 }
1281 if (Sse.IsSupported)
1282 {
1283 Vector128<float> left = Sse.LoadVector128(&matrix.M11);
1284 Vector128<float> right = Sse.LoadVector128(&matrix.M21);
1285 Vector128<float> left2 = Sse.LoadVector128(&matrix.M31);
1286 Vector128<float> right2 = Sse.LoadVector128(&matrix.M41);
1287 Vector128<float> vector = Sse.UnpackLow(left, right);
1288 Vector128<float> vector2 = Sse.UnpackLow(left2, right2);
1289 Vector128<float> vector3 = Sse.UnpackHigh(left, right);
1290 Vector128<float> vector4 = Sse.UnpackHigh(left2, right2);
1291 Sse.Store(&matrix.M11, Sse.MoveLowToHigh(vector, vector2));
1292 Sse.Store(&matrix.M21, Sse.MoveHighToLow(vector2, vector));
1293 Sse.Store(&matrix.M31, Sse.MoveLowToHigh(vector3, vector4));
1294 Sse.Store(&matrix.M41, Sse.MoveHighToLow(vector4, vector3));
1295 return matrix;
1296 }
1297 System.Runtime.CompilerServices.Unsafe.SkipInit(out Matrix4x4 result);
1298 result.M11 = matrix.M11;
1299 result.M12 = matrix.M21;
1300 result.M13 = matrix.M31;
1301 result.M14 = matrix.M41;
1302 result.M21 = matrix.M12;
1303 result.M22 = matrix.M22;
1304 result.M23 = matrix.M32;
1305 result.M24 = matrix.M42;
1306 result.M31 = matrix.M13;
1307 result.M32 = matrix.M23;
1308 result.M33 = matrix.M33;
1309 result.M34 = matrix.M43;
1310 result.M41 = matrix.M14;
1311 result.M42 = matrix.M24;
1312 result.M43 = matrix.M34;
1313 result.M44 = matrix.M44;
1314 return result;
1315 }
1316
1317 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1318 public override readonly bool Equals([NotNullWhen(true)] object? obj)
1319 {
1320 if (obj is Matrix4x4 other)
1321 {
1322 return Equals(other);
1323 }
1324 return false;
1325 }
1326
1327 public readonly bool Equals(Matrix4x4 other)
1328 {
1329 return this == other;
1330 }
1331
1332 public readonly float GetDeterminant()
1333 {
1334 float m = M11;
1335 float m2 = M12;
1336 float m3 = M13;
1337 float m4 = M14;
1338 float m5 = M21;
1339 float m6 = M22;
1340 float m7 = M23;
1341 float m8 = M24;
1342 float m9 = M31;
1343 float m10 = M32;
1344 float m11 = M33;
1345 float m12 = M34;
1346 float m13 = M41;
1347 float m14 = M42;
1348 float m15 = M43;
1349 float m16 = M44;
1350 float num = m11 * m16 - m12 * m15;
1351 float num2 = m10 * m16 - m12 * m14;
1352 float num3 = m10 * m15 - m11 * m14;
1353 float num4 = m9 * m16 - m12 * m13;
1354 float num5 = m9 * m15 - m11 * m13;
1355 float num6 = m9 * m14 - m10 * m13;
1356 return m * (m6 * num - m7 * num2 + m8 * num3) - m2 * (m5 * num - m7 * num4 + m8 * num5) + m3 * (m5 * num2 - m6 * num4 + m8 * num6) - m4 * (m5 * num3 - m6 * num5 + m7 * num6);
1357 }
1358
1359 public override readonly int GetHashCode()
1360 {
1361 HashCode hashCode = default(HashCode);
1362 hashCode.Add(M11);
1363 hashCode.Add(M12);
1364 hashCode.Add(M13);
1365 hashCode.Add(M14);
1366 hashCode.Add(M21);
1367 hashCode.Add(M22);
1368 hashCode.Add(M23);
1369 hashCode.Add(M24);
1370 hashCode.Add(M31);
1371 hashCode.Add(M32);
1372 hashCode.Add(M33);
1373 hashCode.Add(M34);
1374 hashCode.Add(M41);
1375 hashCode.Add(M42);
1376 hashCode.Add(M43);
1377 hashCode.Add(M44);
1378 return hashCode.ToHashCode();
1379 }
1380
1381 public override readonly string ToString()
1382 {
1383 return $"{{ {{M11:{M11} M12:{M12} M13:{M13} M14:{M14}}} {{M21:{M21} M22:{M22} M23:{M23} M24:{M24}}} {{M31:{M31} M32:{M32} M33:{M33} M34:{M34}}} {{M41:{M41} M42:{M42} M43:{M43} M44:{M44}}} }}";
1384 }
1385}
static float Abs(float x)
Definition MathF.cs:130
static float Sqrt(float x)
static float Cos(float x)
static float Sin(float x)
static float Tan(float x)
const double PI
Definition Math.cs:16
static Vector128< float > Lerp(Vector128< float > a, Vector128< float > b, Vector128< float > t)
Definition VectorMath.cs:50
static bool Equal(Vector128< float > vector1, Vector128< float > vector2)
Definition VectorMath.cs:37
static bool NotEqual(Vector128< float > vector1, Vector128< float > vector2)
Definition VectorMath.cs:67
static Vector128< byte > Create(byte value)
Definition Vector128.cs:138
static Vector4 AsVector4(this Vector128< float > value)
Definition Vector128.cs:123
static new bool IsSupported
Definition Avx.cs:15
static Vector128< float > Permute(Vector128< float > value, byte control)
Definition Avx.cs:692
static Vector128< float > MoveHighToLow(Vector128< float > left, Vector128< float > right)
Definition Sse.cs:307
static unsafe void Store(float *address, Vector128< float > source)
Definition Sse.cs:417
static Vector128< float > UnpackHigh(Vector128< float > left, Vector128< float > right)
Definition Sse.cs:452
static new bool IsSupported
Definition Sse.cs:30
static unsafe Vector128< float > LoadVector128(float *address)
Definition Sse.cs:257
static Vector128< float > Shuffle(Vector128< float > left, Vector128< float > right, byte control)
Definition Sse.cs:387
static Vector128< float > Multiply(Vector128< float > left, Vector128< float > right)
Definition Sse.cs:322
static Vector128< float > UnpackLow(Vector128< float > left, Vector128< float > right)
Definition Sse.cs:457
static Vector128< float > Add(Vector128< float > left, Vector128< float > right)
Definition Sse.cs:32
static Vector128< float > Subtract(Vector128< float > left, Vector128< float > right)
Definition Sse.cs:442
static Vector128< float > Divide(Vector128< float > left, Vector128< float > right)
Definition Sse.cs:247
static Vector128< float > MoveLowToHigh(Vector128< float > left, Vector128< float > right)
Definition Sse.cs:312
void Add(int value)
Definition HashCode.cs:239
static Matrix4x4 Transform(Matrix4x4 value, Quaternion rotation)
static unsafe bool Decompose(Matrix4x4 matrix, out Vector3 scale, out Quaternion rotation, out Vector3 translation)
static Matrix4x4 Subtract(Matrix4x4 value1, Matrix4x4 value2)
static Matrix4x4 CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlaneDistance, float farPlaneDistance)
Definition Matrix4x4.cs:581
static Matrix4x4 CreateFromQuaternion(Quaternion quaternion)
Definition Matrix4x4.cs:448
static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount)
static Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector)
Definition Matrix4x4.cs:350
static Matrix4x4 Negate(Matrix4x4 value)
static Matrix4x4 CreateTranslation(float xPosition, float yPosition, float zPosition)
Definition Matrix4x4.cs:824
static bool Invert(Matrix4x4 matrix, out Matrix4x4 result)
Definition Matrix4x4.cs:855
static Matrix4x4 CreateRotationX(float radians, Vector3 centerPoint)
Definition Matrix4x4.cs:646
static Matrix4x4 CreateFromAxisAngle(Vector3 axis, float angle)
Definition Matrix4x4.cs:422
static Matrix4x4 CreateScale(float scale)
Definition Matrix4x4.cs:766
static Matrix4x4 CreateScale(float xScale, float yScale, float zScale)
Definition Matrix4x4.cs:718
static unsafe Matrix4x4 operator-(Matrix4x4 value1, Matrix4x4 value2)
Definition Matrix4x4.cs:277
override readonly bool Equals([NotNullWhen(true)] object? obj)
static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
static unsafe bool operator==(Matrix4x4 value1, Matrix4x4 value2)
Definition Matrix4x4.cs:166
static Matrix4x4 CreateScale(float xScale, float yScale, float zScale, Vector3 centerPoint)
Definition Matrix4x4.cs:727
static Matrix4x4 CreateReflection(Plane value)
Definition Matrix4x4.cs:609
static Matrix4x4 CreateRotationY(float radians)
Definition Matrix4x4.cs:662
static Matrix4x4 CreateScale(Vector3 scales)
Definition Matrix4x4.cs:742
static unsafe bool operator!=(Matrix4x4 value1, Matrix4x4 value2)
Definition Matrix4x4.cs:186
static Matrix4x4 CreateRotationZ(float radians, Vector3 centerPoint)
Definition Matrix4x4.cs:702
static Matrix4x4 CreateScale(float scale, Vector3 centerPoint)
Definition Matrix4x4.cs:775
readonly bool IsIdentity
Definition Matrix4x4.cs:68
static Matrix4x4 CreateShadow(Vector3 lightDirection, Plane plane)
Definition Matrix4x4.cs:790
static readonly Matrix4x4 _identity
Definition Matrix4x4.cs:31
static Matrix4x4 CreateRotationX(float radians)
Definition Matrix4x4.cs:634
Matrix4x4(Matrix3x2 value)
Definition Matrix4x4.cs:113
Matrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
Definition Matrix4x4.cs:93
override readonly string ToString()
static Matrix4x4 CreateRotationY(float radians, Vector3 centerPoint)
Definition Matrix4x4.cs:674
static unsafe Matrix4x4 operator*(Matrix4x4 value1, Matrix4x4 value2)
Definition Matrix4x4.cs:206
static Matrix4x4 Identity
Definition Matrix4x4.cs:65
override readonly int GetHashCode()
static Matrix4x4 CreateConstrainedBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 rotateAxis, Vector3 cameraForwardVector, Vector3 objectForwardVector)
Definition Matrix4x4.cs:377
static Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector)
Definition Matrix4x4.cs:478
static Matrix4x4 CreateWorld(Vector3 position, Vector3 forward, Vector3 up)
Definition Matrix4x4.cs:833
static Matrix4x4 CreateScale(Vector3 scales, Vector3 centerPoint)
Definition Matrix4x4.cs:751
static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance)
Definition Matrix4x4.cs:548
static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2)
Definition Matrix4x4.cs:345
static Matrix4x4 Multiply(Matrix4x4 value1, Matrix4x4 value2)
static Matrix4x4 CreatePerspective(float width, float height, float nearPlaneDistance, float farPlaneDistance)
Definition Matrix4x4.cs:521
static Matrix4x4 CreateFromYawPitchRoll(float yaw, float pitch, float roll)
Definition Matrix4x4.cs:472
static Matrix4x4 CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane)
Definition Matrix4x4.cs:499
static unsafe Matrix4x4 Transpose(Matrix4x4 matrix)
static Matrix4x4 CreateRotationZ(float radians)
Definition Matrix4x4.cs:690
readonly float GetDeterminant()
static Vector128< float > Permute(Vector128< float > value, byte control)
static Matrix4x4 CreateTranslation(Vector3 position)
Definition Matrix4x4.cs:815
readonly bool Equals(Matrix4x4 other)
static Matrix4x4 CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane)
Definition Matrix4x4.cs:509
static unsafe Matrix4x4 operator+(Matrix4x4 value1, Matrix4x4 value2)
Definition Matrix4x4.cs:133
static Plane Normalize(Plane value)
Definition Plane.cs:85
static Quaternion Identity
Definition Quaternion.cs:17
static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix)
static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
static Vector3 Cross(Vector3 vector1, Vector3 vector2)
Definition Vector3.cs:162
readonly float Length()
Definition Vector3.cs:368
readonly float LengthSquared()
Definition Vector3.cs:375
static float Dot(Vector3 vector1, Vector3 vector2)
Definition Vector3.cs:195
static Vector3 Multiply(Vector3 left, Vector3 right)
Definition Vector3.cs:220
static Vector3 Normalize(Vector3 value)
Definition Vector3.cs:244
static float Dot(Vector4 vector1, Vector4 vector2)
Definition Vector4.cs:200