source: 2013/30/MiskaK/MW2(My Warfare 2)/Paranneltu Jypeli/AdvanceMath/Matrix3x3.cs @ 4507

Revision 4507, 60.8 KB checked in by anlakane, 6 years ago (diff)

Talletus.

Line 
1#region MIT License
2/*
3 * Copyright (c) 2005-2008 Jonathan Mark Porter. http://physics2d.googlepages.com/
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights to
7 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 * the Software, and to permit persons to whom the Software is furnished to do so,
9 * subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be
12 * included in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
17 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 * OTHER DEALINGS IN THE SOFTWARE.
20 */
21#endregion
22
23
24#if UseDouble
25using Scalar = System.Double;
26#else
27using Scalar = System.Single;
28#endif
29using System;
30using System.Runtime.InteropServices;
31using AdvanceMath.Design;
32using System.Xml.Serialization;
33
34
35// NOTE. The (x,y,z) coordinate system is assumed to be right-handed.
36// Coordinate axis rotation matrices are of the form
37// RX = 1 0 0
38// 0 cos(t) -sin(t)
39// 0 sin(t) cos(t)
40// where t > 0 indicates a counterclockwise rotation in the yz-plane
41// RY = cos(t) 0 sin(t)
42// 0 1 0
43// -sin(t) 0 cos(t)
44// where t > 0 indicates a counterclockwise rotation in the zx-plane
45// RZ = cos(t) -sin(t) 0
46// sin(t) cos(t) 0
47// 0 0 1
48// where t > 0 indicates a counterclockwise rotation in the xy-plane.
49
50namespace AdvanceMath
51{
52    /// <summary>
53    /// A 3x3 matrix which can represent rotations around axes.
54    /// </summary>
55    [StructLayout(LayoutKind.Sequential, Size = Matrix3x3.Size)]
56    [AdvBrowsableOrder("Rx,Ry,Rz")]
57#if !CompactFramework && !WindowsCE && !PocketPC && !XBOX360 && !SILVERLIGHT && !WINDOWS_PHONE
58    [Serializable]
59    [System.ComponentModel.TypeConverter(typeof(AdvTypeConverter<Matrix3x3>))]
60#endif
61    public struct Matrix3x3 : IMatrix<Matrix3x3, Vector3D, Vector3D>
62    {
63        #region const fields
64        /// <summary>
65        /// The number of rows.
66        /// </summary>
67        public const int RowCount = 3;
68        /// <summary>
69        /// The number of columns.
70        /// </summary>
71        public const int ColumnCount = 3;
72        /// <summary>
73        /// The number of Scalar values in the class.
74        /// </summary>
75        public const int Count = RowCount * ColumnCount;
76        /// <summary>
77        /// The Size of the class in bytes;
78        /// </summary>
79        public const int Size = sizeof(Scalar) * Count;
80        #endregion
81        #region static fields
82        private readonly static string FormatString = MatrixHelper.CreateMatrixFormatString(RowCount, ColumnCount);
83        private readonly static string FormatableString = MatrixHelper.CreateMatrixFormatableString(RowCount, ColumnCount);
84
85        public static readonly Matrix3x3 Identity = new Matrix3x3(
86        1, 0, 0,
87        0, 1, 0,
88        0, 0, 1);
89        public static readonly Matrix3x3 Zero = new Matrix3x3(
90        0, 0, 0,
91        0, 0, 0,
92        0, 0, 0);
93        #endregion
94        #region static methods
95
96        public static void Copy(ref Matrix3x3 matrix, Scalar[] destArray)
97        {
98            Copy(ref matrix, destArray, 0);
99        }
100        public static void Copy(ref Matrix3x3 matrix, Scalar[] destArray, int index)
101        {
102            ThrowHelper.CheckCopy(destArray, index, Count);
103
104            destArray[index] = matrix.m00;
105            destArray[++index] = matrix.m01;
106            destArray[++index] = matrix.m02;
107
108            destArray[++index] = matrix.m10;
109            destArray[++index] = matrix.m11;
110            destArray[++index] = matrix.m12;
111
112            destArray[++index] = matrix.m20;
113            destArray[++index] = matrix.m21;
114            destArray[++index] = matrix.m22;
115        }
116        public static void Copy(Scalar[] sourceArray, out Matrix3x3 result)
117        {
118            Copy(sourceArray, 0, out result);
119        }
120        public static void Copy(Scalar[] sourceArray, int index, out Matrix3x3 result)
121        {
122            ThrowHelper.CheckCopy(sourceArray, index, Count);
123
124            result.m00 = sourceArray[index];
125            result.m01 = sourceArray[++index];
126            result.m02 = sourceArray[++index];
127
128            result.m10 = sourceArray[++index];
129            result.m11 = sourceArray[++index];
130            result.m12 = sourceArray[++index];
131
132            result.m20 = sourceArray[++index];
133            result.m21 = sourceArray[++index];
134            result.m22 = sourceArray[++index];
135        }
136
137        public static void CopyTranspose(ref Matrix3x3 matrix, Scalar[] destArray)
138        {
139            CopyTranspose(ref matrix, destArray, 0);
140        }
141        public static void CopyTranspose(ref Matrix3x3 matrix, Scalar[] destArray, int index)
142        {
143            ThrowHelper.CheckCopy(destArray, index, Count);
144
145            destArray[index] = matrix.m00;
146            destArray[++index] = matrix.m10;
147            destArray[++index] = matrix.m20;
148
149            destArray[++index] = matrix.m01;
150            destArray[++index] = matrix.m11;
151            destArray[++index] = matrix.m21;
152
153            destArray[++index] = matrix.m02;
154            destArray[++index] = matrix.m12;
155            destArray[++index] = matrix.m22;
156        }
157        public static void CopyTranspose(Scalar[] sourceArray, out Matrix3x3 result)
158        {
159            CopyTranspose(sourceArray, 0, out result);
160        }
161        public static void CopyTranspose(Scalar[] sourceArray, int index, out Matrix3x3 result)
162        {
163            ThrowHelper.CheckCopy(sourceArray, index, Count);
164
165            result.m00 = sourceArray[index];
166            result.m10 = sourceArray[++index];
167            result.m20 = sourceArray[++index];
168
169            result.m01 = sourceArray[++index];
170            result.m11 = sourceArray[++index];
171            result.m21 = sourceArray[++index];
172
173            result.m02 = sourceArray[++index];
174            result.m12 = sourceArray[++index];
175            result.m22 = sourceArray[++index];
176        }
177
178        public static void Copy(ref Matrix4x4 source, out Matrix3x3 dest)
179        {
180            dest.m00 = source.m00;
181            dest.m01 = source.m01;
182            dest.m02 = source.m02;
183
184            dest.m10 = source.m10;
185            dest.m11 = source.m11;
186            dest.m12 = source.m12;
187
188            dest.m20 = source.m20;
189            dest.m21 = source.m21;
190            dest.m22 = source.m22;
191        }
192        public static void Copy(ref Matrix2x2 source, ref Matrix3x3 dest)
193        {
194            dest.m00 = source.m00;
195            dest.m01 = source.m01;
196
197            dest.m10 = source.m10;
198            dest.m11 = source.m11;
199        }
200
201        public static void Copy2DToOpenGlMatrix(ref Matrix3x3 source, Scalar[] destArray)
202        {
203            destArray[0] = source.m00;
204            destArray[1] = source.m10;
205
206            destArray[3] = source.m20;
207
208            destArray[4] = source.m01;
209            destArray[5] = source.m11;
210
211            destArray[7] = source.m21;
212
213            destArray[12] = source.m02;
214            destArray[13] = source.m12;
215
216            destArray[15] = source.m22;
217        }
218
219
220        public static Matrix3x3 Lerp(Matrix3x3 left, Matrix3x3 right, Scalar amount)
221        {
222            Matrix3x3 result;
223            Lerp(ref left, ref right, ref amount, out result);
224            return result;
225        }
226        public static void Lerp(ref Matrix3x3 left, ref  Matrix3x3 right, ref  Scalar amount, out Matrix3x3 result)
227        {
228            result.m00 = (right.m00 - left.m00) * amount + left.m00;
229            result.m01 = (right.m01 - left.m01) * amount + left.m01;
230            result.m02 = (right.m02 - left.m02) * amount + left.m02;
231
232            result.m10 = (right.m10 - left.m10) * amount + left.m10;
233            result.m11 = (right.m11 - left.m11) * amount + left.m11;
234            result.m12 = (right.m12 - left.m12) * amount + left.m12;
235
236            result.m20 = (right.m20 - left.m20) * amount + left.m20;
237            result.m21 = (right.m21 - left.m21) * amount + left.m21;
238            result.m22 = (right.m22 - left.m22) * amount + left.m22;
239        }
240
241
242        /// <summary>
243        /// Used to multiply (concatenate) two Matrix4x4s.
244        /// </summary>
245        /// <param name="left"></param>
246        /// <param name="right"></param>
247        /// <returns></returns>
248        public static Matrix3x3 Multiply(Matrix3x3 left, Matrix3x3 right)
249        {
250            Matrix3x3 result;
251
252            result.m00 = left.m00 * right.m00 + left.m01 * right.m10 + left.m02 * right.m20;
253            result.m01 = left.m00 * right.m01 + left.m01 * right.m11 + left.m02 * right.m21;
254            result.m02 = left.m00 * right.m02 + left.m01 * right.m12 + left.m02 * right.m22;
255
256            result.m10 = left.m10 * right.m00 + left.m11 * right.m10 + left.m12 * right.m20;
257            result.m11 = left.m10 * right.m01 + left.m11 * right.m11 + left.m12 * right.m21;
258            result.m12 = left.m10 * right.m02 + left.m11 * right.m12 + left.m12 * right.m22;
259
260            result.m20 = left.m20 * right.m00 + left.m21 * right.m10 + left.m22 * right.m20;
261            result.m21 = left.m20 * right.m01 + left.m21 * right.m11 + left.m22 * right.m21;
262            result.m22 = left.m20 * right.m02 + left.m21 * right.m12 + left.m22 * right.m22;
263
264            return result;
265        }
266        public static void Multiply(ref Matrix3x3 left, ref Matrix3x3 right, out Matrix3x3 result)
267        {
268            Scalar m00 = left.m00 * right.m00 + left.m01 * right.m10 + left.m02 * right.m20;
269            Scalar m01 = left.m00 * right.m01 + left.m01 * right.m11 + left.m02 * right.m21;
270            Scalar m02 = left.m00 * right.m02 + left.m01 * right.m12 + left.m02 * right.m22;
271
272            Scalar m10 = left.m10 * right.m00 + left.m11 * right.m10 + left.m12 * right.m20;
273            Scalar m11 = left.m10 * right.m01 + left.m11 * right.m11 + left.m12 * right.m21;
274            Scalar m12 = left.m10 * right.m02 + left.m11 * right.m12 + left.m12 * right.m22;
275
276            Scalar m20 = left.m20 * right.m00 + left.m21 * right.m10 + left.m22 * right.m20;
277            Scalar m21 = left.m20 * right.m01 + left.m21 * right.m11 + left.m22 * right.m21;
278            Scalar m22 = left.m20 * right.m02 + left.m21 * right.m12 + left.m22 * right.m22;
279
280
281            result.m00 = m00;
282            result.m01 = m01;
283            result.m02 = m02;
284
285            result.m10 = m10;
286            result.m11 = m11;
287            result.m12 = m12;
288
289            result.m20 = m20;
290            result.m21 = m21;
291            result.m22 = m22;
292        }
293
294        /// <summary>
295        /// Used to multiply a Matrix3x3 object by a scalar value..
296        /// </summary>
297        /// <param name="left"></param>
298        /// <param name="scalar"></param>
299        /// <returns></returns>
300        public static Matrix3x3 Multiply(Matrix3x3 left, Scalar scalar)
301        {
302            Matrix3x3 result;
303
304            result.m00 = left.m00 * scalar;
305            result.m01 = left.m01 * scalar;
306            result.m02 = left.m02 * scalar;
307
308            result.m10 = left.m10 * scalar;
309            result.m11 = left.m11 * scalar;
310            result.m12 = left.m12 * scalar;
311
312            result.m20 = left.m20 * scalar;
313            result.m21 = left.m21 * scalar;
314            result.m22 = left.m22 * scalar;
315
316            return result;
317        }
318        public static void Multiply(ref Matrix3x3 left, ref Scalar scalar, out Matrix3x3 result)
319        {
320
321            result.m00 = left.m00 * scalar;
322            result.m01 = left.m01 * scalar;
323            result.m02 = left.m02 * scalar;
324
325            result.m10 = left.m10 * scalar;
326            result.m11 = left.m11 * scalar;
327            result.m12 = left.m12 * scalar;
328
329            result.m20 = left.m20 * scalar;
330            result.m21 = left.m21 * scalar;
331            result.m22 = left.m22 * scalar;
332        }
333
334        /// <summary>
335        /// Used to multiply (concatenate) a Matrix3x3 and a Matrix2x2.
336        /// </summary>
337        /// <param name="left"></param>
338        /// <param name="right"></param>
339        /// <returns></returns>
340        public static Matrix3x3 Multiply(Matrix3x3 left, Matrix2x2 right)
341        {
342            Matrix3x3 result;
343
344            result.m00 = left.m00 * right.m00 + left.m01 * right.m10;
345            result.m01 = left.m00 * right.m01 + left.m01 * right.m11;
346            result.m02 = left.m02;
347
348            result.m10 = left.m10 * right.m00 + left.m11 * right.m10;
349            result.m11 = left.m10 * right.m01 + left.m11 * right.m11;
350            result.m12 = left.m12;
351
352            result.m20 = left.m20 * right.m00 + left.m21 * right.m10;
353            result.m21 = left.m20 * right.m01 + left.m21 * right.m11;
354            result.m22 = left.m22;
355
356            return result;
357        }
358        public static void Multiply(ref Matrix3x3 left, ref Matrix2x2 right, out Matrix3x3 result)
359        {
360            Scalar m00 = left.m00 * right.m00 + left.m01 * right.m10;
361            Scalar m01 = left.m00 * right.m01 + left.m01 * right.m11;
362
363            Scalar m10 = left.m10 * right.m00 + left.m11 * right.m10;
364            Scalar m11 = left.m10 * right.m01 + left.m11 * right.m11;
365
366            Scalar m20 = left.m20 * right.m00 + left.m21 * right.m10;
367            Scalar m21 = left.m20 * right.m01 + left.m21 * right.m11;
368
369            result.m00 = m00;
370            result.m01 = m01;
371            result.m02 = left.m02;
372
373            result.m10 = m10;
374            result.m11 = m11;
375            result.m12 = left.m12;
376
377            result.m20 = m20;
378            result.m21 = m21;
379            result.m22 = left.m22;
380        }
381
382        /// <summary>
383        /// Used to multiply (concatenate) a Matrix3x3 and a Matrix2x2.
384        /// </summary>
385        /// <param name="left"></param>
386        /// <param name="right"></param>
387        /// <returns></returns>
388        public static Matrix3x3 Multiply(Matrix2x2 left, Matrix3x3 right)
389        {
390            Matrix3x3 result;
391
392            result.m00 = left.m00 * right.m00 + left.m01 * right.m10;
393            result.m01 = left.m00 * right.m01 + left.m01 * right.m11;
394            result.m02 = left.m00 * right.m02 + left.m01 * right.m12;
395
396            result.m10 = left.m10 * right.m00 + left.m11 * right.m10;
397            result.m11 = left.m10 * right.m01 + left.m11 * right.m11;
398            result.m12 = left.m10 * right.m02 + left.m11 * right.m12;
399
400            result.m20 = right.m20;
401            result.m21 = right.m21;
402            result.m22 = right.m22;
403
404
405
406            return result;
407        }
408        public static void Multiply(ref Matrix2x2 left, ref Matrix3x3 right, out Matrix3x3 result)
409        {
410            Scalar m00 = left.m00 * right.m00 + left.m01 * right.m10;
411            Scalar m01 = left.m00 * right.m01 + left.m01 * right.m11;
412            Scalar m02 = left.m00 * right.m02 + left.m01 * right.m12;
413
414            Scalar m10 = left.m10 * right.m00 + left.m11 * right.m10;
415            Scalar m11 = left.m10 * right.m01 + left.m11 * right.m11;
416            Scalar m12 = left.m10 * right.m02 + left.m11 * right.m12;
417
418            result.m00 = m00;
419            result.m01 = m01;
420            result.m02 = m02;
421
422            result.m10 = m10;
423            result.m11 = m11;
424            result.m12 = m12;
425
426            result.m20 = right.m20;
427            result.m21 = right.m21;
428            result.m22 = right.m22;
429
430
431        }
432
433
434        /// <summary>
435        /// Used to add two matrices together.
436        /// </summary>
437        /// <param name="left"></param>
438        /// <param name="right"></param>
439        /// <returns></returns>
440        public static Matrix3x3 Add(Matrix3x3 left, Matrix3x3 right)
441        {
442            Matrix3x3 result;
443
444            result.m00 = left.m00 + right.m00;
445            result.m01 = left.m01 + right.m01;
446            result.m02 = left.m02 + right.m02;
447
448            result.m10 = left.m10 + right.m10;
449            result.m11 = left.m11 + right.m11;
450            result.m12 = left.m12 + right.m12;
451
452            result.m20 = left.m20 + right.m20;
453            result.m21 = left.m21 + right.m21;
454            result.m22 = left.m22 + right.m22;
455
456            return result;
457        }
458        public static void Add(ref Matrix3x3 left, ref Matrix3x3 right, out Matrix3x3 result)
459        {
460            result.m00 = left.m00 + right.m00;
461            result.m01 = left.m01 + right.m01;
462            result.m02 = left.m02 + right.m02;
463
464            result.m10 = left.m10 + right.m10;
465            result.m11 = left.m11 + right.m11;
466            result.m12 = left.m12 + right.m12;
467
468            result.m20 = left.m20 + right.m20;
469            result.m21 = left.m21 + right.m21;
470            result.m22 = left.m22 + right.m22;
471        }
472
473        public static Matrix3x3 Add(Matrix2x2 left, Matrix3x3 right)
474        {
475            Matrix3x3 result;
476            Add(ref left, ref right, out result);
477            return result;
478        }
479        public static void Add(ref Matrix2x2 left, ref Matrix3x3 right, out Matrix3x3 result)
480        {
481            result.m00 = left.m00 + right.m00;
482            result.m01 = left.m01 + right.m01;
483            result.m02 = right.m02;
484
485            result.m10 = left.m10 + right.m10;
486            result.m11 = left.m11 + right.m11;
487            result.m12 = right.m12;
488
489            result.m20 = right.m20;
490            result.m21 = right.m21;
491            result.m22 = 1 + right.m22;
492        }
493        public static Matrix3x3 Add(Matrix3x3 left, Matrix2x2 right)
494        {
495            Matrix3x3 result;
496            Add(ref left, ref right, out result);
497            return result;
498        }
499        public static void Add(ref Matrix3x3 left, ref Matrix2x2 right, out Matrix3x3 result)
500        {
501            result.m00 = left.m00 + right.m00;
502            result.m01 = left.m01 + right.m01;
503            result.m02 = left.m02;
504
505            result.m10 = left.m10 + right.m10;
506            result.m11 = left.m11 + right.m11;
507            result.m12 = left.m12;
508
509            result.m20 = left.m20;
510            result.m21 = left.m21;
511            result.m22 = left.m22 + 1;
512        }
513
514
515
516        /// <summary>
517        /// Used to subtract two matrices.
518        /// </summary>
519        /// <param name="left"></param>
520        /// <param name="right"></param>
521        /// <returns></returns>
522        public static Matrix3x3 Subtract(Matrix3x3 left, Matrix3x3 right)
523        {
524            Matrix3x3 result;
525
526            result.m00 = left.m00 - right.m00;
527            result.m01 = left.m01 - right.m01;
528            result.m02 = left.m02 - right.m02;
529
530            result.m10 = left.m10 - right.m10;
531            result.m11 = left.m11 - right.m11;
532            result.m12 = left.m12 - right.m12;
533
534            result.m20 = left.m20 - right.m20;
535            result.m21 = left.m21 - right.m21;
536            result.m22 = left.m22 - right.m22;
537
538            return result;
539        }
540        public static void Subtract(ref Matrix3x3 left, ref Matrix3x3 right, out Matrix3x3 result)
541        {
542            result.m00 = left.m00 - right.m00;
543            result.m01 = left.m01 - right.m01;
544            result.m02 = left.m02 - right.m02;
545
546            result.m10 = left.m10 - right.m10;
547            result.m11 = left.m11 - right.m11;
548            result.m12 = left.m12 - right.m12;
549
550            result.m20 = left.m20 - right.m20;
551            result.m21 = left.m21 - right.m21;
552            result.m22 = left.m22 - right.m22;
553
554        }
555
556        public static Matrix3x3 Subtract(Matrix2x2 left, Matrix3x3 right)
557        {
558            Matrix3x3 result;
559            Subtract(ref left, ref right, out result);
560            return result;
561        }
562        public static void Subtract(ref Matrix2x2 left, ref Matrix3x3 right, out Matrix3x3 result)
563        {
564            result.m00 = left.m00 - right.m00;
565            result.m01 = left.m01 - right.m01;
566            result.m02 = -right.m02;
567
568            result.m10 = left.m10 - right.m10;
569            result.m11 = left.m11 - right.m11;
570            result.m12 = -right.m12;
571
572            result.m20 = -right.m20;
573            result.m21 = -right.m21;
574            result.m22 = 1 - right.m22;
575        }
576        public static Matrix3x3 Subtract(Matrix3x3 left, Matrix2x2 right)
577        {
578            Matrix3x3 result;
579            Subtract(ref left, ref right, out result);
580            return result;
581        }
582        public static void Subtract(ref Matrix3x3 left, ref Matrix2x2 right, out Matrix3x3 result)
583        {
584            result.m00 = left.m00 - right.m00;
585            result.m01 = left.m01 - right.m01;
586            result.m02 = left.m02;
587
588            result.m10 = left.m10 - right.m10;
589            result.m11 = left.m11 - right.m11;
590            result.m12 = left.m12;
591
592            result.m20 = left.m20;
593            result.m21 = left.m21;
594            result.m22 = left.m22 - 1;
595        }
596
597        /// <summary>
598        /// Negates a Matrix3x3.
599        /// </summary>
600        /// <param name="left"></param>
601        /// <param name="right"></param>
602        /// <returns></returns>
603        public static Matrix3x3 Negate(Matrix3x3 source)
604        {
605            Matrix3x3 result;
606
607            result.m00 = -source.m00;
608            result.m01 = -source.m01;
609            result.m02 = -source.m02;
610
611            result.m10 = -source.m10;
612            result.m11 = -source.m11;
613            result.m12 = -source.m12;
614
615            result.m20 = -source.m20;
616            result.m21 = -source.m21;
617            result.m22 = -source.m22;
618
619
620            return result;
621        }
622        [CLSCompliant(false)]
623        public static void Negate(ref Matrix3x3 source)
624        {
625            Negate(ref source, out source);
626        }
627        public static void Negate(ref Matrix3x3 source, out Matrix3x3 result)
628        {
629            result.m00 = -source.m00;
630            result.m01 = -source.m01;
631            result.m02 = -source.m02;
632
633            result.m10 = -source.m10;
634            result.m11 = -source.m11;
635            result.m12 = -source.m12;
636
637            result.m20 = -source.m20;
638            result.m21 = -source.m21;
639            result.m22 = -source.m22;
640        }
641
642        public static Matrix3x3 Invert(Matrix3x3 source)
643        {
644            Matrix3x3 result;
645            Invert(ref source, out result);
646            return result;
647        }
648        public static void Invert(ref Matrix3x3 source, out Matrix3x3 result)
649        {
650            Scalar m01 = source.m01;
651            Scalar m02 = source.m02;
652
653            Scalar m11 = source.m11;
654            Scalar m12 = source.m12;
655
656
657
658
659            Scalar m11m22m12m21 = (m11 * source.m22 - m12 * source.m21);
660            Scalar m10m22m12m20 = (source.m10 * source.m22 - m12 * source.m20);
661            Scalar m10m21m11m20 = (source.m10 * source.m21 - m11 * source.m20);
662
663
664
665            Scalar detInv = 1 / (source.m00 * (m11m22m12m21) - m01 * (m10m22m12m20) + m02 * (m10m21m11m20));
666
667
668            result.m01 = detInv * (-(m01 * source.m22 - m02 * source.m21));
669            result.m02 = detInv * (m01 * m12 - m02 * m11);
670
671            result.m11 = detInv * (source.m00 * source.m22 - m02 * source.m20);
672            result.m12 = detInv * (-(source.m00 * m12 - m02 * source.m10));
673
674            result.m21 = detInv * (-(source.m00 * source.m21 - m01 * source.m20));
675            result.m22 = detInv * (source.m00 * m11 - m01 * source.m10);
676
677
678            result.m00 = detInv * (m11m22m12m21);
679            result.m10 = detInv * (-(m10m22m12m20));
680            result.m20 = detInv * (m10m21m11m20);
681
682        }
683
684        public static Scalar GetDeterminant(Matrix3x3 source)
685        {
686            Scalar result;
687            GetDeterminant(ref source, out result);
688            return result;
689        }
690        public static void GetDeterminant(ref Matrix3x3 source, out Scalar result)
691        {
692            // note: this is an expanded version of the Ogre determinant() method, to give better performance in C#. Generated using a script
693            result =
694            source.m00 * (source.m11 * source.m22 - source.m12 * source.m21) -
695            source.m01 * (source.m10 * source.m22 - source.m12 * source.m20) +
696            source.m02 * (source.m10 * source.m21 - source.m11 * source.m20);
697        }
698
699        public static Matrix3x3 Transpose(Matrix3x3 source)
700        {
701            Matrix3x3 result;
702            Transpose(ref source, out result);
703            return result;
704        }
705        public static void Transpose(ref Matrix3x3 source, out Matrix3x3 result)
706        {
707            Scalar m01 = source.m01;
708            Scalar m02 = source.m02;
709            Scalar m12 = source.m12;
710
711            result.m00 = source.m00;
712            result.m01 = source.m10;
713            result.m02 = source.m20;
714
715            result.m10 = m01;
716            result.m11 = source.m11;
717            result.m12 = source.m21;
718
719            result.m20 = m02;
720            result.m21 = m12;
721            result.m22 = source.m22;
722
723
724
725        }
726
727        public static Matrix3x3 GetAdjoint(Matrix3x3 source)
728        {
729            Matrix3x3 result;
730            GetAdjoint(ref source, out result);
731            return result;
732        }
733        public static void GetAdjoint(ref Matrix3x3 source, out Matrix3x3 result)
734        {
735            Scalar m01 = source.m01;
736            Scalar m02 = source.m02;
737            Scalar m11 = source.m11;
738            Scalar m12 = source.m12;
739
740            Scalar m11m22m12m21 = (m11 * source.m22 - m12 * source.m21);
741            Scalar m10m22m12m20 = (source.m10 * source.m22 - m12 * source.m20);
742            Scalar m10m21m11m20 = (source.m10 * source.m21 - m11 * source.m20);
743
744
745            result.m01 = (-(m01 * source.m22 - m02 * source.m21));
746            result.m02 = (m01 * m12 - m02 * m11);
747
748            result.m11 = (source.m00 * source.m22 - m02 * source.m20);
749            result.m12 = (-(source.m00 * m12 - m02 * source.m10));
750
751            result.m21 = (-(source.m00 * source.m21 - m01 * source.m20));
752            result.m22 = (source.m00 * m11 - m01 * source.m10);
753
754
755            result.m00 = (m11m22m12m21);
756            result.m10 = (-(m10m22m12m20));
757            result.m20 = (m10m21m11m20);
758
759        }
760
761        public static Matrix3x3 GetCofactor(Matrix3x3 source)
762        {
763            Matrix3x3 result;
764            GetCofactor(ref source, out result);
765            return result;
766        }
767        public static void GetCofactor(ref Matrix3x3 source, out Matrix3x3 result)
768        {
769            Scalar m01 = source.m01;
770            Scalar m02 = source.m02;
771            Scalar m11 = source.m11;
772            Scalar m12 = source.m12;
773
774            Scalar m11m22m12m21 = (m11 * source.m22 - m12 * source.m21);
775            Scalar m10m22m12m20 = (source.m10 * source.m22 - m12 * source.m20);
776            Scalar m10m21m11m20 = (source.m10 * source.m21 - m11 * source.m20);
777
778
779            result.m01 = ((m01 * source.m22 - m02 * source.m21));
780            result.m02 = (-(m01 * m12 - m02 * m11));
781
782            result.m11 = (-(source.m00 * source.m22 - m02 * source.m20));
783            result.m12 = ((source.m00 * m12 - m02 * source.m10));
784
785            result.m21 = ((source.m00 * source.m21 - m01 * source.m20));
786            result.m22 = (-(source.m00 * m11 - m01 * source.m10));
787
788
789            result.m00 = (-(m11m22m12m21));
790            result.m10 = ((m10m22m12m20));
791            result.m20 = (-(m10m21m11m20));
792
793        }
794
795
796
797        public static Matrix3x3 FromArray(Scalar[] array)
798        {
799            Matrix3x3 result;
800            Copy(array, 0, out result);
801            return result;
802        }
803        public static Matrix3x3 FromTransposedArray(Scalar[] array)
804        {
805            Matrix3x3 result;
806            CopyTranspose(array, 0, out result);
807            return result;
808        }
809
810        public static Matrix3x3 FromTransformation(Scalar rotation, Vector2D translation)
811        {
812            Matrix3x3 result;
813            FromTransformation(ref rotation, ref translation, out result);
814            return result;
815        }
816        public static void FromTransformation(ref Scalar rotation, ref Vector2D translation, out Matrix3x3 result)
817        {
818            result.m00 = MathHelper.Cos(rotation);
819            result.m10 = MathHelper.Sin(rotation);
820            result.m01 = -result.m10;
821            result.m11 = result.m00;
822            result.m02 = translation.X;
823            result.m12 = translation.Y;
824            result.m20 = 0;
825            result.m21 = 0;
826            result.m22 = 1;
827        }
828
829        public static Matrix3x3 FromRotationX(Scalar radianAngle)
830        {
831            Matrix3x3 result;
832
833            result.m21 = MathHelper.Sin(radianAngle);
834
835
836            result.m00 = 1;
837            result.m01 = 0;
838            result.m02 = 0;
839
840            result.m10 = 0;
841            result.m11 = MathHelper.Cos(radianAngle);
842            result.m12 = -result.m21;
843
844            result.m20 = 0;
845            result.m22 = result.m11;
846
847            return result;
848        }
849        public static void FromRotationX(ref Scalar radianAngle, out Matrix3x3 result)
850        {
851            result.m21 = MathHelper.Sin(radianAngle);
852
853
854            result.m00 = 1;
855            result.m01 = 0;
856            result.m02 = 0;
857
858            result.m10 = 0;
859            result.m11 = MathHelper.Cos(radianAngle);
860            result.m12 = -result.m21;
861
862            result.m20 = 0;
863            result.m22 = result.m11;
864        }
865        public static Matrix3x3 FromRotationY(Scalar radianAngle)
866        {
867            Matrix3x3 result;
868
869            result.m20 = MathHelper.Sin(radianAngle);
870
871
872            result.m00 = MathHelper.Cos(radianAngle);
873            result.m01 = 0;
874            result.m02 = -result.m20;
875
876            result.m10 = 0;
877            result.m11 = 1;
878            result.m12 = 0;
879
880            result.m21 = 0;
881            result.m22 = result.m00;
882
883            return result;
884        }
885        public static void FromRotationY(ref Scalar radianAngle, out Matrix3x3 result)
886        {
887            result.m20 = MathHelper.Sin(radianAngle);
888
889
890            result.m00 = MathHelper.Cos(radianAngle);
891            result.m01 = 0;
892            result.m02 = -result.m20;
893
894            result.m10 = 0;
895            result.m11 = 1;
896            result.m12 = 0;
897
898            result.m21 = 0;
899            result.m22 = result.m00;
900
901        }
902        public static Matrix3x3 FromRotationZ(Scalar radianAngle)
903        {
904            Matrix3x3 result;
905
906            result.m10 = MathHelper.Sin(radianAngle);
907
908
909            result.m00 = MathHelper.Cos(radianAngle);
910            result.m01 = -result.m10;
911            result.m02 = 0;
912
913            result.m11 = result.m00;
914            result.m12 = 0;
915
916            result.m20 = 0;
917            result.m21 = 0;
918            result.m22 = 1;
919
920            return result;
921        }
922        public static void FromRotationZ(ref Scalar radianAngle, out Matrix3x3 result)
923        {
924
925            result.m10 = MathHelper.Sin(radianAngle);
926
927
928            result.m00 = MathHelper.Cos(radianAngle);
929            result.m01 = -result.m10;
930            result.m02 = 0;
931
932            result.m11 = result.m00;
933            result.m12 = 0;
934
935            result.m20 = 0;
936            result.m21 = 0;
937            result.m22 = 1;
938
939        }
940        public static Matrix3x3 FromRotationAxisUsingAtan(Scalar radianAngle, Vector3D axis)
941        {
942            Scalar zAngle;
943            Scalar yAngle;
944            if (axis.X == 0)
945            {
946                if (axis.Y == 0)
947                {
948                    return FromRotationZ(radianAngle);
949                }
950                else
951                {
952                    zAngle = MathHelper.PiOver2;
953                    yAngle = (Scalar)Math.Atan(axis.Z / axis.Y);
954                }
955            }
956            else
957            {
958                zAngle = (Scalar)Math.Atan(axis.Y / axis.X);
959                yAngle = (Scalar)Math.Atan(axis.Z / Math.Sqrt(axis.X * axis.X + axis.Y * axis.Y));
960            }
961            return FromRotationZ(-zAngle) *
962            FromRotationY(-yAngle) *
963            FromRotationX(radianAngle) *
964            FromRotationY(yAngle) *
965            FromRotationZ(zAngle);
966        }
967
968        public static Matrix3x3 FromRotationAxis(Scalar radianAngle, Vector3D axis)
969        {
970            Matrix3x3 first = FromLookAt(Vector3D.Zero, axis, new Vector3D(axis.Z, axis.X, axis.Y));
971            return first.Inverted * FromRotationZ(radianAngle) * first;
972        }
973        internal static Matrix3x3 FromLookAt(Vector3D origin, Vector3D positiveZAxis, Vector3D onPositiveY)
974        {
975            Matrix3x3 rv = Identity;
976            rv.Rz = Vector3D.Normalize(positiveZAxis - origin);
977            rv.Rx = Vector3D.Normalize((onPositiveY - origin) ^ rv.Rz);
978            rv.Ry = Vector3D.Normalize(rv.Rz ^ rv.Rx);
979            return rv;
980        }
981
982
983        public static Matrix3x3 FromScale(Vector3D scale)
984        {
985            Matrix3x3 result;
986
987            result.m00 = scale.X;
988            result.m01 = 0;
989            result.m02 = 0;
990
991            result.m10 = 0;
992            result.m11 = scale.Y;
993            result.m12 = 0;
994
995            result.m20 = 0;
996            result.m21 = 0;
997            result.m22 = scale.Z;
998
999            return result;
1000        }
1001        public static void FromScale(ref Vector3D scale, out Matrix3x3 result)
1002        {
1003            result.m00 = scale.X;
1004            result.m01 = 0;
1005            result.m02 = 0;
1006
1007            result.m10 = 0;
1008            result.m11 = scale.Y;
1009            result.m12 = 0;
1010
1011            result.m20 = 0;
1012            result.m21 = 0;
1013            result.m22 = scale.Z;
1014        }
1015        public static Matrix3x3 FromScale(Vector2D scale)
1016        {
1017            Matrix3x3 result;
1018            result.m00 = scale.X;
1019            result.m01 = 0;
1020            result.m02 = 0;
1021
1022            result.m10 = 0;
1023            result.m11 = scale.Y;
1024            result.m12 = 0;
1025
1026            result.m20 = 0;
1027            result.m21 = 0;
1028            result.m22 = 1;
1029            return result;
1030        }
1031        public static void FromScale(ref Vector2D scale, out Matrix3x3 result)
1032        {
1033            result.m00 = scale.X;
1034            result.m01 = 0;
1035            result.m02 = 0;
1036
1037            result.m10 = 0;
1038            result.m11 = scale.Y;
1039            result.m12 = 0;
1040
1041            result.m20 = 0;
1042            result.m21 = 0;
1043            result.m22 = 1;
1044        }
1045        public static Matrix3x3 FromTranslate2D(Vector2D value)
1046        {
1047            Matrix3x3 result;
1048
1049            result.m00 = 1;
1050            result.m01 = 0;
1051            result.m02 = value.X;
1052
1053            result.m10 = 0;
1054            result.m11 = 1;
1055            result.m12 = value.Y;
1056
1057            result.m20 = 0;
1058            result.m21 = 0;
1059            result.m22 = 1;
1060
1061            return result;
1062        }
1063        public static void FromTranslate2D(ref Vector2D value, out Matrix3x3 result)
1064        {
1065            result.m00 = 1;
1066            result.m01 = 0;
1067            result.m02 = value.X;
1068
1069            result.m10 = 0;
1070            result.m11 = 1;
1071            result.m12 = value.Y;
1072
1073            result.m20 = 0;
1074            result.m21 = 0;
1075            result.m22 = 1;
1076        }
1077        public static Matrix3x3 FromShear3D(Vector2D value)
1078        {
1079            Matrix3x3 result;
1080
1081            result.m00 = 1;
1082            result.m01 = 0;
1083            result.m02 = value.X;
1084
1085            result.m10 = 0;
1086            result.m11 = 1;
1087            result.m12 = value.Y;
1088
1089            result.m20 = 0;
1090            result.m21 = 0;
1091            result.m22 = 1;
1092
1093            return result;
1094        }
1095        public static void FromShear3D(ref Vector2D value, out Matrix3x3 result)
1096        {
1097            result.m00 = 1;
1098            result.m01 = 0;
1099            result.m02 = value.X;
1100
1101            result.m10 = 0;
1102            result.m11 = 1;
1103            result.m12 = value.Y;
1104
1105            result.m20 = 0;
1106            result.m21 = 0;
1107            result.m22 = 1;
1108        }
1109
1110        public static Scalar GetDeterminant(Scalar m00, Scalar m01, Scalar m02,
1111        Scalar m10, Scalar m11, Scalar m12,
1112        Scalar m20, Scalar m21, Scalar m22)
1113        {
1114            Scalar cofactor00 = m11 * m22 - m12 * m21;
1115            Scalar cofactor10 = m12 * m20 - m10 * m22;
1116            Scalar cofactor20 = m10 * m21 - m11 * m20;
1117            Scalar result =
1118            m00 * cofactor00 +
1119            m01 * cofactor10 +
1120            m02 * cofactor20;
1121            return result;
1122        }
1123        public static Scalar GetDeterminant(Vector3D Rx, Vector3D Ry, Vector3D Rz)
1124        {
1125            Scalar cofactor00 = Ry.Y * Rz.Z - Ry.Z * Rz.Y;
1126            Scalar cofactor10 = Ry.Z * Rz.X - Ry.X * Rz.Z;
1127            Scalar cofactor20 = Ry.X * Rz.Y - Ry.Y * Rz.X;
1128            Scalar result =
1129            Rx.X * cofactor00 +
1130            Rx.Y * cofactor10 +
1131            Rx.Z * cofactor20;
1132            return result;
1133        }
1134
1135        /// <summary>
1136        /// Constructs this Matrix from 3 euler angles, in degrees.
1137        /// </summary>
1138        /// <param name="yaw"></param>
1139        /// <param name="pitch"></param>
1140        /// <param name="roll"></param>
1141        public static Matrix3x3 FromEulerAnglesXYZ(Scalar yaw, Scalar pitch, Scalar roll)
1142        {
1143            return FromRotationX(yaw) * (FromRotationY(pitch) * FromRotationZ(roll));
1144        }
1145
1146        [ParseMethod]
1147        public static Matrix3x3 Parse(string s)
1148        {
1149            Matrix3x3 rv = Zero;
1150            ParseHelper.ParseMatrix<Matrix3x3>(s, ref rv);
1151            return rv;
1152        }
1153#if !CompactFramework && !WindowsCE && !PocketPC && !XBOX360 && !SILVERLIGHT
1154        public static bool TryParse(string s, out Matrix3x3 result)
1155        {
1156            result = Zero;
1157            return ParseHelper.TryParseMatrix<Matrix3x3>(s, ref result);
1158        }
1159#endif
1160
1161
1162        public static bool Equals(Matrix3x3 left, Matrix3x3 right)
1163        {
1164            return
1165                left.m00 == right.m00 && left.m01 == right.m01 && left.m02 == right.m02 &&
1166                left.m10 == right.m10 && left.m11 == right.m11 && left.m12 == right.m12 &&
1167                left.m20 == right.m20 && left.m21 == right.m21 && left.m22 == right.m22;
1168        }
1169        [CLSCompliant(false)]
1170        public static bool Equals(ref Matrix3x3 left, ref Matrix3x3 right)
1171        {
1172            return
1173                left.m00 == right.m00 && left.m01 == right.m01 && left.m02 == right.m02 &&
1174                left.m10 == right.m10 && left.m11 == right.m11 && left.m12 == right.m12 &&
1175                left.m20 == right.m20 && left.m21 == right.m21 && left.m22 == right.m22;
1176        }
1177
1178        #endregion
1179        #region fields
1180
1181        // | m00 m01 m02 |
1182        // | m10 m11 m12 |
1183        // | m20 m21 m22 |
1184        [XmlIgnore]
1185        public Scalar m00, m01, m02;
1186        [XmlIgnore]
1187        public Scalar m10, m11, m12;
1188        [XmlIgnore]
1189        public Scalar m20, m21, m22;
1190
1191        #endregion
1192        #region Constructors
1193
1194        /// <summary>
1195        /// Creates a new Matrix3 with all the specified parameters.
1196        /// </summary>
1197        public Matrix3x3(Scalar m00, Scalar m01, Scalar m02,
1198        Scalar m10, Scalar m11, Scalar m12,
1199        Scalar m20, Scalar m21, Scalar m22)
1200        {
1201            this.m00 = m00; this.m01 = m01; this.m02 = m02;
1202            this.m10 = m10; this.m11 = m11; this.m12 = m12;
1203            this.m20 = m20; this.m21 = m21; this.m22 = m22;
1204        }
1205
1206        /// <summary>
1207        /// Create a new Matrix from 3 Vertex3 objects.
1208        /// </summary>
1209        /// <param name="xAxis"></param>
1210        /// <param name="yAxis"></param>
1211        /// <param name="zAxis"></param>
1212        [InstanceConstructor("Rx,Ry,Rz")]
1213        public Matrix3x3(Vector3D xAxis, Vector3D yAxis, Vector3D zAxis)
1214        {
1215            this.m00 = xAxis.X; this.m01 = xAxis.Y; this.m02 = xAxis.Z;
1216            this.m10 = yAxis.X; this.m11 = yAxis.Y; this.m12 = yAxis.Z;
1217            this.m20 = zAxis.X; this.m21 = zAxis.Y; this.m22 = zAxis.Z;
1218        }
1219        public Matrix3x3(Scalar[] values) : this(values, 0) { }
1220        public Matrix3x3(Scalar[] values, int index)
1221        {
1222            Copy(values, index, out this);
1223        }
1224        #endregion
1225        #region Properties
1226        [AdvBrowsable]
1227        [System.ComponentModel.Description("The First row of the Matrix3x3")]
1228        public Vector3D Rx
1229        {
1230            get
1231            {
1232                Vector3D value;
1233                value.X = m00;
1234                value.Y = m01;
1235                value.Z = m02;
1236                return value;
1237            }
1238            set
1239            {
1240                m00 = value.X;
1241                m01 = value.Y;
1242                m02 = value.Z;
1243            }
1244        }
1245        [AdvBrowsable]
1246        [System.ComponentModel.Description("The Second row of the Matrix3x3")]
1247        public Vector3D Ry
1248        {
1249            get
1250            {
1251                Vector3D value;
1252                value.X = m10;
1253                value.Y = m11;
1254                value.Z = m12;
1255                return value;
1256            }
1257            set
1258            {
1259                m10 = value.X;
1260                m11 = value.Y;
1261                m12 = value.Z;
1262            }
1263        }
1264        [AdvBrowsable]
1265        [System.ComponentModel.Description("The Third row of the Matrix3x3")]
1266        public Vector3D Rz
1267        {
1268            get
1269            {
1270                Vector3D value;
1271                value.X = m20;
1272                value.Y = m21;
1273                value.Z = m22;
1274                return value;
1275            }
1276            set
1277            {
1278                m20 = value.X;
1279                m21 = value.Y;
1280                m22 = value.Z;
1281            }
1282        }
1283        [XmlIgnore]
1284        public Vector3D Cx
1285        {
1286            get
1287            {
1288                return new Vector3D(m00, m10, m20);
1289            }
1290            set
1291            {
1292                this.m00 = value.X;
1293                this.m10 = value.Y;
1294                this.m20 = value.Z;
1295            }
1296        }
1297        [XmlIgnore]
1298        public Vector3D Cy
1299        {
1300            get
1301            {
1302                return new Vector3D(m01, m11, m21);
1303            }
1304            set
1305            {
1306                this.m01 = value.X;
1307                this.m11 = value.Y;
1308                this.m21 = value.Z;
1309            }
1310        }
1311        [XmlIgnore]
1312        public Vector3D Cz
1313        {
1314            get
1315            {
1316                return new Vector3D(m02, m12, m22);
1317            }
1318            set
1319            {
1320                this.m02 = value.X;
1321                this.m12 = value.Y;
1322                this.m22 = value.Z;
1323            }
1324        }
1325
1326        public Scalar Determinant
1327        {
1328            get
1329            {
1330                Scalar result;
1331                GetDeterminant(ref this, out result);
1332                return result;
1333            }
1334        }
1335        /// <summary>
1336        /// Swap the rows of the matrix with the columns.
1337        /// </summary>
1338        /// <returns>A transposed Matrix.</returns>
1339        public Matrix3x3 Transposed
1340        {
1341            get
1342            {
1343                Matrix3x3 result;
1344                Transpose(ref this, out result);
1345                return result;
1346            }
1347        }
1348        public Matrix3x3 Adjoint
1349        {
1350            get
1351            {
1352                Matrix3x3 result;
1353                GetAdjoint(ref this, out result);
1354                return result;
1355            }
1356        }
1357        public Matrix3x3 Cofactor
1358        {
1359            get
1360            {
1361                Matrix3x3 result;
1362                GetCofactor(ref this, out result);
1363                return result;
1364            }
1365        }
1366        public Matrix3x3 Inverted
1367        {
1368            get
1369            {
1370                Matrix3x3 result;
1371                Invert(ref this, out result);
1372                return result;
1373            }
1374        }
1375
1376        int IAdvanceValueType.Count { get { return Count; } }
1377        int IMatrix.RowCount { get { return RowCount; } }
1378        int IMatrix.ColumnCount { get { return ColumnCount; } }
1379        #endregion Properties
1380        #region Methods
1381
1382        public Vector3D GetColumn(int columnIndex)
1383        {
1384            switch (columnIndex)
1385            {
1386                case 0:
1387                    return Cx;
1388                case 1:
1389                    return Cy;
1390                case 2:
1391                    return Cz;
1392            }
1393            throw ThrowHelper.GetThrowIndex("columnIndex", ColumnCount);
1394        }
1395        public void SetColumn(int columnIndex, Vector3D value)
1396        {
1397
1398            switch (columnIndex)
1399            {
1400                case 0:
1401                    Cx = value;
1402                    return;
1403                case 1:
1404                    Cy = value;
1405                    return;
1406                case 2:
1407                    Cz = value;
1408                    return;
1409            }
1410            throw ThrowHelper.GetThrowIndex("columnIndex", ColumnCount);
1411        }
1412        public Vector3D GetRow(int rowIndex)
1413        {
1414            switch (rowIndex)
1415            {
1416                case 0:
1417                    return Rx;
1418                case 1:
1419                    return Ry;
1420                case 2:
1421                    return Rz;
1422            }
1423            throw ThrowHelper.GetThrowIndex("rowIndex", RowCount);
1424        }
1425        public void SetRow(int rowIndex, Vector3D value)
1426        {
1427            switch (rowIndex)
1428            {
1429                case 0:
1430                    Rx = value;
1431                    return;
1432                case 1:
1433                    Ry = value;
1434                    return;
1435                case 2:
1436                    Rz = value;
1437                    return;
1438            }
1439            throw ThrowHelper.GetThrowIndex("rowIndex", RowCount);
1440        }
1441
1442        public Scalar[,] ToMatrixArray()
1443        {
1444            return new Scalar[RowCount, ColumnCount] { { m00, m01, m02 }, { m10, m11, m12 }, { m20, m21, m22 } };
1445        }
1446        public Scalar[] ToArray()
1447        {
1448            return new Scalar[Count] { m00, m01, m02, m10, m11, m12, m20, m21, m22 };
1449        }
1450        public Scalar[] ToTransposedArray()
1451        {
1452            return new Scalar[Count] { m00, m10, m20, m01, m11, m21, m02, m12, m22 };
1453        }
1454
1455        public Matrix4x4 ToMatrix4x4From2D()
1456        {
1457            Matrix4x4 result = Matrix4x4.Identity;
1458            result.m00 = this.m00; result.m01 = this.m01; result.m03 = this.m02;
1459            result.m10 = this.m10; result.m11 = this.m11; result.m13 = this.m12;
1460            result.m30 = this.m20; result.m31 = this.m21; result.m33 = this.m22;
1461            return result;
1462        }
1463        public Matrix4x4 ToMatrix4x4()
1464        {
1465            Matrix4x4 result = Matrix4x4.Identity;
1466            result.m00 = this.m00; result.m01 = this.m01; result.m02 = this.m02;
1467            result.m10 = this.m10; result.m11 = this.m11; result.m12 = this.m12;
1468            result.m20 = this.m20; result.m21 = this.m21; result.m22 = this.m22;
1469            return result;
1470        }
1471
1472        public void CopyTo(Scalar[] array, int index)
1473        {
1474            Copy(ref this, array, index);
1475        }
1476        public void CopyTransposedTo(Scalar[] array, int index)
1477        {
1478            CopyTranspose(ref this, array, index);
1479        }
1480        public void CopyFrom(Scalar[] array, int index)
1481        {
1482            Copy(array, index, out this);
1483        }
1484        public void CopyTransposedFrom(Scalar[] array, int index)
1485        {
1486            CopyTranspose(array, index, out this);
1487        }
1488
1489
1490
1491        private string ToStringInternal(string FormatString)
1492        {
1493            return string.Format(FormatString,
1494            m00, m01, m02,
1495            m10, m11, m12,
1496            m20, m21, m22);
1497        }
1498        public string ToString(string format)
1499        {
1500            return ToStringInternal(string.Format(FormatableString, format));
1501        }
1502        public override string ToString()
1503        {
1504            return ToStringInternal(FormatString);
1505        }
1506
1507        public override int GetHashCode()
1508        {
1509            return
1510            m00.GetHashCode() ^ m01.GetHashCode() ^ m02.GetHashCode() ^
1511            m10.GetHashCode() ^ m11.GetHashCode() ^ m12.GetHashCode() ^
1512            m20.GetHashCode() ^ m21.GetHashCode() ^ m22.GetHashCode();
1513        }
1514
1515        public override bool Equals(object obj)
1516        {
1517            return
1518                (obj is Matrix3x3) &&
1519                Equals((Matrix3x3)obj);
1520        }
1521        public bool Equals(Matrix3x3 other)
1522        {
1523            return Equals(ref this, ref other);
1524        }
1525
1526        #endregion
1527        #region Indexors
1528#if UNSAFE
1529        /// <summary>
1530        /// Allows the Matrix to be accessed like a 2d array (i.e. matrix[2,3])
1531        /// </summary>
1532        /// <remarks>
1533        /// This indexer is only provided as a convenience, and is <b>not</b> recommended for use in
1534        /// intensive applications.
1535        /// </remarks>
1536        public Scalar this[int rowIndex, int columnIndex]
1537        {
1538            get
1539            {
1540                ThrowHelper.CheckIndex("rowIndex", rowIndex, RowCount);
1541                ThrowHelper.CheckIndex("columnIndex", columnIndex, ColumnCount);
1542                unsafe
1543                {
1544                    fixed (Scalar* pM = &m00)
1545                    {
1546                        return pM[(ColumnCount * rowIndex) + columnIndex];
1547                    }
1548                }
1549            }
1550            set
1551            {
1552                ThrowHelper.CheckIndex("rowIndex", rowIndex, RowCount);
1553                ThrowHelper.CheckIndex("columnIndex", columnIndex, ColumnCount);
1554                unsafe
1555                {
1556                    fixed (Scalar* pM = &m00)
1557                    {
1558                        pM[(ColumnCount * rowIndex) + columnIndex] = value;
1559                    }
1560                }
1561            }
1562        }
1563        /// <summary>
1564        /// Allows the Matrix to be accessed linearly (m[0] -> m[ColumnCount*RowCount-1]).
1565        /// </summary>
1566        /// <remarks>
1567        /// This indexer is only provided as a convenience, and is <b>not</b> recommended for use in
1568        /// intensive applications.
1569        /// </remarks>
1570        public Scalar this[int index]
1571        {
1572            get
1573            {
1574                ThrowHelper.CheckIndex("index", index, Count);
1575                unsafe
1576                {
1577                    fixed (Scalar* pMatrix = &this.m00)
1578                    {
1579                        return pMatrix[index];
1580                    }
1581                }
1582            }
1583            set
1584            {
1585                ThrowHelper.CheckIndex("index", index, Count);
1586                unsafe
1587                {
1588                    fixed (Scalar* pMatrix = &this.m00)
1589                    {
1590                        pMatrix[index] = value;
1591                    }
1592                }
1593            }
1594        }
1595#endif
1596        #endregion
1597        #region Operator overloads
1598        /// <summary>
1599        /// Multiply (concatenate) two Matrix3 instances together.
1600        /// </summary>
1601        /// <param name="left"></param>
1602        /// <param name="right"></param>
1603        /// <returns></returns>
1604        public static Matrix3x3 operator *(Matrix3x3 left, Matrix3x3 right)
1605        {
1606
1607            Matrix3x3 result;
1608
1609            result.m00 = left.m00 * right.m00 + left.m01 * right.m10 + left.m02 * right.m20;
1610            result.m01 = left.m00 * right.m01 + left.m01 * right.m11 + left.m02 * right.m21;
1611            result.m02 = left.m00 * right.m02 + left.m01 * right.m12 + left.m02 * right.m22;
1612
1613            result.m10 = left.m10 * right.m00 + left.m11 * right.m10 + left.m12 * right.m20;
1614            result.m11 = left.m10 * right.m01 + left.m11 * right.m11 + left.m12 * right.m21;
1615            result.m12 = left.m10 * right.m02 + left.m11 * right.m12 + left.m12 * right.m22;
1616
1617            result.m20 = left.m20 * right.m00 + left.m21 * right.m10 + left.m22 * right.m20;
1618            result.m21 = left.m20 * right.m01 + left.m21 * right.m11 + left.m22 * right.m21;
1619            result.m22 = left.m20 * right.m02 + left.m21 * right.m12 + left.m22 * right.m22;
1620
1621            return result;
1622        }
1623        /// <summary>
1624        /// Multiply (concatenate) a Matrix3x3 and a Matrix2x2
1625        /// </summary>
1626        /// <param name="left"></param>
1627        /// <param name="right"></param>
1628        /// <returns></returns>
1629        public static Matrix3x3 operator *(Matrix2x2 left, Matrix3x3 right)
1630        {
1631
1632            Matrix3x3 result;
1633
1634            result.m00 = left.m00 * right.m00 + left.m01 * right.m10;
1635            result.m01 = left.m00 * right.m01 + left.m01 * right.m11;
1636            result.m02 = left.m00 * right.m02 + left.m01 * right.m12;
1637
1638            result.m10 = left.m10 * right.m00 + left.m11 * right.m10;
1639            result.m11 = left.m10 * right.m01 + left.m11 * right.m11;
1640            result.m12 = left.m10 * right.m02 + left.m11 * right.m12;
1641
1642            result.m20 = right.m20;
1643            result.m21 = right.m21;
1644            result.m22 = right.m22;
1645
1646            return result;
1647        }
1648        /// <summary>
1649        /// Multiply (concatenate) a Matrix3x3 and a Matrix2x2
1650        /// </summary>
1651        /// <param name="left"></param>
1652        /// <param name="right"></param>
1653        /// <returns></returns>
1654        public static Matrix3x3 operator *(Matrix3x3 left, Matrix2x2 right)
1655        {
1656
1657            Matrix3x3 result;
1658
1659            result.m00 = left.m00 * right.m00 + left.m01 * right.m10;
1660            result.m01 = left.m00 * right.m01 + left.m01 * right.m11;
1661            result.m02 = left.m02;
1662
1663            result.m10 = left.m10 * right.m00 + left.m11 * right.m10;
1664            result.m11 = left.m10 * right.m01 + left.m11 * right.m11;
1665            result.m12 = left.m12;
1666
1667            result.m20 = left.m20 * right.m00 + left.m21 * right.m10;
1668            result.m21 = left.m20 * right.m01 + left.m21 * right.m11;
1669            result.m22 = left.m22;
1670
1671            return result;
1672        }
1673
1674        /// <summary>
1675        /// Multiplies all the items in the Matrix3 by a scalar value.
1676        /// </summary>
1677        /// <param name="matrix"></param>
1678        /// <param name="scalar"></param>
1679        /// <returns></returns>
1680        public static Matrix3x3 operator *(Matrix3x3 matrix, Scalar scalar)
1681        {
1682            Matrix3x3 result;
1683
1684            result.m00 = matrix.m00 * scalar;
1685            result.m01 = matrix.m01 * scalar;
1686            result.m02 = matrix.m02 * scalar;
1687            result.m10 = matrix.m10 * scalar;
1688            result.m11 = matrix.m11 * scalar;
1689            result.m12 = matrix.m12 * scalar;
1690            result.m20 = matrix.m20 * scalar;
1691            result.m21 = matrix.m21 * scalar;
1692            result.m22 = matrix.m22 * scalar;
1693
1694            return result;
1695        }
1696        /// <summary>
1697        /// Multiplies all the items in the Matrix3 by a scalar value.
1698        /// </summary>
1699        /// <param name="matrix"></param>
1700        /// <param name="scalar"></param>
1701        /// <returns></returns>
1702        public static Matrix3x3 operator *(Scalar scalar, Matrix3x3 matrix)
1703        {
1704            Matrix3x3 result;
1705
1706            result.m00 = matrix.m00 * scalar;
1707            result.m01 = matrix.m01 * scalar;
1708            result.m02 = matrix.m02 * scalar;
1709            result.m10 = matrix.m10 * scalar;
1710            result.m11 = matrix.m11 * scalar;
1711            result.m12 = matrix.m12 * scalar;
1712            result.m20 = matrix.m20 * scalar;
1713            result.m21 = matrix.m21 * scalar;
1714            result.m22 = matrix.m22 * scalar;
1715
1716            return result;
1717        }
1718        /// <summary>
1719        /// Used to add two matrices together.
1720        /// </summary>
1721        /// <param name="left"></param>
1722        /// <param name="right"></param>
1723        /// <returns></returns>
1724        public static Matrix3x3 operator +(Matrix3x3 left, Matrix3x3 right)
1725        {
1726            Matrix3x3 result;
1727
1728            result.m00 = left.m00 + right.m00;
1729            result.m01 = left.m01 + right.m01;
1730            result.m02 = left.m02 + right.m02;
1731
1732            result.m10 = left.m10 + right.m10;
1733            result.m11 = left.m11 + right.m11;
1734            result.m12 = left.m12 + right.m12;
1735
1736            result.m20 = left.m20 + right.m20;
1737            result.m21 = left.m21 + right.m21;
1738            result.m22 = left.m22 + right.m22;
1739
1740            return result;
1741        }
1742        public static Matrix3x3 operator +(Matrix2x2 left, Matrix3x3 right)
1743        {
1744            Matrix3x3 result;
1745            Add(ref left, ref right, out result);
1746            return result;
1747        }
1748        public static Matrix3x3 operator +(Matrix3x3 left, Matrix2x2 right)
1749        {
1750            Matrix3x3 result;
1751            Add(ref left, ref right, out result);
1752            return result;
1753        }
1754        /// <summary>
1755        /// Used to subtract two matrices.
1756        /// </summary>
1757        /// <param name="left"></param>
1758        /// <param name="right"></param>
1759        /// <returns></returns>
1760        public static Matrix3x3 operator -(Matrix3x3 left, Matrix3x3 right)
1761        {
1762            Matrix3x3 result;
1763
1764            result.m00 = left.m00 - right.m00;
1765            result.m01 = left.m01 - right.m01;
1766            result.m02 = left.m02 - right.m02;
1767
1768            result.m10 = left.m10 - right.m10;
1769            result.m11 = left.m11 - right.m11;
1770            result.m12 = left.m12 - right.m12;
1771
1772            result.m20 = left.m20 - right.m20;
1773            result.m21 = left.m21 - right.m21;
1774            result.m22 = left.m22 - right.m22;
1775
1776            return result;
1777        }
1778        public static Matrix3x3 operator -(Matrix2x2 left, Matrix3x3 right)
1779        {
1780            Matrix3x3 result;
1781            Subtract(ref left, ref right, out result);
1782            return result;
1783        }
1784        public static Matrix3x3 operator -(Matrix3x3 left, Matrix2x2 right)
1785        {
1786            Matrix3x3 result;
1787            Subtract(ref left, ref right, out result);
1788            return result;
1789        }
1790        /// <summary>
1791        /// Negates all the items in the Matrix.
1792        /// </summary>
1793        /// <param name="matrix"></param>
1794        /// <returns></returns>
1795        public static Matrix3x3 operator -(Matrix3x3 matrix)
1796        {
1797            Matrix3x3 result;
1798
1799            result.m00 = -matrix.m00;
1800            result.m01 = -matrix.m01;
1801            result.m02 = -matrix.m02;
1802            result.m10 = -matrix.m10;
1803            result.m11 = -matrix.m11;
1804            result.m12 = -matrix.m12;
1805            result.m20 = -matrix.m20;
1806            result.m21 = -matrix.m21;
1807            result.m22 = -matrix.m22;
1808
1809            return result;
1810        }
1811        /// <summary>
1812        /// Test two matrices for (value) equality
1813        /// </summary>
1814        /// <param name="left"></param>
1815        /// <param name="right"></param>
1816        /// <returns></returns>
1817        public static bool operator ==(Matrix3x3 left, Matrix3x3 right)
1818        {
1819            return
1820            left.m00 == right.m00 && left.m01 == right.m01 && left.m02 == right.m02 &&
1821            left.m10 == right.m10 && left.m11 == right.m11 && left.m12 == right.m12 &&
1822            left.m20 == right.m20 && left.m21 == right.m21 && left.m22 == right.m22;
1823        }
1824        public static bool operator !=(Matrix3x3 left, Matrix3x3 right)
1825        {
1826            return !(left == right);
1827        }
1828
1829
1830        public static explicit operator Matrix3x3(Matrix4x4 source)
1831        {
1832            Matrix3x3 result;
1833
1834            result.m00 = source.m00;
1835            result.m01 = source.m01;
1836            result.m02 = source.m02;
1837
1838            result.m10 = source.m10;
1839            result.m11 = source.m11;
1840            result.m12 = source.m12;
1841
1842            result.m20 = source.m20;
1843            result.m21 = source.m21;
1844            result.m22 = source.m22;
1845
1846            return result;
1847        }
1848        public static explicit operator Matrix3x3(Matrix2x2 source)
1849        {
1850            Matrix3x3 result;
1851
1852            result.m00 = source.m00;
1853            result.m01 = source.m01;
1854            result.m02 = 0;
1855
1856            result.m10 = source.m10;
1857            result.m11 = source.m11;
1858            result.m12 = 0;
1859
1860            result.m20 = 0;
1861            result.m21 = 0;
1862            result.m22 = 1;
1863
1864
1865
1866
1867
1868            return result;
1869        }
1870
1871        #endregion
1872    }
1873}
Note: See TracBrowser for help on using the repository browser.