[1114] | 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 | }
|
---|