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 |
} |