Falco Engine 3.9.0.1 (beta)
Matrix4.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Globalization;
4using System.Linq;
5using System.Text;
6
7namespace FalcoEngine
8{
9 public struct Matrix4
10 {
11 public float m00;
12 public float m10;
13 public float m20;
14 public float m30;
15 public float m01;
16 public float m11;
17 public float m21;
18 public float m31;
19 public float m02;
20 public float m12;
21 public float m22;
22 public float m32;
23 public float m03;
24 public float m13;
25 public float m23;
26 public float m33;
27
31 private static readonly Matrix4 zeroMatrix = new Matrix4(new Vector4(0f, 0f, 0f, 0f), new Vector4(0f, 0f, 0f, 0f), new Vector4(0f, 0f, 0f, 0f), new Vector4(0f, 0f, 0f, 0f));
32
36 private static readonly Matrix4 identityMatrix = new Matrix4(new Vector4(1f, 0f, 0f, 0f), new Vector4(0f, 1f, 0f, 0f), new Vector4(0f, 0f, 1f, 0f), new Vector4(0f, 0f, 0f, 1f));
37
38 public Matrix4(Vector4 column0, Vector4 column1, Vector4 column2, Vector4 column3)
39 {
40 m00 = column0.x;
41 m01 = column1.x;
42 m02 = column2.x;
43 m03 = column3.x;
44 m10 = column0.y;
45 m11 = column1.y;
46 m12 = column2.y;
47 m13 = column3.y;
48 m20 = column0.z;
49 m21 = column1.z;
50 m22 = column2.z;
51 m23 = column3.z;
52 m30 = column0.w;
53 m31 = column1.w;
54 m32 = column2.w;
55 m33 = column3.w;
56 }
57
58 public Matrix4(float d00, float d01, float d02, float d03,
59 float d10, float d11, float d12, float d13,
60 float d20, float d21, float d22, float d23,
61 float d30, float d31, float d32, float d33)
62 {
63 m00 = d00;
64 m01 = d01;
65 m02 = d02;
66 m03 = d03;
67 m10 = d10;
68 m11 = d11;
69 m12 = d12;
70 m13 = d13;
71 m20 = d20;
72 m21 = d21;
73 m22 = d22;
74 m23 = d23;
75 m30 = d30;
76 m31 = d31;
77 m32 = d32;
78 m33 = d33;
79 }
80
81 public float this[int row, int column]
82 {
83 get
84 {
85 return this[row + column * 4];
86 }
87 set
88 {
89 this[row + column * 4] = value;
90 }
91 }
92
93 public float this[int index]
94 {
95 get
96 {
97 switch (index)
98 {
99 case 0:
100 return m00;
101 case 1:
102 return m10;
103 case 2:
104 return m20;
105 case 3:
106 return m30;
107 case 4:
108 return m01;
109 case 5:
110 return m11;
111 case 6:
112 return m21;
113 case 7:
114 return m31;
115 case 8:
116 return m02;
117 case 9:
118 return m12;
119 case 10:
120 return m22;
121 case 11:
122 return m32;
123 case 12:
124 return m03;
125 case 13:
126 return m13;
127 case 14:
128 return m23;
129 case 15:
130 return m33;
131 default:
132 throw new IndexOutOfRangeException("Invalid matrix index!");
133 }
134 }
135 set
136 {
137 switch (index)
138 {
139 case 0:
140 m00 = value;
141 break;
142 case 1:
143 m10 = value;
144 break;
145 case 2:
146 m20 = value;
147 break;
148 case 3:
149 m30 = value;
150 break;
151 case 4:
152 m01 = value;
153 break;
154 case 5:
155 m11 = value;
156 break;
157 case 6:
158 m21 = value;
159 break;
160 case 7:
161 m31 = value;
162 break;
163 case 8:
164 m02 = value;
165 break;
166 case 9:
167 m12 = value;
168 break;
169 case 10:
170 m22 = value;
171 break;
172 case 11:
173 m32 = value;
174 break;
175 case 12:
176 m03 = value;
177 break;
178 case 13:
179 m13 = value;
180 break;
181 case 14:
182 m23 = value;
183 break;
184 case 15:
185 m33 = value;
186 break;
187 default:
188 throw new IndexOutOfRangeException("Invalid matrix index!");
189 }
190 }
191 }
192
193 public override bool Equals(object other)
194 {
195 if (!(other is Matrix4))
196 {
197 return false;
198 }
199 return Equals((Matrix4)other);
200 }
201
202 public bool Equals(Matrix4 other)
203 {
204 return GetColumn(0).Equals(other.GetColumn(0)) && GetColumn(1).Equals(other.GetColumn(1)) && GetColumn(2).Equals(other.GetColumn(2)) && GetColumn(3).Equals(other.GetColumn(3));
205 }
206
207 public static Matrix4 operator *(Matrix4 lhs, Matrix4 rhs)
208 {
209 Matrix4 result = default(Matrix4);
210 result.m00 = lhs.m00 * rhs.m00 + lhs.m01 * rhs.m10 + lhs.m02 * rhs.m20 + lhs.m03 * rhs.m30;
211 result.m01 = lhs.m00 * rhs.m01 + lhs.m01 * rhs.m11 + lhs.m02 * rhs.m21 + lhs.m03 * rhs.m31;
212 result.m02 = lhs.m00 * rhs.m02 + lhs.m01 * rhs.m12 + lhs.m02 * rhs.m22 + lhs.m03 * rhs.m32;
213 result.m03 = lhs.m00 * rhs.m03 + lhs.m01 * rhs.m13 + lhs.m02 * rhs.m23 + lhs.m03 * rhs.m33;
214 result.m10 = lhs.m10 * rhs.m00 + lhs.m11 * rhs.m10 + lhs.m12 * rhs.m20 + lhs.m13 * rhs.m30;
215 result.m11 = lhs.m10 * rhs.m01 + lhs.m11 * rhs.m11 + lhs.m12 * rhs.m21 + lhs.m13 * rhs.m31;
216 result.m12 = lhs.m10 * rhs.m02 + lhs.m11 * rhs.m12 + lhs.m12 * rhs.m22 + lhs.m13 * rhs.m32;
217 result.m13 = lhs.m10 * rhs.m03 + lhs.m11 * rhs.m13 + lhs.m12 * rhs.m23 + lhs.m13 * rhs.m33;
218 result.m20 = lhs.m20 * rhs.m00 + lhs.m21 * rhs.m10 + lhs.m22 * rhs.m20 + lhs.m23 * rhs.m30;
219 result.m21 = lhs.m20 * rhs.m01 + lhs.m21 * rhs.m11 + lhs.m22 * rhs.m21 + lhs.m23 * rhs.m31;
220 result.m22 = lhs.m20 * rhs.m02 + lhs.m21 * rhs.m12 + lhs.m22 * rhs.m22 + lhs.m23 * rhs.m32;
221 result.m23 = lhs.m20 * rhs.m03 + lhs.m21 * rhs.m13 + lhs.m22 * rhs.m23 + lhs.m23 * rhs.m33;
222 result.m30 = lhs.m30 * rhs.m00 + lhs.m31 * rhs.m10 + lhs.m32 * rhs.m20 + lhs.m33 * rhs.m30;
223 result.m31 = lhs.m30 * rhs.m01 + lhs.m31 * rhs.m11 + lhs.m32 * rhs.m21 + lhs.m33 * rhs.m31;
224 result.m32 = lhs.m30 * rhs.m02 + lhs.m31 * rhs.m12 + lhs.m32 * rhs.m22 + lhs.m33 * rhs.m32;
225 result.m33 = lhs.m30 * rhs.m03 + lhs.m31 * rhs.m13 + lhs.m32 * rhs.m23 + lhs.m33 * rhs.m33;
226 return result;
227 }
228
229 public static Vector4 operator *(Matrix4 lhs, Vector4 vector)
230 {
231 Vector4 result = default(Vector4);
232 result.x = lhs.m00 * vector.x + lhs.m01 * vector.y + lhs.m02 * vector.z + lhs.m03 * vector.w;
233 result.y = lhs.m10 * vector.x + lhs.m11 * vector.y + lhs.m12 * vector.z + lhs.m13 * vector.w;
234 result.z = lhs.m20 * vector.x + lhs.m21 * vector.y + lhs.m22 * vector.z + lhs.m23 * vector.w;
235 result.w = lhs.m30 * vector.x + lhs.m31 * vector.y + lhs.m32 * vector.z + lhs.m33 * vector.w;
236 return result;
237 }
238
239 public static bool operator ==(Matrix4 lhs, Matrix4 rhs)
240 {
241 return lhs.GetColumn(0) == rhs.GetColumn(0) && lhs.GetColumn(1) == rhs.GetColumn(1) && lhs.GetColumn(2) == rhs.GetColumn(2) && lhs.GetColumn(3) == rhs.GetColumn(3);
242 }
243
244 public static bool operator !=(Matrix4 lhs, Matrix4 rhs)
245 {
246 return !(lhs == rhs);
247 }
248
252 public Matrix4 inverse => Inverse(this);
253
257 //public Matrix4 transpose => Transpose(this);
258
259 public static Matrix4 Inverse(Matrix4 m)
260 {
261 float m00 = m.m00, m01 = m.m01, m02 = m.m02, m03 = m.m03;
262 float m10 = m.m10, m11 = m.m11, m12 = m.m12, m13 = m.m13;
263 float m20 = m.m20, m21 = m.m21, m22 = m.m22, m23 = m.m23;
264 float m30 = m.m30, m31 = m.m31, m32 = m.m32, m33 = m.m33;
265
266 float v0 = m20 * m31 - m21 * m30;
267 float v1 = m20 * m32 - m22 * m30;
268 float v2 = m20 * m33 - m23 * m30;
269 float v3 = m21 * m32 - m22 * m31;
270 float v4 = m21 * m33 - m23 * m31;
271 float v5 = m22 * m33 - m23 * m32;
272
273 float t00 = +(v5 * m11 - v4 * m12 + v3 * m13);
274 float t10 = -(v5 * m10 - v2 * m12 + v1 * m13);
275 float t20 = +(v4 * m10 - v2 * m11 + v0 * m13);
276 float t30 = -(v3 * m10 - v1 * m11 + v0 * m12);
277
278 float invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);
279
280 float d00 = t00 * invDet;
281 float d10 = t10 * invDet;
282 float d20 = t20 * invDet;
283 float d30 = t30 * invDet;
284
285 float d01 = -(v5 * m01 - v4 * m02 + v3 * m03) * invDet;
286 float d11 = +(v5 * m00 - v2 * m02 + v1 * m03) * invDet;
287 float d21 = -(v4 * m00 - v2 * m01 + v0 * m03) * invDet;
288 float d31 = +(v3 * m00 - v1 * m01 + v0 * m02) * invDet;
289
290 v0 = m10 * m31 - m11 * m30;
291 v1 = m10 * m32 - m12 * m30;
292 v2 = m10 * m33 - m13 * m30;
293 v3 = m11 * m32 - m12 * m31;
294 v4 = m11 * m33 - m13 * m31;
295 v5 = m12 * m33 - m13 * m32;
296
297 float d02 = +(v5 * m01 - v4 * m02 + v3 * m03) * invDet;
298 float d12 = -(v5 * m00 - v2 * m02 + v1 * m03) * invDet;
299 float d22 = +(v4 * m00 - v2 * m01 + v0 * m03) * invDet;
300 float d32 = -(v3 * m00 - v1 * m01 + v0 * m02) * invDet;
301
302 v0 = m21 * m10 - m20 * m11;
303 v1 = m22 * m10 - m20 * m12;
304 v2 = m23 * m10 - m20 * m13;
305 v3 = m22 * m11 - m21 * m12;
306 v4 = m23 * m11 - m21 * m13;
307 v5 = m23 * m12 - m22 * m13;
308
309 float d03 = -(v5 * m01 - v4 * m02 + v3 * m03) * invDet;
310 float d13 = +(v5 * m00 - v2 * m02 + v1 * m03) * invDet;
311 float d23 = -(v4 * m00 - v2 * m01 + v0 * m03) * invDet;
312 float d33 = +(v3 * m00 - v1 * m01 + v0 * m02) * invDet;
313
314 return new Matrix4(
315 d00, d01, d02, d03,
316 d10, d11, d12, d13,
317 d20, d21, d22, d23,
318 d30, d31, d32, d33);
319 }
320
321 //public static Matrix4 Transpose(Matrix4 m)
322 //{
323
324 //}
325
330 public Vector4 GetColumn(int index)
331 {
332 switch (index)
333 {
334 case 0:
335 return new Vector4(m00, m10, m20, m30);
336 case 1:
337 return new Vector4(m01, m11, m21, m31);
338 case 2:
339 return new Vector4(m02, m12, m22, m32);
340 case 3:
341 return new Vector4(m03, m13, m23, m33);
342 default:
343 throw new IndexOutOfRangeException("Invalid column index!");
344 }
345 }
346
351 public Vector4 GetRow(int index)
352 {
353 switch (index)
354 {
355 case 0:
356 return new Vector4(m00, m01, m02, m03);
357 case 1:
358 return new Vector4(m10, m11, m12, m13);
359 case 2:
360 return new Vector4(m20, m21, m22, m23);
361 case 3:
362 return new Vector4(m30, m31, m32, m33);
363 default:
364 throw new IndexOutOfRangeException("Invalid row index!");
365 }
366 }
367
373 public void SetColumn(int index, Vector4 column)
374 {
375 this[0, index] = column.x;
376 this[1, index] = column.y;
377 this[2, index] = column.z;
378 this[3, index] = column.w;
379 }
380
386 public void SetRow(int index, Vector4 row)
387 {
388 this[index, 0] = row.x;
389 this[index, 1] = row.y;
390 this[index, 2] = row.z;
391 this[index, 3] = row.w;
392 }
393
399 {
400 Vector3 result = default(Vector3);
401 result.x = m00 * point.x + m01 * point.y + m02 * point.z + m03;
402 result.y = m10 * point.x + m11 * point.y + m12 * point.z + m13;
403 result.z = m20 * point.x + m21 * point.y + m22 * point.z + m23;
404 float num = m30 * point.x + m31 * point.y + m32 * point.z + m33;
405 num = 1f / num;
406 result.x *= num;
407 result.y *= num;
408 result.z *= num;
409 return result;
410 }
411
417 {
418 Vector3 result = default(Vector3);
419 result.x = m00 * point.x + m01 * point.y + m02 * point.z + m03;
420 result.y = m10 * point.x + m11 * point.y + m12 * point.z + m13;
421 result.z = m20 * point.x + m21 * point.y + m22 * point.z + m23;
422 return result;
423 }
424
430 {
431 Vector3 result = default(Vector3);
432 result.x = m00 * vector.x + m01 * vector.y + m02 * vector.z;
433 result.y = m10 * vector.x + m11 * vector.y + m12 * vector.z;
434 result.z = m20 * vector.x + m21 * vector.y + m22 * vector.z;
435 return result;
436 }
437
443 {
444 Matrix4 inverse = this.inverse;
445 Vector3 normal = plane.normal;
446 float x = normal.x;
447 Vector3 normal2 = plane.normal;
448 float y = normal2.y;
449 Vector3 normal3 = plane.normal;
450 float z = normal3.z;
451 float distance = plane.distance;
452 float x2 = inverse.m00 * x + inverse.m10 * y + inverse.m20 * z + inverse.m30 * distance;
453 float y2 = inverse.m01 * x + inverse.m11 * y + inverse.m21 * z + inverse.m31 * distance;
454 float z2 = inverse.m02 * x + inverse.m12 * y + inverse.m22 * z + inverse.m32 * distance;
455 float d = inverse.m03 * x + inverse.m13 * y + inverse.m23 * z + inverse.m33 * distance;
456 return new Plane(new Vector3(x2, y2, z2), d);
457 }
458
463 public static Matrix4 Scale(Vector3 vector)
464 {
465 Matrix4 result = default(Matrix4);
466 result.m00 = vector.x;
467 result.m01 = 0f;
468 result.m02 = 0f;
469 result.m03 = 0f;
470 result.m10 = 0f;
471 result.m11 = vector.y;
472 result.m12 = 0f;
473 result.m13 = 0f;
474 result.m20 = 0f;
475 result.m21 = 0f;
476 result.m22 = vector.z;
477 result.m23 = 0f;
478 result.m30 = 0f;
479 result.m31 = 0f;
480 result.m32 = 0f;
481 result.m33 = 1f;
482 return result;
483 }
484
489 public static Matrix4 Translate(Vector3 vector)
490 {
491 Matrix4 result = default(Matrix4);
492 result.m00 = 1f;
493 result.m01 = 0f;
494 result.m02 = 0f;
495 result.m03 = vector.x;
496 result.m10 = 0f;
497 result.m11 = 1f;
498 result.m12 = 0f;
499 result.m13 = vector.y;
500 result.m20 = 0f;
501 result.m21 = 0f;
502 result.m22 = 1f;
503 result.m23 = vector.z;
504 result.m30 = 0f;
505 result.m31 = 0f;
506 result.m32 = 0f;
507 result.m33 = 1f;
508 return result;
509 }
510
515 public static Matrix4 Rotate(Quaternion q)
516 {
517 float num = q.x * 2f;
518 float num2 = q.y * 2f;
519 float num3 = q.z * 2f;
520 float num4 = q.x * num;
521 float num5 = q.y * num2;
522 float num6 = q.z * num3;
523 float num7 = q.x * num2;
524 float num8 = q.x * num3;
525 float num9 = q.y * num3;
526 float num10 = q.w * num;
527 float num11 = q.w * num2;
528 float num12 = q.w * num3;
529 Matrix4 result = default(Matrix4);
530 result.m00 = 1f - (num5 + num6);
531 result.m10 = num7 + num12;
532 result.m20 = num8 - num11;
533 result.m30 = 0f;
534 result.m01 = num7 - num12;
535 result.m11 = 1f - (num4 + num6);
536 result.m21 = num9 + num10;
537 result.m31 = 0f;
538 result.m02 = num8 + num11;
539 result.m12 = num9 - num10;
540 result.m22 = 1f - (num4 + num5);
541 result.m32 = 0f;
542 result.m03 = 0f;
543 result.m13 = 0f;
544 result.m23 = 0f;
545 result.m33 = 1f;
546 return result;
547 }
548
553 public override string ToString()
554 {
555 return String.Format("{0:F5}\t{1:F5}\t{2:F5}\t{3:F5}\n{4:F5}\t{5:F5}\t{6:F5}\t{7:F5}\n{8:F5}\t{9:F5}\t{10:F5}\t{11:F5}\n{12:F5}\t{13:F5}\t{14:F5}\t{15:F5}\n", m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);
556 }
557
562 public string ToString(string format)
563 {
564 return String.Format("{0}\t{1}\t{2}\t{3}\n{4}\t{5}\t{6}\t{7}\n{8}\t{9}\t{10}\t{11}\n{12}\t{13}\t{14}\t{15}\n", ToInvariantString(format, m00), ToInvariantString(format, m01), ToInvariantString(format, m02), ToInvariantString(format, m03), ToInvariantString(format, m10), ToInvariantString(format, m11), ToInvariantString(format, m12), ToInvariantString(format, m13), ToInvariantString(format, m20), ToInvariantString(format, m21), ToInvariantString(format, m22), ToInvariantString(format, m23), ToInvariantString(format, m30), ToInvariantString(format, m31), ToInvariantString(format, m32), ToInvariantString(format, m33));
565 }
566
567 private string ToInvariantString(string format, float val)
568 {
569 return val.ToString(format, CultureInfo.InvariantCulture.NumberFormat);
570 }
571
572 public override int GetHashCode()
573 {
574 return base.GetHashCode();
575 }
576 }
577}
static Matrix4 Translate(Vector3 vector)
Definition: Matrix4.cs:489
Matrix4(Vector4 column0, Vector4 column1, Vector4 column2, Vector4 column3)
Definition: Matrix4.cs:38
static bool operator==(Matrix4 lhs, Matrix4 rhs)
Definition: Matrix4.cs:239
override string ToString()
Definition: Matrix4.cs:553
static Matrix4 Rotate(Quaternion q)
Definition: Matrix4.cs:515
static Matrix4 operator*(Matrix4 lhs, Matrix4 rhs)
Definition: Matrix4.cs:207
Vector3 MultiplyPoint3x4(Vector3 point)
Definition: Matrix4.cs:416
Plane TransformPlane(Plane plane)
Definition: Matrix4.cs:442
Vector4 GetRow(int index)
Definition: Matrix4.cs:351
bool Equals(Matrix4 other)
Definition: Matrix4.cs:202
override int GetHashCode()
Definition: Matrix4.cs:572
static bool operator!=(Matrix4 lhs, Matrix4 rhs)
Definition: Matrix4.cs:244
void SetColumn(int index, Vector4 column)
Definition: Matrix4.cs:373
Vector4 GetColumn(int index)
Definition: Matrix4.cs:330
Vector3 MultiplyVector(Vector3 vector)
Definition: Matrix4.cs:429
void SetRow(int index, Vector4 row)
Definition: Matrix4.cs:386
Vector3 MultiplyPoint(Vector3 point)
Definition: Matrix4.cs:398
Matrix4(float d00, float d01, float d02, float d03, float d10, float d11, float d12, float d13, float d20, float d21, float d22, float d23, float d30, float d31, float d32, float d33)
Definition: Matrix4.cs:58
string ToString(string format)
Definition: Matrix4.cs:562
static Matrix4 Inverse(Matrix4 m)
Definition: Matrix4.cs:259
static Matrix4 Scale(Vector3 vector)
Definition: Matrix4.cs:463
override bool Equals(object other)
Definition: Matrix4.cs:193
float distance
Definition: Plane.cs:35
Vector3 normal
Definition: Plane.cs:20
override bool Equals(object other)
Definition: Vector4.cs:229