1 | using System;
|
---|
2 |
|
---|
3 | namespace Oni
|
---|
4 | {
|
---|
5 | internal struct Matrix : IEquatable<Matrix>
|
---|
6 | {
|
---|
7 | public float M11, M12, M13, M14;
|
---|
8 | public float M21, M22, M23, M24;
|
---|
9 | public float M31, M32, M33, M34;
|
---|
10 | public float M41, M42, M43, M44;
|
---|
11 |
|
---|
12 | public Matrix(float m11, float m12, float m13, float m14,
|
---|
13 | float m21, float m22, float m23, float m24,
|
---|
14 | float m31, float m32, float m33, float m34,
|
---|
15 | float m41, float m42, float m43, float m44)
|
---|
16 | {
|
---|
17 | M11 = m11; M12 = m12; M13 = m13; M14 = m14;
|
---|
18 | M21 = m21; M22 = m22; M23 = m23; M24 = m24;
|
---|
19 | M31 = m31; M32 = m32; M33 = m33; M34 = m34;
|
---|
20 | M41 = m41; M42 = m42; M43 = m43; M44 = m44;
|
---|
21 | }
|
---|
22 |
|
---|
23 | public Matrix(float[] values)
|
---|
24 | {
|
---|
25 | M11 = values[0]; M12 = values[4]; M13 = values[8]; M14 = values[12];
|
---|
26 | M21 = values[1]; M22 = values[5]; M23 = values[9]; M24 = values[13];
|
---|
27 | M31 = values[2]; M32 = values[6]; M33 = values[10]; M34 = values[14];
|
---|
28 | M41 = values[3]; M42 = values[7]; M43 = values[11]; M44 = values[15];
|
---|
29 | }
|
---|
30 |
|
---|
31 | public void CopyTo(float[] values)
|
---|
32 | {
|
---|
33 | values[0] = M11;
|
---|
34 | values[1] = M21;
|
---|
35 | values[2] = M31;
|
---|
36 | values[3] = M41;
|
---|
37 |
|
---|
38 | values[4] = M12;
|
---|
39 | values[5] = M22;
|
---|
40 | values[6] = M32;
|
---|
41 | values[7] = M42;
|
---|
42 |
|
---|
43 | values[8] = M13;
|
---|
44 | values[9] = M23;
|
---|
45 | values[10] = M33;
|
---|
46 | values[11] = M43;
|
---|
47 |
|
---|
48 | values[12] = M14;
|
---|
49 | values[13] = M24;
|
---|
50 | values[14] = M34;
|
---|
51 | values[15] = M44;
|
---|
52 | }
|
---|
53 |
|
---|
54 | public static Matrix CreateTranslation(float x, float y, float z)
|
---|
55 | {
|
---|
56 | Matrix r = Identity;
|
---|
57 |
|
---|
58 | r.M41 = x;
|
---|
59 | r.M42 = y;
|
---|
60 | r.M43 = z;
|
---|
61 |
|
---|
62 | return r;
|
---|
63 | }
|
---|
64 |
|
---|
65 | public static Matrix CreateTranslation(Vector3 v) => CreateTranslation(v.X, v.Y, v.Z);
|
---|
66 |
|
---|
67 | public static Matrix CreateScale(float sx, float sy, float sz)
|
---|
68 | {
|
---|
69 | Matrix r = Identity;
|
---|
70 |
|
---|
71 | r.M11 = sx;
|
---|
72 | r.M22 = sy;
|
---|
73 | r.M33 = sz;
|
---|
74 |
|
---|
75 | return r;
|
---|
76 | }
|
---|
77 |
|
---|
78 | public static Matrix CreateScale(float s) => CreateScale(s, s, s);
|
---|
79 | public static Matrix CreateScale(Vector3 s) => CreateScale(s.X, s.Y, s.Z);
|
---|
80 |
|
---|
81 | public static Matrix CreateRotationX(float angle)
|
---|
82 | {
|
---|
83 | float cos = FMath.Cos(angle);
|
---|
84 | float sin = FMath.Sin(angle);
|
---|
85 |
|
---|
86 | Matrix r = Identity;
|
---|
87 | r.M22 = cos;
|
---|
88 | r.M23 = sin;
|
---|
89 | r.M32 = -sin;
|
---|
90 | r.M33 = cos;
|
---|
91 | return r;
|
---|
92 | }
|
---|
93 |
|
---|
94 | public static Matrix CreateRotationY(float angle)
|
---|
95 | {
|
---|
96 | float cos = FMath.Cos(angle);
|
---|
97 | float sin = FMath.Sin(angle);
|
---|
98 |
|
---|
99 | Matrix r = Identity;
|
---|
100 | r.M11 = cos;
|
---|
101 | r.M13 = -sin;
|
---|
102 | r.M31 = sin;
|
---|
103 | r.M33 = cos;
|
---|
104 | return r;
|
---|
105 | }
|
---|
106 |
|
---|
107 | public static Matrix CreateRotationZ(float angle)
|
---|
108 | {
|
---|
109 | float cos = FMath.Cos(angle);
|
---|
110 | float sin = FMath.Sin(angle);
|
---|
111 |
|
---|
112 | Matrix r = Identity;
|
---|
113 | r.M11 = cos;
|
---|
114 | r.M12 = sin;
|
---|
115 | r.M21 = -sin;
|
---|
116 | r.M22 = cos;
|
---|
117 | return r;
|
---|
118 | }
|
---|
119 |
|
---|
120 | public static Matrix CreateFromAxisAngle(Vector3 axis, float angle)
|
---|
121 | {
|
---|
122 | float sin = FMath.Sin(angle);
|
---|
123 | float cos = FMath.Cos(angle);
|
---|
124 |
|
---|
125 | float x = axis.X;
|
---|
126 | float y = axis.Y;
|
---|
127 | float z = axis.Z;
|
---|
128 | float xx = x * x;
|
---|
129 | float yy = y * y;
|
---|
130 | float zz = z * z;
|
---|
131 | float xy = x * y;
|
---|
132 | float xz = x * z;
|
---|
133 | float yz = y * z;
|
---|
134 |
|
---|
135 | Matrix r = Identity;
|
---|
136 | r.M11 = xx + (cos * (1.0f - xx));
|
---|
137 | r.M12 = (xy - (cos * xy)) + (sin * z);
|
---|
138 | r.M13 = (xz - (cos * xz)) - (sin * y);
|
---|
139 | r.M21 = (xy - (cos * xy)) - (sin * z);
|
---|
140 | r.M22 = yy + (cos * (1.0f - yy));
|
---|
141 | r.M23 = (yz - (cos * yz)) + (sin * x);
|
---|
142 | r.M31 = (xz - (cos * xz)) + (sin * y);
|
---|
143 | r.M32 = (yz - (cos * yz)) - (sin * x);
|
---|
144 | r.M33 = zz + (cos * (1.0f - zz));
|
---|
145 | return r;
|
---|
146 | }
|
---|
147 |
|
---|
148 | public static Matrix CreateFromQuaternion(Quaternion q)
|
---|
149 | {
|
---|
150 | float xx = q.X * q.X;
|
---|
151 | float yy = q.Y * q.Y;
|
---|
152 | float zz = q.Z * q.Z;
|
---|
153 | float xy = q.X * q.Y;
|
---|
154 | float zw = q.Z * q.W;
|
---|
155 | float zx = q.Z * q.X;
|
---|
156 | float yw = q.Y * q.W;
|
---|
157 | float yz = q.Y * q.Z;
|
---|
158 | float xw = q.X * q.W;
|
---|
159 |
|
---|
160 | Matrix r = Identity;
|
---|
161 |
|
---|
162 | r.M11 = 1.0f - 2.0f * (yy + zz);
|
---|
163 | r.M12 = 2.0f * (xy + zw);
|
---|
164 | r.M13 = 2.0f * (zx - yw);
|
---|
165 |
|
---|
166 | r.M21 = 2.0f * (xy - zw);
|
---|
167 | r.M22 = 1.0f - 2.0f * (zz + xx);
|
---|
168 | r.M23 = 2.0f * (yz + xw);
|
---|
169 |
|
---|
170 | r.M31 = 2.0f * (zx + yw);
|
---|
171 | r.M32 = 2.0f * (yz - xw);
|
---|
172 | r.M33 = 1.0f - 2.0f * (yy + xx);
|
---|
173 |
|
---|
174 | return r;
|
---|
175 | }
|
---|
176 |
|
---|
177 | public static Matrix operator +(Matrix m1, Matrix m2)
|
---|
178 | {
|
---|
179 | m1.M11 += m2.M11;
|
---|
180 | m1.M12 += m2.M12;
|
---|
181 | m1.M13 += m2.M13;
|
---|
182 | m1.M14 += m2.M14;
|
---|
183 | m1.M21 += m2.M21;
|
---|
184 | m1.M22 += m2.M22;
|
---|
185 | m1.M23 += m2.M23;
|
---|
186 | m1.M24 += m2.M24;
|
---|
187 | m1.M31 += m2.M31;
|
---|
188 | m1.M32 += m2.M32;
|
---|
189 | m1.M33 += m2.M33;
|
---|
190 | m1.M34 += m2.M34;
|
---|
191 | m1.M41 += m2.M41;
|
---|
192 | m1.M42 += m2.M42;
|
---|
193 | m1.M43 += m2.M43;
|
---|
194 | m1.M44 += m2.M44;
|
---|
195 |
|
---|
196 | return m1;
|
---|
197 | }
|
---|
198 |
|
---|
199 | public static Matrix operator -(Matrix m1, Matrix m2)
|
---|
200 | {
|
---|
201 | m1.M11 -= m2.M11;
|
---|
202 | m1.M12 -= m2.M12;
|
---|
203 | m1.M13 -= m2.M13;
|
---|
204 | m1.M14 -= m2.M14;
|
---|
205 | m1.M21 -= m2.M21;
|
---|
206 | m1.M22 -= m2.M22;
|
---|
207 | m1.M23 -= m2.M23;
|
---|
208 | m1.M24 -= m2.M24;
|
---|
209 | m1.M31 -= m2.M31;
|
---|
210 | m1.M32 -= m2.M32;
|
---|
211 | m1.M33 -= m2.M33;
|
---|
212 | m1.M34 -= m2.M34;
|
---|
213 | m1.M41 -= m2.M41;
|
---|
214 | m1.M42 -= m2.M42;
|
---|
215 | m1.M43 -= m2.M43;
|
---|
216 | m1.M44 -= m2.M44;
|
---|
217 |
|
---|
218 | return m1;
|
---|
219 | }
|
---|
220 |
|
---|
221 | public static Matrix operator *(Matrix m, float s)
|
---|
222 | {
|
---|
223 | m.M11 *= s;
|
---|
224 | m.M12 *= s;
|
---|
225 | m.M13 *= s;
|
---|
226 | m.M14 *= s;
|
---|
227 | m.M21 *= s;
|
---|
228 | m.M22 *= s;
|
---|
229 | m.M23 *= s;
|
---|
230 | m.M24 *= s;
|
---|
231 | m.M31 *= s;
|
---|
232 | m.M32 *= s;
|
---|
233 | m.M33 *= s;
|
---|
234 | m.M34 *= s;
|
---|
235 | m.M41 *= s;
|
---|
236 | m.M42 *= s;
|
---|
237 | m.M43 *= s;
|
---|
238 | m.M44 *= s;
|
---|
239 |
|
---|
240 | return m;
|
---|
241 | }
|
---|
242 |
|
---|
243 | public static Matrix operator *(float s, Matrix m) => m * s;
|
---|
244 |
|
---|
245 | public static Matrix operator /(Matrix m, float s) => m * (1.0f / s);
|
---|
246 |
|
---|
247 | public static Matrix operator *(Matrix m1, Matrix m2)
|
---|
248 | {
|
---|
249 | Matrix r;
|
---|
250 |
|
---|
251 | r.M11 = m1.M11 * m2.M11 + m1.M12 * m2.M21 + m1.M13 * m2.M31 + m1.M14 * m2.M41;
|
---|
252 | r.M12 = m1.M11 * m2.M12 + m1.M12 * m2.M22 + m1.M13 * m2.M32 + m1.M14 * m2.M42;
|
---|
253 | r.M13 = m1.M11 * m2.M13 + m1.M12 * m2.M23 + m1.M13 * m2.M33 + m1.M14 * m2.M43;
|
---|
254 | r.M14 = m1.M11 * m2.M14 + m1.M12 * m2.M24 + m1.M13 * m2.M34 + m1.M14 * m2.M44;
|
---|
255 | r.M21 = m1.M21 * m2.M11 + m1.M22 * m2.M21 + m1.M23 * m2.M31 + m1.M24 * m2.M41;
|
---|
256 | r.M22 = m1.M21 * m2.M12 + m1.M22 * m2.M22 + m1.M23 * m2.M32 + m1.M24 * m2.M42;
|
---|
257 | r.M23 = m1.M21 * m2.M13 + m1.M22 * m2.M23 + m1.M23 * m2.M33 + m1.M24 * m2.M43;
|
---|
258 | r.M24 = m1.M21 * m2.M14 + m1.M22 * m2.M24 + m1.M23 * m2.M34 + m1.M24 * m2.M44;
|
---|
259 | r.M31 = m1.M31 * m2.M11 + m1.M32 * m2.M21 + m1.M33 * m2.M31 + m1.M34 * m2.M41;
|
---|
260 | r.M32 = m1.M31 * m2.M12 + m1.M32 * m2.M22 + m1.M33 * m2.M32 + m1.M34 * m2.M42;
|
---|
261 | r.M33 = m1.M31 * m2.M13 + m1.M32 * m2.M23 + m1.M33 * m2.M33 + m1.M34 * m2.M43;
|
---|
262 | r.M34 = m1.M31 * m2.M14 + m1.M32 * m2.M24 + m1.M33 * m2.M34 + m1.M34 * m2.M44;
|
---|
263 | r.M41 = m1.M41 * m2.M11 + m1.M42 * m2.M21 + m1.M43 * m2.M31 + m1.M44 * m2.M41;
|
---|
264 | r.M42 = m1.M41 * m2.M12 + m1.M42 * m2.M22 + m1.M43 * m2.M32 + m1.M44 * m2.M42;
|
---|
265 | r.M43 = m1.M41 * m2.M13 + m1.M42 * m2.M23 + m1.M43 * m2.M33 + m1.M44 * m2.M43;
|
---|
266 | r.M44 = m1.M41 * m2.M14 + m1.M42 * m2.M24 + m1.M43 * m2.M34 + m1.M44 * m2.M44;
|
---|
267 |
|
---|
268 | return r;
|
---|
269 | }
|
---|
270 |
|
---|
271 | public Matrix Transpose()
|
---|
272 | {
|
---|
273 | Matrix t;
|
---|
274 |
|
---|
275 | t.M11 = M11;
|
---|
276 | t.M12 = M21;
|
---|
277 | t.M13 = M31;
|
---|
278 | t.M14 = M41;
|
---|
279 | t.M21 = M12;
|
---|
280 | t.M22 = M22;
|
---|
281 | t.M23 = M32;
|
---|
282 | t.M24 = M42;
|
---|
283 | t.M31 = M13;
|
---|
284 | t.M32 = M23;
|
---|
285 | t.M33 = M33;
|
---|
286 | t.M34 = M43;
|
---|
287 | t.M41 = M14;
|
---|
288 | t.M42 = M24;
|
---|
289 | t.M43 = M34;
|
---|
290 | t.M44 = M44;
|
---|
291 |
|
---|
292 | return t;
|
---|
293 | }
|
---|
294 |
|
---|
295 | public static bool operator ==(Matrix m1, Matrix m2) => m1.Equals(m2);
|
---|
296 | public static bool operator !=(Matrix m1, Matrix m2) => !m1.Equals(m2);
|
---|
297 |
|
---|
298 | public Vector3 XAxis
|
---|
299 | {
|
---|
300 | get
|
---|
301 | {
|
---|
302 | return new Vector3(M11, M12, M13);
|
---|
303 | }
|
---|
304 | set
|
---|
305 | {
|
---|
306 | M11 = value.X;
|
---|
307 | M12 = value.Y;
|
---|
308 | M13 = value.Z;
|
---|
309 | }
|
---|
310 | }
|
---|
311 |
|
---|
312 | public Vector3 YAxis
|
---|
313 | {
|
---|
314 | get
|
---|
315 | {
|
---|
316 | return new Vector3(M21, M22, M23);
|
---|
317 | }
|
---|
318 | set
|
---|
319 | {
|
---|
320 | M21 = value.X;
|
---|
321 | M22 = value.Y;
|
---|
322 | M23 = value.Z;
|
---|
323 | }
|
---|
324 | }
|
---|
325 |
|
---|
326 | public Vector3 ZAxis
|
---|
327 | {
|
---|
328 | get
|
---|
329 | {
|
---|
330 | return new Vector3(M31, M32, M33);
|
---|
331 | }
|
---|
332 | set
|
---|
333 | {
|
---|
334 | M31 = value.X;
|
---|
335 | M32 = value.Y;
|
---|
336 | M33 = value.Z;
|
---|
337 | }
|
---|
338 | }
|
---|
339 |
|
---|
340 | public Vector3 Scale
|
---|
341 | {
|
---|
342 | get
|
---|
343 | {
|
---|
344 | return new Vector3(M11, M22, M33);
|
---|
345 | }
|
---|
346 | set
|
---|
347 | {
|
---|
348 | M11 = value.X;
|
---|
349 | M22 = value.Y;
|
---|
350 | M33 = value.Z;
|
---|
351 | }
|
---|
352 | }
|
---|
353 |
|
---|
354 | public Vector3 Translation
|
---|
355 | {
|
---|
356 | get
|
---|
357 | {
|
---|
358 | return new Vector3(M41, M42, M43);
|
---|
359 | }
|
---|
360 | set
|
---|
361 | {
|
---|
362 | M41 = value.X;
|
---|
363 | M42 = value.Y;
|
---|
364 | M43 = value.Z;
|
---|
365 | }
|
---|
366 | }
|
---|
367 |
|
---|
368 | public bool Equals(Matrix other)
|
---|
369 | {
|
---|
370 | return (M11 == other.M11 && M12 == other.M12 && M13 == other.M13 && M14 == other.M14
|
---|
371 | && M21 == other.M21 && M22 == other.M22 && M23 == other.M23 && M24 == other.M24
|
---|
372 | && M31 == other.M31 && M32 == other.M32 && M33 == other.M33 && M34 == other.M34
|
---|
373 | && M41 == other.M41 && M42 == other.M42 && M43 == other.M43 && M44 == other.M44);
|
---|
374 | }
|
---|
375 |
|
---|
376 | public override bool Equals(object obj) => obj is Matrix && Equals((Matrix)obj);
|
---|
377 |
|
---|
378 | public override int GetHashCode()
|
---|
379 | {
|
---|
380 | return M11.GetHashCode() ^ M12.GetHashCode() ^ M13.GetHashCode() ^ M14.GetHashCode()
|
---|
381 | ^ M11.GetHashCode() ^ M12.GetHashCode() ^ M13.GetHashCode() ^ M14.GetHashCode()
|
---|
382 | ^ M11.GetHashCode() ^ M12.GetHashCode() ^ M13.GetHashCode() ^ M14.GetHashCode()
|
---|
383 | ^ M11.GetHashCode() ^ M12.GetHashCode() ^ M13.GetHashCode() ^ M14.GetHashCode();
|
---|
384 | }
|
---|
385 |
|
---|
386 | public override string ToString()
|
---|
387 | {
|
---|
388 | return string.Format("{{M11:{0} M12:{1} M13:{2} M14:{3}}}\n{{M21:{4} M22:{5} M23:{6} M24:{7}}}\n{{M31:{8} M32:{9} M33:{10} M34:{11}}}\n{{M41:{12} M42:{13} M43:{14} M44:{15}}}",
|
---|
389 | M11, M12, M13, M14,
|
---|
390 | M21, M22, M23, M24,
|
---|
391 | M31, M32, M33, M34,
|
---|
392 | M41, M42, M43, M44);
|
---|
393 | }
|
---|
394 |
|
---|
395 | private static readonly Matrix identity = new Matrix(
|
---|
396 | 1.0f, 0.0f, 0.0f, 0.0f,
|
---|
397 | 0.0f, 1.0f, 0.0f, 0.0f,
|
---|
398 | 0.0f, 0.0f, 1.0f, 0.0f,
|
---|
399 | 0.0f, 0.0f, 0.0f, 1.0f);
|
---|
400 |
|
---|
401 | public static Matrix Identity => identity;
|
---|
402 |
|
---|
403 | public Vector3 ToEuler()
|
---|
404 | {
|
---|
405 | float a = M11;
|
---|
406 | float b = M21;
|
---|
407 | float c, s, r;
|
---|
408 |
|
---|
409 | if (b == 0.0f)
|
---|
410 | {
|
---|
411 | c = FMath.Sign(a);
|
---|
412 | s = 0.0f;
|
---|
413 | r = Math.Abs(a);
|
---|
414 | }
|
---|
415 | else if (a == 0.0f)
|
---|
416 | {
|
---|
417 | c = 0.0f;
|
---|
418 | s = FMath.Sign(b);
|
---|
419 | r = Math.Abs(b);
|
---|
420 | }
|
---|
421 | else if (Math.Abs(b) > Math.Abs(a))
|
---|
422 | {
|
---|
423 | float t = a / b;
|
---|
424 | float u = FMath.Sign(b) * FMath.Sqrt(1.0f + t * t);
|
---|
425 | s = 1.0f / u;
|
---|
426 | c = s * t;
|
---|
427 | r = b * u;
|
---|
428 | }
|
---|
429 | else
|
---|
430 | {
|
---|
431 | float t = b / a;
|
---|
432 | float u = FMath.Sign(a) * FMath.Sqrt(1.0f + t * t);
|
---|
433 | c = 1.0f / u;
|
---|
434 | s = c * t;
|
---|
435 | r = a * u;
|
---|
436 | }
|
---|
437 |
|
---|
438 | Vector3 e;
|
---|
439 | e.Z = MathHelper.ToDegrees(-FMath.Atan2(s, c));
|
---|
440 | e.Y = MathHelper.ToDegrees(FMath.Atan2(M31, r));
|
---|
441 | e.X = MathHelper.ToDegrees(-FMath.Atan2(M32, M33));
|
---|
442 | return e;
|
---|
443 | }
|
---|
444 |
|
---|
445 | public float Determinant()
|
---|
446 | {
|
---|
447 | var m11 = M11;
|
---|
448 | var m12 = M12;
|
---|
449 | var m13 = M13;
|
---|
450 | var m14 = M14;
|
---|
451 | var m21 = M21;
|
---|
452 | var m22 = M22;
|
---|
453 | var m23 = M23;
|
---|
454 | var m24 = M24;
|
---|
455 | var m31 = M31;
|
---|
456 | var m32 = M32;
|
---|
457 | var m33 = M33;
|
---|
458 | var m34 = M34;
|
---|
459 | var m41 = M41;
|
---|
460 | var m42 = M42;
|
---|
461 | var m43 = M43;
|
---|
462 | var m44 = M44;
|
---|
463 |
|
---|
464 | var d3434 = m33 * m44 - m34 * m43;
|
---|
465 | var d3424 = m32 * m44 - m34 * m42;
|
---|
466 | var d3423 = m32 * m43 - m33 * m42;
|
---|
467 | var d3414 = m31 * m44 - m34 * m41;
|
---|
468 | var d3413 = m31 * m43 - m33 * m41;
|
---|
469 | var d3412 = m31 * m42 - m32 * m41;
|
---|
470 |
|
---|
471 | return m11 * (m22 * d3434 - m23 * d3424 + m24 * d3423)
|
---|
472 | - m12 * (m21 * d3434 - m23 * d3414 + m24 * d3413)
|
---|
473 | + m13 * (m21 * d3424 - m22 * d3414 + m24 * d3412)
|
---|
474 | - m14 * (m21 * d3423 - m22 * d3413 + m23 * d3412);
|
---|
475 | }
|
---|
476 |
|
---|
477 | //Matrix m = Matrix.Identity;
|
---|
478 | //m *= Matrix.CreateScale(3.3f, 1.3f, 7.6f);
|
---|
479 | //m *= Matrix.CreateTranslation(2.3f, 4.5f, 6.7f);
|
---|
480 | //m *= Matrix.CreateRotationY(1.2f);
|
---|
481 | //m *= Matrix.CreateTranslation(2.3f, 4.5f, 6.7f);
|
---|
482 | //m *= Matrix.CreateRotationY(1.2f);
|
---|
483 | //m *= Matrix.CreateTranslation(2.3f, 4.5f, 6.7f);
|
---|
484 | //m *= Matrix.CreateRotationY(1.2f);
|
---|
485 |
|
---|
486 | //Vector3 s, t;
|
---|
487 | //Quaternion r;
|
---|
488 | //m.Decompose(out s, out r, out t);
|
---|
489 | //Matrix m2 = Matrix.CreateScale(s) * Matrix.CreateFromQuaternion(r) * Matrix.CreateTranslation(t);
|
---|
490 |
|
---|
491 | //Console.WriteLine(m2 - m);
|
---|
492 | //return 0;
|
---|
493 |
|
---|
494 | //[StructLayout(LayoutKind.Sequential)]
|
---|
495 | //private unsafe struct VectorBasis
|
---|
496 | //{
|
---|
497 | // public Vector3* axis0;
|
---|
498 | // public Vector3* axis1;
|
---|
499 | // public Vector3* axis2;
|
---|
500 | //}
|
---|
501 |
|
---|
502 | //[StructLayout(LayoutKind.Sequential)]
|
---|
503 | //private struct CanonicalBasis
|
---|
504 | //{
|
---|
505 | // public Vector3 axis0;
|
---|
506 | // public Vector3 axis1;
|
---|
507 | // public Vector3 axis2;
|
---|
508 | //}
|
---|
509 |
|
---|
510 | //public unsafe bool Decompose(out Vector3 outScale, out Quaternion outRotation, out Vector3 outTranslation)
|
---|
511 | //{
|
---|
512 | // outTranslation.X = M41;
|
---|
513 | // outTranslation.Y = M42;
|
---|
514 | // outTranslation.Z = M43;
|
---|
515 |
|
---|
516 | // var rotation = new Matrix(
|
---|
517 | // M11, M12, M13, 0.0f,
|
---|
518 | // M21, M22, M23, 0.0f,
|
---|
519 | // M31, M32, M33, 0.0f,
|
---|
520 | // 0.0f, 0.0f, 0.0f, 1.0f);
|
---|
521 |
|
---|
522 | // var vectorBasis = new VectorBasis {
|
---|
523 | // axis0 = (Vector3*)&rotation.M11,
|
---|
524 | // axis1 = (Vector3*)&rotation.M21,
|
---|
525 | // axis2 = (Vector3*)&rotation.M31
|
---|
526 | // };
|
---|
527 |
|
---|
528 | // var canonicalBasis = new CanonicalBasis {
|
---|
529 | // axis0 = Vector3.UnitX,
|
---|
530 | // axis1 = Vector3.UnitY,
|
---|
531 | // axis2 = Vector3.UnitZ
|
---|
532 | // };
|
---|
533 |
|
---|
534 | // var scale = new Vector3(
|
---|
535 | // vectorBasis.axis0->Length(),
|
---|
536 | // vectorBasis.axis1->Length(),
|
---|
537 | // vectorBasis.axis2->Length()
|
---|
538 | // );
|
---|
539 |
|
---|
540 | // int xi, yi, zi;
|
---|
541 |
|
---|
542 | // if (scale.X < scale.Y)
|
---|
543 | // {
|
---|
544 | // if (scale.Y < scale.Z)
|
---|
545 | // {
|
---|
546 | // xi = 2;
|
---|
547 | // yi = 1;
|
---|
548 | // zi = 0;
|
---|
549 | // }
|
---|
550 | // else
|
---|
551 | // {
|
---|
552 | // xi = 1;
|
---|
553 |
|
---|
554 | // if (scale.X < scale.Z)
|
---|
555 | // {
|
---|
556 | // yi = 2;
|
---|
557 | // zi = 0;
|
---|
558 | // }
|
---|
559 | // else
|
---|
560 | // {
|
---|
561 | // yi = 0;
|
---|
562 | // zi = 2;
|
---|
563 | // }
|
---|
564 | // }
|
---|
565 | // }
|
---|
566 | // else
|
---|
567 | // {
|
---|
568 | // if (scale.X < scale.Z)
|
---|
569 | // {
|
---|
570 | // xi = 2;
|
---|
571 | // yi = 0;
|
---|
572 | // zi = 1;
|
---|
573 | // }
|
---|
574 | // else
|
---|
575 | // {
|
---|
576 | // xi = 0;
|
---|
577 |
|
---|
578 | // if (scale.Y < scale.Z)
|
---|
579 | // {
|
---|
580 | // yi = 2;
|
---|
581 | // zi = 1;
|
---|
582 | // }
|
---|
583 | // else
|
---|
584 | // {
|
---|
585 | // yi = 1;
|
---|
586 | // zi = 2;
|
---|
587 | // }
|
---|
588 | // }
|
---|
589 | // }
|
---|
590 |
|
---|
591 | // var pScale = &scale.X;
|
---|
592 |
|
---|
593 | // var pvBasis = &vectorBasis.axis0;
|
---|
594 | // var pcBasis = &canonicalBasis.axis0;
|
---|
595 |
|
---|
596 | // if (pScale[xi] < 0.0001f)
|
---|
597 | // {
|
---|
598 | // //
|
---|
599 | // // If the smallest scale is < 0.0001 then use the coresponding cannonical basis instead
|
---|
600 | // //
|
---|
601 |
|
---|
602 | // pvBasis[xi] = &pcBasis[xi];
|
---|
603 | // }
|
---|
604 | // else
|
---|
605 | // {
|
---|
606 | // pvBasis[xi]->Normalize();
|
---|
607 | // }
|
---|
608 |
|
---|
609 | // if (pScale[yi] < 0.0001f)
|
---|
610 | // {
|
---|
611 | // //
|
---|
612 | // // The second smallest scale is < 0.0001 too, build a perpendicular vector
|
---|
613 | // //
|
---|
614 |
|
---|
615 | // float fx = Math.Abs(pvBasis[xi]->X);
|
---|
616 | // float fy = Math.Abs(pvBasis[xi]->Y);
|
---|
617 | // float fz = Math.Abs(pvBasis[xi]->Z);
|
---|
618 |
|
---|
619 | // int yij;
|
---|
620 |
|
---|
621 | // if (fx < fy)
|
---|
622 | // {
|
---|
623 | // if (fy < fz)
|
---|
624 | // {
|
---|
625 | // yij = 0;
|
---|
626 | // }
|
---|
627 | // else
|
---|
628 | // {
|
---|
629 | // if (fx < fz)
|
---|
630 | // yij = 0;
|
---|
631 | // else
|
---|
632 | // yij = 2;
|
---|
633 | // }
|
---|
634 | // }
|
---|
635 | // else
|
---|
636 | // {
|
---|
637 | // if (fx < fz)
|
---|
638 | // {
|
---|
639 | // yij = 1;
|
---|
640 | // }
|
---|
641 | // else
|
---|
642 | // {
|
---|
643 | // if (fy < fz)
|
---|
644 | // yij = 1;
|
---|
645 | // else
|
---|
646 | // yij = 2;
|
---|
647 | // }
|
---|
648 | // }
|
---|
649 |
|
---|
650 | // pcBasis[yij] = Vector3.Cross(*pvBasis[yi], *pvBasis[xi]);
|
---|
651 | // }
|
---|
652 |
|
---|
653 | // pvBasis[yi]->Normalize();
|
---|
654 |
|
---|
655 | // if (pScale[zi] < 0.0001f)
|
---|
656 | // *(pvBasis[zi]) = Vector3.Cross(*pvBasis[yi], *pvBasis[xi]);
|
---|
657 | // else
|
---|
658 | // pvBasis[zi]->Normalize();
|
---|
659 |
|
---|
660 | // float rotDet = rotation.Determinant();
|
---|
661 |
|
---|
662 | // if (rotDet < 0.0f)
|
---|
663 | // {
|
---|
664 | // pScale[xi] = -pScale[xi];
|
---|
665 | // *(pvBasis[xi]) = -(*(pvBasis[xi]));
|
---|
666 | // rotDet = -rotDet;
|
---|
667 | // }
|
---|
668 |
|
---|
669 | // outScale = scale;
|
---|
670 |
|
---|
671 | // if (Math.Abs(rotDet - 1.0f) > 0.01f)
|
---|
672 | // {
|
---|
673 | // outRotation = Quaternion.Identity;
|
---|
674 | // return false;
|
---|
675 | // }
|
---|
676 | // else
|
---|
677 | // {
|
---|
678 | // outRotation = Quaternion.CreateFromRotationMatrix(rotation);
|
---|
679 | // return true;
|
---|
680 | // }
|
---|
681 | //}
|
---|
682 | }
|
---|
683 | }
|
---|